diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2021-02-22 15:36:07 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2021-02-22 15:36:07 +0100 |
commit | 9fa7d7d97d374b091819670299f25cad87a75779 (patch) | |
tree | e854a91bbdd27b84685030e8318e69652b07ba32 /networking | |
parent | a4959eef71067dd6763bf60113bdeafdcb5f2d91 (diff) |
dnsd: check that we don't read past packet
function old new delta
dnsd_main 1296 1304 +8
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'networking')
-rw-r--r-- | networking/dnsd.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/networking/dnsd.c b/networking/dnsd.c index 0ff0290fb..a0f320c6c 100644 --- a/networking/dnsd.c +++ b/networking/dnsd.c @@ -379,7 +379,8 @@ Domain name in a message can be represented as either: */ static int process_packet(struct dns_entry *conf_data, uint32_t conf_ttl, - uint8_t *buf) + uint8_t *buf, + unsigned buflen) { struct dns_head *head; struct type_and_class *unaligned_type_class; @@ -402,9 +403,6 @@ static int process_packet(struct dns_entry *conf_data, bb_simple_error_msg("response packet, ignored"); return 0; /* don't reply */ } - /* QR = 1 "response", RCODE = 4 "Not Implemented" */ - outr_flags = htons(0x8000 | 4); - err_msg = NULL; /* start of query string */ query_string = (void *)(head + 1); @@ -416,6 +414,15 @@ static int process_packet(struct dns_entry *conf_data, /* where to append answer block */ answb = (void *)(unaligned_type_class + 1); + if (buflen < answb - buf) { + bb_simple_error_msg("packet too short"); + return 0; /* don't reply */ + } + + /* QR = 1 "response", RCODE = 4 "Not Implemented" */ + outr_flags = htons(0x8000 | 4); + err_msg = NULL; + /* OPCODE != 0 "standard query"? */ if ((head->flags & htons(0x7800)) != 0) { err_msg = "opcode != 0"; @@ -559,7 +566,7 @@ int dnsd_main(int argc UNUSED_PARAM, char **argv) if (OPT_verbose) bb_simple_info_msg("got UDP packet"); buf[r] = '\0'; /* paranoia */ - r = process_packet(conf_data, conf_ttl, buf); + r = process_packet(conf_data, conf_ttl, buf, r); if (r <= 0) continue; send_to_from(udps, buf, r, 0, &from->u.sa, &to->u.sa, lsa->len); |