From 446225e54b4f23c08a07968433b39d62ed65afd1 Mon Sep 17 00:00:00 2001 From: Changqing Li Date: Tue, 14 Sep 2021 13:59:28 +0800 Subject: [PATCH 2/2] ares_expand_name(): fix formatting and handling of root name response Fixes issue introduced in prior commit with formatting and handling of parsing a root name response which should not be escaped. Fix By: Brad House Upstream-Status: Backport [https://github.com/c-ares/c-ares/commit/44c009b8e62ea1929de68e3f438181bea469ec14] CVE: CVE-2021-3672 Signed-off-by: Changqing Li --- ares_expand_name.c | 56 +++++++++++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 21 deletions(-) diff --git a/ares_expand_name.c b/ares_expand_name.c index 8604543..af0c2e8 100644 --- a/ares_expand_name.c +++ b/ares_expand_name.c @@ -133,22 +133,30 @@ int ares_expand_name(const unsigned char *encoded, const unsigned char *abuf, } else { - len = *p; + int name_len = *p; + len = name_len; p++; while (len--) { - if (!isprint(*p)) { - /* Output as \DDD for consistency with RFC1035 5.1 */ - *q++ = '\\'; - *q++ = '0' + *p / 100; - *q++ = '0' + (*p % 100) / 10; - *q++ = '0' + (*p % 10); - } else if (is_reservedch(*p)) { - *q++ = '\\'; - *q++ = *p; - } else { - *q++ = *p; - } + /* Output as \DDD for consistency with RFC1035 5.1, except + * for the special case of a root name response */ + if (!isprint(*p) && !(name_len == 1 && *p == 0)) + { + + *q++ = '\\'; + *q++ = '0' + *p / 100; + *q++ = '0' + (*p % 100) / 10; + *q++ = '0' + (*p % 10); + } + else if (is_reservedch(*p)) + { + *q++ = '\\'; + *q++ = *p; + } + else + { + *q++ = *p; + } p++; } *q++ = '.'; @@ -200,19 +208,25 @@ static int name_length(const unsigned char *encoded, const unsigned char *abuf, } else if (top == 0x00) { - offset = *encoded; + int name_len = *encoded; + offset = name_len; if (encoded + offset + 1 >= abuf + alen) return -1; encoded++; while (offset--) { - if (!isprint(*encoded)) { - n += 4; - } else if (is_reservedch(*encoded)) { - n += 2; - } else { - n += 1; - } + if (!isprint(*encoded) && !(name_len == 1 && *encoded == 0)) + { + n += 4; + } + else if (is_reservedch(*encoded)) + { + n += 2; + } + else + { + n += 1; + } encoded++; } n++; -- 2.17.1