Ethereal-dev: Re: [Ethereal-dev] tcp.port == .... causes the Filtering to hang forever

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

From: Gilbert Ramirez <gram@xxxxxxxxxx>
Date: Fri, 16 Feb 2001 17:56:07 -0500
Here's a more correct diff from Ethereal 0.8.15.

I wasn't thinking correctly when I wrote the code to check
the length against the the buffer size for the string.

--gilbert
Index: packet-diameter.c
===================================================================
RCS file: /usr/local/cvsroot/ethereal/packet-diameter.c,v
retrieving revision 1.11
retrieving revision 1.15
diff -u -r1.11 -r1.15
--- packet-diameter.c	2001/01/09 06:31:35	1.11
+++ packet-diameter.c	2001/02/16 22:53:07	1.15
@@ -1,7 +1,7 @@
 /* packet-diameter.c
  * Routines for DIAMETER packet disassembly
  *
- * $Id: packet-diameter.c,v 1.11 2001/01/09 06:31:35 guy Exp $
+ * $Id: packet-diameter.c,v 1.15 2001/02/16 22:53:07 gram Exp $
  *
  * Copyright (c) 2000 by David Frascone <chaos@xxxxxxxxxxxxxx>
  *
@@ -150,7 +150,7 @@
   return(0);
 }
 
-static gchar *rdconvertbufftostr(gchar *dest,guint8 length,const guint8 *pd)
+static gchar *rdconvertbufftostr(gchar *dest,int length,const guint8 *pd)
 {
 /*converts the raw buffer into printable text */
 guint32 i;
@@ -299,6 +299,8 @@
 	return NULL;
 }
 
+#define BUFLEN 1024
+
 static gchar *rd_value_to_str(e_avphdr *avph,const u_char *pd, int offset)
 {
 	int print_type;
@@ -306,7 +308,7 @@
 	guint32 intval;
 	int dataLen;
 	char *valstr;
-	static char buffer[1024];
+	static char buffer[BUFLEN + 7 + 1]; /* 7 = "Value: ", 1 = NUL */
 
 	dataLen = avph->avp_length - sizeof(e_avphdr);
 
@@ -315,12 +317,19 @@
 	if (!(avph->avp_flags & AVP_FLAGS_T))
 		dataLen += 4;
 
+	if (dataLen < 0) {
+		return "Data Length too small.";
+	}
+	else if (dataLen > BUFLEN) {
+		return "Data Length too big.";
+	}
+
 /* prints the values of the attribute value pairs into a text buffer */
 	
 	print_type=match_numval(avph->avp_type,diameter_printinfo);
 	/* Default begin */
 	sprintf(buffer,"Value: ");
-	cont=&buffer[strlen(buffer)];
+	cont=&buffer[7];
 	switch(print_type)
 		{
 		case DIAMETER_COMPLEX:
@@ -387,17 +396,23 @@
 	guint32 vendorId=0;
 	int dataOffset;
 	int fixAmt;
+	int adj;
 	proto_item *avptf;
 	proto_tree *avptree;
 	int vendorOffset, tagOffset;
 	
-	if (avplength==0) {
+	if (avplength <= 0) {
 		proto_tree_add_text(tree, NullTVB,offset,0,
 		    "No Attribute Value Pairs Found");
 		return;
 	}
-	
+
 	while (avplength > 0 ) {
+
+		if (! IS_DATA_IN_FRAME(offset)) {
+			break;
+		}
+
 		vendorOffset = tagOffset = 0;
 		memcpy(&avph,&pd[offset],sizeof(e_avphdr));
 		avph.avp_type = ntohl(avph.avp_type);
@@ -433,7 +448,8 @@
 		 */
 		fixAmt = 4 - (avph.avp_length % 4);
 		if (fixAmt == 4) fixAmt = 0;
-		avplength=avplength - (avph.avp_length + fixAmt);
+		adj = avph.avp_length + fixAmt;
+		avplength -= adj;
 		avptpstrval=match_strval(avph.avp_type, diameter_attrib_type_vals);
 		if (avptpstrval == NULL) avptpstrval="Unknown Type";
 		if (!BYTES_ARE_IN_FRAME(offset, avph.avp_length)) {
@@ -480,8 +496,11 @@
 			    offset+dataOffset, avph.avp_length - dataOffset,
 			    "Data: (%d bytes) %s",
 			    avph.avp_length - dataOffset, valstr);
+		}
+		if (adj <= 0) {
+			break;
 		}
-		offset=offset+avph.avp_length + fixAmt;
+		offset += adj;
 	}
 }