diff options
author | Christian Grothoff <christian@grothoff.org> | 2013-09-25 17:44:41 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2013-09-25 17:44:41 +0000 |
commit | 80a5a8965b3e28e6c1eb1a8a92c7b0189d87950b (patch) | |
tree | 8f1bd3df8ee70aaf6eb3a05e9c8eaf69b79566ef /src/dns | |
parent | ba226793d64360acfc9e192ba3ed886d4cda5dcb (diff) | |
download | gnunet-80a5a8965b3e28e6c1eb1a8a92c7b0189d87950b.tar.gz gnunet-80a5a8965b3e28e6c1eb1a8a92c7b0189d87950b.zip |
-better error logging, return correct offset when parsing mx
Diffstat (limited to 'src/dns')
-rw-r--r-- | src/dns/dnsparser.c | 53 |
1 files changed, 51 insertions, 2 deletions
diff --git a/src/dns/dnsparser.c b/src/dns/dnsparser.c index ed70f6386..74ca584c6 100644 --- a/src/dns/dnsparser.c +++ b/src/dns/dnsparser.c | |||
@@ -211,7 +211,10 @@ parse_name (const char *udp_payload, | |||
211 | while (1) | 211 | while (1) |
212 | { | 212 | { |
213 | if (*off >= udp_payload_length) | 213 | if (*off >= udp_payload_length) |
214 | { | ||
215 | GNUNET_break_op (0); | ||
214 | goto error; | 216 | goto error; |
217 | } | ||
215 | len = input[*off]; | 218 | len = input[*off]; |
216 | if (0 == len) | 219 | if (0 == len) |
217 | { | 220 | { |
@@ -221,7 +224,10 @@ parse_name (const char *udp_payload, | |||
221 | if (len < 64) | 224 | if (len < 64) |
222 | { | 225 | { |
223 | if (*off + 1 + len > udp_payload_length) | 226 | if (*off + 1 + len > udp_payload_length) |
227 | { | ||
228 | GNUNET_break_op (0); | ||
224 | goto error; | 229 | goto error; |
230 | } | ||
225 | GNUNET_asprintf (&tmp, | 231 | GNUNET_asprintf (&tmp, |
226 | "%.*s", | 232 | "%.*s", |
227 | (int) len, | 233 | (int) len, |
@@ -260,17 +266,26 @@ parse_name (const char *udp_payload, | |||
260 | else if ((64 | 128) == (len & (64 | 128)) ) | 266 | else if ((64 | 128) == (len & (64 | 128)) ) |
261 | { | 267 | { |
262 | if (depth > 32) | 268 | if (depth > 32) |
269 | { | ||
270 | GNUNET_break_op (0); | ||
263 | goto error; /* hard bound on stack to prevent "infinite" recursion, disallow! */ | 271 | goto error; /* hard bound on stack to prevent "infinite" recursion, disallow! */ |
272 | } | ||
264 | /* pointer to string */ | 273 | /* pointer to string */ |
265 | if (*off + 1 > udp_payload_length) | 274 | if (*off + 1 > udp_payload_length) |
275 | { | ||
276 | GNUNET_break_op (0); | ||
266 | goto error; | 277 | goto error; |
278 | } | ||
267 | xoff = ((len - (64 | 128)) << 8) + input[*off+1]; | 279 | xoff = ((len - (64 | 128)) << 8) + input[*off+1]; |
268 | xstr = parse_name (udp_payload, | 280 | xstr = parse_name (udp_payload, |
269 | udp_payload_length, | 281 | udp_payload_length, |
270 | &xoff, | 282 | &xoff, |
271 | depth + 1); | 283 | depth + 1); |
272 | if (NULL == xstr) | 284 | if (NULL == xstr) |
285 | { | ||
286 | GNUNET_break_op (0); | ||
273 | goto error; | 287 | goto error; |
288 | } | ||
274 | GNUNET_asprintf (&tmp, | 289 | GNUNET_asprintf (&tmp, |
275 | "%s%s.", | 290 | "%s%s.", |
276 | ret, | 291 | ret, |
@@ -279,7 +294,10 @@ parse_name (const char *udp_payload, | |||
279 | GNUNET_free (xstr); | 294 | GNUNET_free (xstr); |
280 | ret = tmp; | 295 | ret = tmp; |
281 | if (strlen (ret) > udp_payload_length) | 296 | if (strlen (ret) > udp_payload_length) |
297 | { | ||
298 | GNUNET_break_op (0); | ||
282 | goto error; /* we are looping (building an infinite string) */ | 299 | goto error; /* we are looping (building an infinite string) */ |
300 | } | ||
283 | *off += 2; | 301 | *off += 2; |
284 | /* pointers always terminate names */ | 302 | /* pointers always terminate names */ |
285 | break; | 303 | break; |
@@ -287,6 +305,7 @@ parse_name (const char *udp_payload, | |||
287 | else | 305 | else |
288 | { | 306 | { |
289 | /* neither pointer nor inline string, not supported... */ | 307 | /* neither pointer nor inline string, not supported... */ |
308 | GNUNET_break_op (0); | ||
290 | goto error; | 309 | goto error; |
291 | } | 310 | } |
292 | } | 311 | } |
@@ -294,6 +313,7 @@ parse_name (const char *udp_payload, | |||
294 | ret[strlen(ret)-1] = '\0'; /* eat tailing '.' */ | 313 | ret[strlen(ret)-1] = '\0'; /* eat tailing '.' */ |
295 | return ret; | 314 | return ret; |
296 | error: | 315 | error: |
316 | GNUNET_break_op (0); | ||
297 | GNUNET_free (ret); | 317 | GNUNET_free (ret); |
298 | return NULL; | 318 | return NULL; |
299 | } | 319 | } |
@@ -340,10 +360,16 @@ GNUNET_DNSPARSER_parse_query (const char *udp_payload, | |||
340 | udp_payload_length, | 360 | udp_payload_length, |
341 | off); | 361 | off); |
342 | if (NULL == name) | 362 | if (NULL == name) |
363 | { | ||
364 | GNUNET_break_op (0); | ||
343 | return GNUNET_SYSERR; | 365 | return GNUNET_SYSERR; |
366 | } | ||
344 | q->name = name; | 367 | q->name = name; |
345 | if (*off + sizeof (struct GNUNET_TUN_DnsQueryLine) > udp_payload_length) | 368 | if (*off + sizeof (struct GNUNET_TUN_DnsQueryLine) > udp_payload_length) |
369 | { | ||
370 | GNUNET_break_op (0); | ||
346 | return GNUNET_SYSERR; | 371 | return GNUNET_SYSERR; |
372 | } | ||
347 | memcpy (&ql, &udp_payload[*off], sizeof (ql)); | 373 | memcpy (&ql, &udp_payload[*off], sizeof (ql)); |
348 | *off += sizeof (ql); | 374 | *off += sizeof (ql); |
349 | q->type = ntohs (ql.type); | 375 | q->type = ntohs (ql.type); |
@@ -382,6 +408,7 @@ GNUNET_DNSPARSER_parse_soa (const char *udp_payload, | |||
382 | (NULL == soa->rname) || | 408 | (NULL == soa->rname) || |
383 | (*off + sizeof (struct GNUNET_TUN_DnsSoaRecord) > udp_payload_length) ) | 409 | (*off + sizeof (struct GNUNET_TUN_DnsSoaRecord) > udp_payload_length) ) |
384 | { | 410 | { |
411 | GNUNET_break_op (0); | ||
385 | GNUNET_DNSPARSER_free_soa (soa); | 412 | GNUNET_DNSPARSER_free_soa (soa); |
386 | *off = old_off; | 413 | *off = old_off; |
387 | return NULL; | 414 | return NULL; |
@@ -419,7 +446,10 @@ GNUNET_DNSPARSER_parse_mx (const char *udp_payload, | |||
419 | 446 | ||
420 | old_off = *off; | 447 | old_off = *off; |
421 | if (*off + sizeof (uint16_t) > udp_payload_length) | 448 | if (*off + sizeof (uint16_t) > udp_payload_length) |
449 | { | ||
450 | GNUNET_break_op (0); | ||
422 | return NULL; | 451 | return NULL; |
452 | } | ||
423 | memcpy (&mxpref, &udp_payload[*off], sizeof (uint16_t)); | 453 | memcpy (&mxpref, &udp_payload[*off], sizeof (uint16_t)); |
424 | (*off) += sizeof (uint16_t); | 454 | (*off) += sizeof (uint16_t); |
425 | mx = GNUNET_new (struct GNUNET_DNSPARSER_MxRecord); | 455 | mx = GNUNET_new (struct GNUNET_DNSPARSER_MxRecord); |
@@ -429,11 +459,11 @@ GNUNET_DNSPARSER_parse_mx (const char *udp_payload, | |||
429 | off); | 459 | off); |
430 | if (NULL == mx->mxhost) | 460 | if (NULL == mx->mxhost) |
431 | { | 461 | { |
462 | GNUNET_break_op (0); | ||
432 | GNUNET_DNSPARSER_free_mx (mx); | 463 | GNUNET_DNSPARSER_free_mx (mx); |
433 | *off = old_off; | 464 | *off = old_off; |
434 | return NULL; | 465 | return NULL; |
435 | } | 466 | } |
436 | *off = old_off; | ||
437 | return mx; | 467 | return mx; |
438 | } | 468 | } |
439 | 469 | ||
@@ -539,10 +569,16 @@ GNUNET_DNSPARSER_parse_record (const char *udp_payload, | |||
539 | udp_payload_length, | 569 | udp_payload_length, |
540 | off); | 570 | off); |
541 | if (NULL == name) | 571 | if (NULL == name) |
572 | { | ||
573 | GNUNET_break_op (0); | ||
542 | return GNUNET_SYSERR; | 574 | return GNUNET_SYSERR; |
575 | } | ||
543 | r->name = name; | 576 | r->name = name; |
544 | if (*off + sizeof (struct GNUNET_TUN_DnsRecordLine) > udp_payload_length) | 577 | if (*off + sizeof (struct GNUNET_TUN_DnsRecordLine) > udp_payload_length) |
578 | { | ||
579 | GNUNET_break_op (0); | ||
545 | return GNUNET_SYSERR; | 580 | return GNUNET_SYSERR; |
581 | } | ||
546 | memcpy (&rl, &udp_payload[*off], sizeof (rl)); | 582 | memcpy (&rl, &udp_payload[*off], sizeof (rl)); |
547 | (*off) += sizeof (rl); | 583 | (*off) += sizeof (rl); |
548 | r->type = ntohs (rl.type); | 584 | r->type = ntohs (rl.type); |
@@ -551,7 +587,10 @@ GNUNET_DNSPARSER_parse_record (const char *udp_payload, | |||
551 | ntohl (rl.ttl))); | 587 | ntohl (rl.ttl))); |
552 | data_len = ntohs (rl.data_len); | 588 | data_len = ntohs (rl.data_len); |
553 | if (*off + data_len > udp_payload_length) | 589 | if (*off + data_len > udp_payload_length) |
590 | { | ||
591 | GNUNET_break_op (0); | ||
554 | return GNUNET_SYSERR; | 592 | return GNUNET_SYSERR; |
593 | } | ||
555 | old_off = *off; | 594 | old_off = *off; |
556 | switch (r->type) | 595 | switch (r->type) |
557 | { | 596 | { |
@@ -571,7 +610,10 @@ GNUNET_DNSPARSER_parse_record (const char *udp_payload, | |||
571 | off); | 610 | off); |
572 | if ( (NULL == r->data.soa) || | 611 | if ( (NULL == r->data.soa) || |
573 | (old_off + data_len != *off) ) | 612 | (old_off + data_len != *off) ) |
613 | { | ||
614 | GNUNET_break_op (0); | ||
574 | return GNUNET_SYSERR; | 615 | return GNUNET_SYSERR; |
616 | } | ||
575 | return GNUNET_OK; | 617 | return GNUNET_OK; |
576 | case GNUNET_DNSPARSER_TYPE_MX: | 618 | case GNUNET_DNSPARSER_TYPE_MX: |
577 | r->data.mx = GNUNET_DNSPARSER_parse_mx (udp_payload, | 619 | r->data.mx = GNUNET_DNSPARSER_parse_mx (udp_payload, |
@@ -579,7 +621,10 @@ GNUNET_DNSPARSER_parse_record (const char *udp_payload, | |||
579 | off); | 621 | off); |
580 | if ( (NULL == r->data.mx) || | 622 | if ( (NULL == r->data.mx) || |
581 | (old_off + data_len != *off) ) | 623 | (old_off + data_len != *off) ) |
624 | { | ||
625 | GNUNET_break_op (0); | ||
582 | return GNUNET_SYSERR; | 626 | return GNUNET_SYSERR; |
627 | } | ||
583 | return GNUNET_OK; | 628 | return GNUNET_OK; |
584 | case GNUNET_DNSPARSER_TYPE_SRV: | 629 | case GNUNET_DNSPARSER_TYPE_SRV: |
585 | r->data.srv = GNUNET_DNSPARSER_parse_srv (r->name, | 630 | r->data.srv = GNUNET_DNSPARSER_parse_srv (r->name, |
@@ -588,7 +633,10 @@ GNUNET_DNSPARSER_parse_record (const char *udp_payload, | |||
588 | off); | 633 | off); |
589 | if ( (NULL == r->data.srv) || | 634 | if ( (NULL == r->data.srv) || |
590 | (old_off + data_len != *off) ) | 635 | (old_off + data_len != *off) ) |
636 | { | ||
637 | GNUNET_break_op (0); | ||
591 | return GNUNET_SYSERR; | 638 | return GNUNET_SYSERR; |
639 | } | ||
592 | return GNUNET_OK; | 640 | return GNUNET_OK; |
593 | default: | 641 | default: |
594 | r->data.raw.data = GNUNET_malloc (data_len); | 642 | r->data.raw.data = GNUNET_malloc (data_len); |
@@ -680,6 +728,7 @@ GNUNET_DNSPARSER_parse (const char *udp_payload, | |||
680 | } | 728 | } |
681 | return p; | 729 | return p; |
682 | error: | 730 | error: |
731 | GNUNET_break_op (0); | ||
683 | GNUNET_DNSPARSER_free_packet (p); | 732 | GNUNET_DNSPARSER_free_packet (p); |
684 | return NULL; | 733 | return NULL; |
685 | } | 734 | } |
@@ -765,7 +814,7 @@ GNUNET_DNSPARSER_builder_add_name (char *dst, | |||
765 | len = strlen (idna_name); | 814 | len = strlen (idna_name); |
766 | else | 815 | else |
767 | len = dot - idna_name; | 816 | len = dot - idna_name; |
768 | if ( (len >= 64) || (len == 0) ) | 817 | if ( (len >= 64) || (0 == len) ) |
769 | goto fail; /* segment too long or empty */ | 818 | goto fail; /* segment too long or empty */ |
770 | dst[pos++] = (char) (uint8_t) len; | 819 | dst[pos++] = (char) (uint8_t) len; |
771 | memcpy (&dst[pos], idna_name, len); | 820 | memcpy (&dst[pos], idna_name, len); |