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 | |
parent | a4959eef71067dd6763bf60113bdeafdcb5f2d91 (diff) | |
download | busybox-w32-9fa7d7d97d374b091819670299f25cad87a75779.tar.gz busybox-w32-9fa7d7d97d374b091819670299f25cad87a75779.tar.bz2 busybox-w32-9fa7d7d97d374b091819670299f25cad87a75779.zip |
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>
-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: | |||
379 | */ | 379 | */ |
380 | static int process_packet(struct dns_entry *conf_data, | 380 | static int process_packet(struct dns_entry *conf_data, |
381 | uint32_t conf_ttl, | 381 | uint32_t conf_ttl, |
382 | uint8_t *buf) | 382 | uint8_t *buf, |
383 | unsigned buflen) | ||
383 | { | 384 | { |
384 | struct dns_head *head; | 385 | struct dns_head *head; |
385 | struct type_and_class *unaligned_type_class; | 386 | struct type_and_class *unaligned_type_class; |
@@ -402,9 +403,6 @@ static int process_packet(struct dns_entry *conf_data, | |||
402 | bb_simple_error_msg("response packet, ignored"); | 403 | bb_simple_error_msg("response packet, ignored"); |
403 | return 0; /* don't reply */ | 404 | return 0; /* don't reply */ |
404 | } | 405 | } |
405 | /* QR = 1 "response", RCODE = 4 "Not Implemented" */ | ||
406 | outr_flags = htons(0x8000 | 4); | ||
407 | err_msg = NULL; | ||
408 | 406 | ||
409 | /* start of query string */ | 407 | /* start of query string */ |
410 | query_string = (void *)(head + 1); | 408 | query_string = (void *)(head + 1); |
@@ -416,6 +414,15 @@ static int process_packet(struct dns_entry *conf_data, | |||
416 | /* where to append answer block */ | 414 | /* where to append answer block */ |
417 | answb = (void *)(unaligned_type_class + 1); | 415 | answb = (void *)(unaligned_type_class + 1); |
418 | 416 | ||
417 | if (buflen < answb - buf) { | ||
418 | bb_simple_error_msg("packet too short"); | ||
419 | return 0; /* don't reply */ | ||
420 | } | ||
421 | |||
422 | /* QR = 1 "response", RCODE = 4 "Not Implemented" */ | ||
423 | outr_flags = htons(0x8000 | 4); | ||
424 | err_msg = NULL; | ||
425 | |||
419 | /* OPCODE != 0 "standard query"? */ | 426 | /* OPCODE != 0 "standard query"? */ |
420 | if ((head->flags & htons(0x7800)) != 0) { | 427 | if ((head->flags & htons(0x7800)) != 0) { |
421 | err_msg = "opcode != 0"; | 428 | err_msg = "opcode != 0"; |
@@ -559,7 +566,7 @@ int dnsd_main(int argc UNUSED_PARAM, char **argv) | |||
559 | if (OPT_verbose) | 566 | if (OPT_verbose) |
560 | bb_simple_info_msg("got UDP packet"); | 567 | bb_simple_info_msg("got UDP packet"); |
561 | buf[r] = '\0'; /* paranoia */ | 568 | buf[r] = '\0'; /* paranoia */ |
562 | r = process_packet(conf_data, conf_ttl, buf); | 569 | r = process_packet(conf_data, conf_ttl, buf, r); |
563 | if (r <= 0) | 570 | if (r <= 0) |
564 | continue; | 571 | continue; |
565 | send_to_from(udps, buf, r, 0, &from->u.sa, &to->u.sa, lsa->len); | 572 | send_to_from(udps, buf, r, 0, &from->u.sa, &to->u.sa, lsa->len); |