]> granicus.if.org Git - curl/commitdiff
progress_cb: avoid buffer overflow
authorDaniel Stenberg <daniel@haxx.se>
Wed, 9 Nov 2011 21:50:36 +0000 (22:50 +0100)
committerDaniel Stenberg <daniel@haxx.se>
Fri, 11 Nov 2011 18:57:49 +0000 (19:57 +0100)
The progress bar output function would blindly use the terminal width
without bounds checking. When using a very wide terminal that caused a
buffer overflow and segfault.

We now limit the max bar with to 255 columns, and I simplified the code
to avoid an extra snprintf and buffer.

Bug: http://curl.haxx.se/bug/view.cgi?id=3435710
Reported by: Alexey Zakhlestin

src/tool_cb_prg.c

index e141f1e6590e90d4e82a04e986ee25d1538fc6c4..457c1a75dc27b35120766c226ba274f733370e19 100644 (file)
@@ -36,6 +36,8 @@
 ** callback for CURLOPT_PROGRESSFUNCTION
 */
 
+#define MAX_BARLENGTH 256
+
 int tool_progress_cb(void *clientp,
                      double dltotal, double dlnow,
                      double ultotal, double ulnow)
@@ -43,8 +45,7 @@ int tool_progress_cb(void *clientp,
   /* The original progress-bar source code was written for curl by Lars Aas,
      and this new edition inherits some of his concepts. */
 
-  char line[256];
-  char outline[256];
+  char line[MAX_BARLENGTH+1];
   char format[40];
   double frac;
   double percent;
@@ -82,12 +83,13 @@ int tool_progress_cb(void *clientp,
     percent = frac * 100.0f;
     barwidth = bar->width - 7;
     num = (int) (((double)barwidth) * frac);
+    if(num > MAX_BARLENGTH)
+      num = MAX_BARLENGTH;
     for(i = 0; i < num; i++)
       line[i] = '#';
     line[i] = '\0';
-    snprintf(format, sizeof(format), "%%-%ds %%5.1f%%%%", barwidth);
-    snprintf(outline, sizeof(outline), format, line, percent);
-    fprintf(bar->out, "\r%s", outline);
+    snprintf(format, sizeof(format), "\r%%-%ds %%5.1f%%%%", barwidth);
+    fprintf(bar->out, format, line, percent);
   }
   fflush(bar->out);
   bar->prev = point;