diff mbox series

[scarthgap,1/2] c-ares: patch CVE-2026-69186

Message ID 20261003095050.3977773-1-peter.marko@siemens.com
State New
Headers show
Series [scarthgap,1/2] c-ares: patch CVE-2026-69186 | expand

Commit Message

Peter Marko Oct. 3, 2026, 9:50 a.m. UTC
From: Peter Marko <peter.marko@siemens.com>

Pick patch per [1].

[1] https://security-tracker.debian.org/tracker/CVE-2026-69184

Signed-off-by: Peter Marko <peter.marko@siemens.com>
---
 .../c-ares/c-ares/CVE-2026-69186.patch        | 159 ++++++++++++++++++
 .../recipes-support/c-ares/c-ares_1.27.0.bb   |   4 +-
 2 files changed, 162 insertions(+), 1 deletion(-)
 create mode 100644 meta-oe/recipes-support/c-ares/c-ares/CVE-2026-69186.patch
diff mbox series

Patch

diff --git a/meta-oe/recipes-support/c-ares/c-ares/CVE-2026-69186.patch b/meta-oe/recipes-support/c-ares/c-ares/CVE-2026-69186.patch
new file mode 100644
index 0000000000..b3c003acaa
--- /dev/null
+++ b/meta-oe/recipes-support/c-ares/c-ares/CVE-2026-69186.patch
@@ -0,0 +1,159 @@ 
+From e47c203f91cd8b749c8736bc18d75a31ffdec8f4 Mon Sep 17 00:00:00 2001
+From: jmestwa-coder <jmestwa@gmail.com>
+Date: Sun, 12 Apr 2026 23:50:54 +0530
+Subject: [PATCH] validate RR counts before preallocation to reject malformed
+ packets early (#1134)
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+## Summary
+
+Validate DNS RR counts before preallocation to reject malformed packets
+early.
+
+## What’s the issue?
+
+The parser currently trusts RR counts from the DNS header (`ANCOUNT`,
+`NSCOUNT`, `ARCOUNT`) without verifying that the packet contains enough
+data.
+
+A malformed packet can claim a large number of records without providing
+sufficient payload, causing the parser to proceed with unnecessary work
+and incorrect handling.
+
+## What changed?
+
+- Added validation to ensure RR counts are feasible based on the
+remaining buffer size
+- Moved RR preallocation from `ares_dns_parse_header` to
+`ares_dns_parse_buf`
+- Perform validation after question parsing and before preallocation
+- Return `ARES_EBADRESP` early for malformed packets
+
+## Why this approach?
+
+This keeps the parser aligned with its natural flow:
+
+parse header → parse question → validate → preallocate → parse records
+
+It avoids trusting unverified input and ensures malformed packets are
+rejected early and consistently.
+
+## Test
+
+Added a regression test (`ParseMalformedRRCount`) that reproduces the
+issue using a malformed packet with inconsistent RR count.
+
+Signed-off-by: @jmestwa-coder
+
+CVE: CVE-2026-69186
+Upstream-Status: Backport [https://github.com/c-ares/c-ares/commit/e47c203f91cd8b749c8736bc18d75a31ffdec8f4]
+Signed-off-by: Peter Marko <peter.marko@siemens.com>
+---
+ src/lib/ares_dns_parse.c | 55 ++++++++++++++++++++++------------------
+ test/ares-test-parse.cc  | 11 ++++++++
+ 2 files changed, 42 insertions(+), 24 deletions(-)
+
+diff --git a/src/lib/ares_dns_parse.c b/src/lib/ares_dns_parse.c
+index 2d2a7bb2..01f3f43c 100644
+--- a/src/lib/ares_dns_parse.c
++++ b/src/lib/ares_dns_parse.c
+@@ -848,30 +848,6 @@ static ares_status_t ares_dns_parse_header(ares__buf_t *buf, unsigned int flags,
+ 
+   (*dnsrec)->raw_rcode = rcode;
+ 
+-  if (*ancount > 0) {
+-    status =
+-      ares_dns_record_rr_prealloc(*dnsrec, ARES_SECTION_ANSWER, *ancount);
+-    if (status != ARES_SUCCESS) {
+-      goto fail;
+-    }
+-  }
+-
+-  if (*nscount > 0) {
+-    status =
+-      ares_dns_record_rr_prealloc(*dnsrec, ARES_SECTION_AUTHORITY, *nscount);
+-    if (status != ARES_SUCCESS) {
+-      goto fail;
+-    }
+-  }
+-
+-  if (*arcount > 0) {
+-    status =
+-      ares_dns_record_rr_prealloc(*dnsrec, ARES_SECTION_ADDITIONAL, *arcount);
+-    if (status != ARES_SUCCESS) {
+-      goto fail;
+-    }
+-  }
+-
+   return ARES_SUCCESS;
+ 
+ fail:
+@@ -1134,6 +1110,8 @@ static ares_status_t ares_dns_parse_buf(ares__buf_t *buf, unsigned int flags,
+                                         ares_dns_record_t **dnsrec)
+ {
+   ares_status_t  status;
++  size_t         total_rr_count;
++  const size_t   min_rr_wire_len = 11;
+   unsigned short qdcount;
+   unsigned short ancount;
+   unsigned short nscount;
+@@ -1194,6 +1172,35 @@ static ares_status_t ares_dns_parse_buf(ares__buf_t *buf, unsigned int flags,
+     }
+   }
+ 
++  total_rr_count = (size_t)ancount + (size_t)nscount + (size_t)arcount;
++  if (total_rr_count > ares__buf_len(buf) / min_rr_wire_len) {
++    status = ARES_EBADRESP;
++    goto fail;
++  }
++
++  if (ancount > 0) {
++    status = ares_dns_record_rr_prealloc(*dnsrec, ARES_SECTION_ANSWER, ancount);
++    if (status != ARES_SUCCESS) {
++      goto fail; /* LCOV_EXCL_LINE: OutOfMemory */
++    }
++  }
++
++  if (nscount > 0) {
++    status =
++      ares_dns_record_rr_prealloc(*dnsrec, ARES_SECTION_AUTHORITY, nscount);
++    if (status != ARES_SUCCESS) {
++      goto fail; /* LCOV_EXCL_LINE: OutOfMemory */
++    }
++  }
++
++  if (arcount > 0) {
++    status =
++      ares_dns_record_rr_prealloc(*dnsrec, ARES_SECTION_ADDITIONAL, arcount);
++    if (status != ARES_SUCCESS) {
++      goto fail; /* LCOV_EXCL_LINE: OutOfMemory */
++    }
++  }
++
+   /* Parse Answers */
+   for (i = 0; i < ancount; i++) {
+     status = ares_dns_parse_rr(buf, flags, ARES_SECTION_ANSWER, *dnsrec);
+diff --git a/test/ares-test-parse.cc b/test/ares-test-parse.cc
+index ff1fe14d..81fd7deb 100644
+--- a/test/ares-test-parse.cc
++++ b/test/ares-test-parse.cc
+@@ -207,6 +207,17 @@ TEST_F(LibraryTest, ParseFullyCompressedName) {
+   ares_free_hostent(host);
+ }
+ 
++TEST_F(LibraryTest, ParseMalformedRRCount) {
++  ares_dns_record_t *dnsrec = NULL;
++  const unsigned char data[] = {
++    0x12, 0x34, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01,
++    0x00, 0x00, 0x00, 0x00, 0x01, 'a',  0x00, 0x00,
++    0x01, 0x00, 0x01,
++  };
++
++  EXPECT_EQ(ARES_EBADRESP, ares_dns_parse(data, sizeof(data), 0, &dnsrec));
++  EXPECT_EQ(nullptr, dnsrec);
++}
+ 
+ }  // namespace test
+ }  // namespace ares
diff --git a/meta-oe/recipes-support/c-ares/c-ares_1.27.0.bb b/meta-oe/recipes-support/c-ares/c-ares_1.27.0.bb
index f6de281058..f409899026 100644
--- a/meta-oe/recipes-support/c-ares/c-ares_1.27.0.bb
+++ b/meta-oe/recipes-support/c-ares/c-ares_1.27.0.bb
@@ -6,7 +6,9 @@  LICENSE = "MIT"
 LIC_FILES_CHKSUM = "file://LICENSE.md;md5=fdbc58a6da11a9f68aa73c453818decc"
 
 SRC_URI = "https://github.com/c-ares/c-ares/releases/download/cares-1_27_0/${BPN}-${PV}.tar.gz \
-           file://run-ptest"
+           file://run-ptest \
+           file://CVE-2026-69186.patch \
+"
 SRC_URI[sha256sum] = "0a72be66959955c43e2af2fbd03418e82a2bd5464604ec9a62147e37aceb420b"
 
 PACKAGECONFIG ?= "${@bb.utils.contains('PTEST_ENABLED', '1', 'tests', '', d)}"