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>
This commit is contained in:
Denys Vlasenko 2021-02-22 15:36:07 +01:00
parent a4959eef71
commit 9fa7d7d97d

View File

@ -379,7 +379,8 @@ Domain name in a message can be represented as either:
*/ */
static int process_packet(struct dns_entry *conf_data, static int process_packet(struct dns_entry *conf_data,
uint32_t conf_ttl, uint32_t conf_ttl,
uint8_t *buf) uint8_t *buf,
unsigned buflen)
{ {
struct dns_head *head; struct dns_head *head;
struct type_and_class *unaligned_type_class; 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"); bb_simple_error_msg("response packet, ignored");
return 0; /* don't reply */ return 0; /* don't reply */
} }
/* QR = 1 "response", RCODE = 4 "Not Implemented" */
outr_flags = htons(0x8000 | 4);
err_msg = NULL;
/* start of query string */ /* start of query string */
query_string = (void *)(head + 1); query_string = (void *)(head + 1);
@ -416,6 +414,15 @@ static int process_packet(struct dns_entry *conf_data,
/* where to append answer block */ /* where to append answer block */
answb = (void *)(unaligned_type_class + 1); 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"? */ /* OPCODE != 0 "standard query"? */
if ((head->flags & htons(0x7800)) != 0) { if ((head->flags & htons(0x7800)) != 0) {
err_msg = "opcode != 0"; err_msg = "opcode != 0";
@ -559,7 +566,7 @@ int dnsd_main(int argc UNUSED_PARAM, char **argv)
if (OPT_verbose) if (OPT_verbose)
bb_simple_info_msg("got UDP packet"); bb_simple_info_msg("got UDP packet");
buf[r] = '\0'; /* paranoia */ buf[r] = '\0'; /* paranoia */
r = process_packet(conf_data, conf_ttl, buf); r = process_packet(conf_data, conf_ttl, buf, r);
if (r <= 0) if (r <= 0)
continue; continue;
send_to_from(udps, buf, r, 0, &from->u.sa, &to->u.sa, lsa->len); send_to_from(udps, buf, r, 0, &from->u.sa, &to->u.sa, lsa->len);