From fd9570f30319b2e845576fdd089e519e57b906e9 Mon Sep 17 00:00:00 2001 From: Manu Nicolas Date: Tue, 18 Aug 2026 17:24:45 +0000 Subject: [PATCH] BUG/MINOR: resolvers: accept fields at the response boundary resolv_validate_dns_response() treats as an exclusive end pointer. Its fixed-width field checks nevertheless reject "reader + 2 == bufend", although reader[0] and reader[1] are both within the response. Use a strict greater-than comparison for every two-byte DNS header and question field. No complete successful answer is affected, but this corrects the parser contract and lets later checks classify minimal responses instead of rejecting them early as invalid. This may be backported as far as 2.4. --- src/resolvers.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/resolvers.c b/src/resolvers.c index 706882767..b6da43d88 100644 --- a/src/resolvers.c +++ b/src/resolvers.c @@ -1035,7 +1035,7 @@ static int resolv_validate_dns_response(unsigned char *resp, unsigned char *bufe r_res = &resolution->response; /* query id */ - if (reader + 2 >= bufend) + if (reader + 2 > bufend) goto invalid_resp; r_res->header.id = reader[0] * 256 + reader[1]; @@ -1049,7 +1049,7 @@ static int resolv_validate_dns_response(unsigned char *resp, unsigned char *bufe * - truncated (1 bit) * - recursion desired (1 bit) */ - if (reader + 2 >= bufend) + if (reader + 2 > bufend) goto invalid_resp; flags = reader[0] * 256 + reader[1]; @@ -1073,7 +1073,7 @@ static int resolv_validate_dns_response(unsigned char *resp, unsigned char *bufe reader += 2; /* 2 bytes for question count */ - if (reader + 2 >= bufend) + if (reader + 2 > bufend) goto invalid_resp; r_res->header.qdcount = reader[0] * 256 + reader[1]; /* (for now) we send one query only, so we expect only one in the @@ -1088,7 +1088,7 @@ static int resolv_validate_dns_response(unsigned char *resp, unsigned char *bufe reader += 2; /* 2 bytes for answer count */ - if (reader + 2 >= bufend) + if (reader + 2 > bufend) goto invalid_resp; r_res->header.ancount = reader[0] * 256 + reader[1]; if (r_res->header.ancount == 0) { @@ -1102,13 +1102,13 @@ static int resolv_validate_dns_response(unsigned char *resp, unsigned char *bufe reader += 2; /* 2 bytes authority count */ - if (reader + 2 >= bufend) + if (reader + 2 > bufend) goto invalid_resp; r_res->header.nscount = reader[0] * 256 + reader[1]; reader += 2; /* 2 bytes additional count */ - if (reader + 2 >= bufend) + if (reader + 2 > bufend) goto invalid_resp; r_res->header.arcount = reader[0] * 256 + reader[1]; reader += 2; @@ -1138,13 +1138,13 @@ static int resolv_validate_dns_response(unsigned char *resp, unsigned char *bufe previous_dname = query->name; /* move forward 2 bytes for question type */ - if (reader + 2 >= bufend) + if (reader + 2 > bufend) goto invalid_resp; query->type = reader[0] * 256 + reader[1]; reader += 2; /* move forward 2 bytes for question class */ - if (reader + 2 >= bufend) + if (reader + 2 > bufend) goto invalid_resp; query->class = reader[0] * 256 + reader[1]; reader += 2; -- 2.47.3