Browse code

dns: more strict record end checking

- be more strict and check always if a record doesn't exceed it's
declared length (before we checked only if the end is inside the
message).

Andrei Pelinescu-Onciul authored on 30/03/2009 13:59:42
Showing 1 changed files
... ...
@@ -499,6 +499,7 @@ struct rdata* get_record(char* name, int type, int flags)
499 499
 	static union dns_query buff;
500 500
 	unsigned char* p;
501 501
 	unsigned char* end;
502
+	unsigned char* rd_end;
502 503
 	static char rec_name[MAX_DNS_NAME]; /* placeholder for the record name */
503 504
 	int rec_name_len;
504 505
 	unsigned short rtype, class, rdlength;
... ...
@@ -593,10 +594,11 @@ again:
593 593
 		memcpy((void*)&rdlength, (void*)p, 2);
594 594
 		rdlength=ntohs(rdlength);
595 595
 		p+=2;
596
-		if (unlikely((p+rdlength)>end)) goto error_boundary;
596
+		rd_end=p+rdlength;
597
+		if (unlikely((rd_end)>end)) goto error_boundary;
597 598
 		if ((flags & RES_ONLY_TYPE) && (rtype!=type)){
598 599
 			/* skip */
599
-			p+=rdlength;
600
+			p=rd_end;
600 601
 			continue;
601 602
 		}
602 603
 		/* expand the "type" record  (rdata)*/
... ...
@@ -639,7 +641,7 @@ again:
639 639
 		}
640 640
 		switch(rtype){
641 641
 			case T_SRV:
642
-				srv_rd= dns_srv_parser(buff.buff, end, p);
642
+				srv_rd= dns_srv_parser(buff.buff, rd_end, p);
643 643
 				rd->rdata=(void*)srv_rd;
644 644
 				if (unlikely(srv_rd==0)) goto error_parse;
645 645
 				
... ...
@@ -663,26 +665,26 @@ again:
663 663
 				*crt=rd;
664 664
 				break;
665 665
 			case T_A:
666
-				rd->rdata=(void*) dns_a_parser(p,end);
666
+				rd->rdata=(void*) dns_a_parser(p, rd_end);
667 667
 				if (unlikely(rd->rdata==0)) goto error_parse;
668 668
 				*last=rd; /* last points to the last "next" or the list
669 669
 							 	head*/
670 670
 				last=&(rd->next);
671 671
 				break;
672 672
 			case T_AAAA:
673
-				rd->rdata=(void*) dns_aaaa_parser(p,end);
673
+				rd->rdata=(void*) dns_aaaa_parser(p, rd_end);
674 674
 				if (unlikely(rd->rdata==0)) goto error_parse;
675 675
 				*last=rd;
676 676
 				last=&(rd->next);
677 677
 				break;
678 678
 			case T_CNAME:
679
-				rd->rdata=(void*) dns_cname_parser(buff.buff, end, p);
679
+				rd->rdata=(void*) dns_cname_parser(buff.buff, rd_end, p);
680 680
 				if(unlikely(rd->rdata==0)) goto error_parse;
681 681
 				*last=rd;
682 682
 				last=&(rd->next);
683 683
 				break;
684 684
 			case T_NAPTR:
685
-				rd->rdata=(void*) dns_naptr_parser(buff.buff, end, p);
685
+				rd->rdata=(void*) dns_naptr_parser(buff.buff, rd_end, p);
686 686
 				if(unlikely(rd->rdata==0)) goto error_parse;
687 687
 				*last=rd;
688 688
 				last=&(rd->next);