From: Christopher Faulet Date: Tue, 29 Sep 2026 07:43:40 +0000 (+0200) Subject: BUG/MINOR: resolvers: compute a name's wire length by walking its labels X-Git-Url: https://git.kaiwu.me/?a=commitdiff_plain;h=15535bb6a8ccef61d819b1b81073f6e07b9f40a3;p=haproxy.git BUG/MINOR: resolvers: compute a name's wire length by walking its labels After decoding a name, resolv_read_name() computes the number of bytes the name occupies in the message by scanning it byte by byte until it finds either a zero byte or a byte with the two upper bits set, which it takes for the terminating zero or a compression pointer. But labels may contain any byte, so a label containing a zero byte or a byte >= 0xc0 stops the scan in the middle of the name, and the rest of the message is parsed from this wrong position, generally resulting in the response being considered invalid. Such bytes are found for example in names using raw UTF-8 characters instead of their IDNA form, which do-resolve may be asked to resolve: "caf\xc3\xa9.test" is correctly sent in the query, but the valid response is rejected because the question name is believed to end at 0xc3 (seen as a pointer), and do-resolve fails while plain names work. Let's walk the labels instead, as the first loop already validated them. This patch may be backported to stable branches. --- diff --git a/src/resolvers.c b/src/resolvers.c index db8714ac8..95259f068 100644 --- a/src/resolvers.c +++ b/src/resolvers.c @@ -699,7 +699,9 @@ int resolv_read_name(unsigned char *buffer, unsigned char *bufend, out: /* offset computation: - * parse from until finding either NULL or a pointer "c0xx" + * walk the labels from until finding either the terminating + * zero or a pointer "c0xx". Labels may contain any byte, and were + * already validated above. */ reader = name; *offset = 0; @@ -712,8 +714,8 @@ int resolv_read_name(unsigned char *buffer, unsigned char *bufend, *offset += 1; break; } - *offset += 1; - ++reader; + *offset += *reader + 1; + reader += *reader + 1; } return nb_bytes;