Ethereal-dev: [Ethereal-dev] Patch for tethereal: line buffer overflow

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

From: Sebastian Felis <felis@xxxxxxxxxxxxx>
Date: Wed, 10 Nov 2004 16:52:18 +0100
Hi,

last days I posted my problems of tethereal in the ethereal-user mailing
list. Now here is my patch for a small bug.


Description:
        In tethereal.c in print_columns() around line 2820 there is a
	buffer length check for the output line. If the buffer is too
	small it will doubled another overflow check isn't done.

Bug: 
        If new column string is greater than doubled buffer length an
        overflow will occur.


I'm using a huge list of protocol fields in the info column of tethreal
and a SEGV occurs by time to time resulted by this special case.

The patch is against current svn verion 12505. I insert while loops
around doubling of buffer lengths in print_columns().


Best regards

Sebastian
Index: tethereal.c
===================================================================
--- tethereal.c	(revision 12505)
+++ tethereal.c	(working copy)
@@ -2750,7 +2750,9 @@
       if (column_len < 3)
         column_len = 3;
       if (buf_offset + column_len > line_buf_len) {
-        line_buf_len *= 2;
+        while (buf_offset + column_len > line_buf_len) {
+          line_buf_len *= 2;
+        }
         line_bufp = g_realloc(line_bufp, line_buf_len + 1);
       }
       snprintf(line_bufp + buf_offset, COL_MAX_LEN+1, "%3s", cf->cinfo.col_data[i]);
@@ -2764,7 +2766,9 @@
       if (column_len < 10)
         column_len = 10;
       if (buf_offset + column_len > line_buf_len) {
-        line_buf_len *= 2;
+        while (buf_offset + column_len > line_buf_len) {
+          line_buf_len *= 2;
+        }
         line_bufp = g_realloc(line_bufp, line_buf_len + 1);
       }
       snprintf(line_bufp + buf_offset, COL_MAX_LEN+1, "%10s", cf->cinfo.col_data[i]);
@@ -2783,7 +2787,9 @@
       if (column_len < 12)
         column_len = 12;
       if (buf_offset + column_len > line_buf_len) {
-        line_buf_len *= 2;
+        while (buf_offset + column_len > line_buf_len) {
+          line_buf_len *= 2;
+        }
         line_bufp = g_realloc(line_bufp, line_buf_len + 1);
       }
       snprintf(line_bufp + buf_offset, COL_MAX_LEN+1, "%12s", cf->cinfo.col_data[i]);
@@ -2802,7 +2808,9 @@
       if (column_len < 12)
         column_len = 12;
       if (buf_offset + column_len > line_buf_len) {
-        line_buf_len *= 2;
+        while (buf_offset + column_len > line_buf_len) {
+          line_buf_len *= 2;
+        }
         line_bufp = g_realloc(line_bufp, line_buf_len + 1);
       }
       snprintf(line_bufp + buf_offset, COL_MAX_LEN+1, "%-12s", cf->cinfo.col_data[i]);
@@ -2811,7 +2819,9 @@
     default:
       column_len = strlen(cf->cinfo.col_data[i]);
       if (buf_offset + column_len > line_buf_len) {
-        line_buf_len *= 2;
+        while (buf_offset + column_len > line_buf_len) {
+            line_buf_len *= 2;
+        }
         line_bufp = g_realloc(line_bufp, line_buf_len + 1);
       }
       strcat(line_bufp + buf_offset, cf->cinfo.col_data[i]);
@@ -2834,7 +2844,9 @@
        * even if we're only adding " ".
        */
       if (buf_offset + 4 > line_buf_len) {
-        line_buf_len *= 2;
+        while (buf_offset + 4 > line_buf_len) {  
+          line_buf_len *= 2;
+        }
         line_bufp = g_realloc(line_bufp, line_buf_len + 1);
       }
       switch (cf->cinfo.col_fmt[i]) {