aboutsummaryrefslogtreecommitdiff
path: root/src/dns
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2013-09-25 17:44:41 +0000
committerChristian Grothoff <christian@grothoff.org>2013-09-25 17:44:41 +0000
commit80a5a8965b3e28e6c1eb1a8a92c7b0189d87950b (patch)
tree8f1bd3df8ee70aaf6eb3a05e9c8eaf69b79566ef /src/dns
parentba226793d64360acfc9e192ba3ed886d4cda5dcb (diff)
downloadgnunet-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.c53
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);