resolv_validate_dns_response() treats <bufend> 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.54.0