]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Avoid unchecked string concatenation
authorBenny Baumann <BenBE@geshi.org>
Wed, 24 Jun 2020 20:56:58 +0000 (22:56 +0200)
committerPauli <pauli@openssl.org>
Mon, 23 May 2022 00:07:09 +0000 (10:07 +1000)
To avoid the issue of overflowing the buffer start while
building up the help string prefix this rewrite of the
string building logic does multiple smaller writes to
opt_printf_stderr. While this is slower it completely
avoids the buffer overflow issue and does not place
any (unchecked) length constraints on the name of passed
options. Instead such long options are gracefully
wrapped onto the next line.

Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/12265)

apps/lib/opt.c

index ce81408e38074845c0203fc9bf8d8a1a877946c3..df9152d77b3d00ef2d8be4e3380f133eee46909e 100644 (file)
@@ -1109,7 +1109,7 @@ static void opt_print(const OPTIONS *o, int doingparams, int width)
 {
     const char* help;
     char start[80 + 1];
-    char *p;
+    int linelen, printlen;
 
     /* Avoid OOB if width is beyond the buffer size of start */
     if (width >= (int)sizeof(start))
@@ -1140,31 +1140,27 @@ static void opt_print(const OPTIONS *o, int doingparams, int width)
     }
 
     /* Build up the "-flag [param]" part. */
-    p = start;
-
-    *p++ = ' ';
+    linelen = 0;
 
-    if (!doingparams)
-        *p++ = '-';
+    printlen = opt_printf_stderr(" %s", !doingparams ? "-" : "");
+    linelen += (printlen > 0) ? printlen : MAX_OPT_HELP_WIDTH;
 
-    if (o->name[0])
-        p += strlen(strcpy(p, o->name));
-    else
-        *p++ = '*';
+    printlen = opt_printf_stderr("%s" , o->name[0] ? o->name : "*");
+    linelen += (printlen > 0) ? printlen : MAX_OPT_HELP_WIDTH;
 
     if (o->valtype != '-') {
-        *p++ = ' ';
-        p += strlen(strcpy(p, valtype2param(o)));
+        printlen = opt_printf_stderr(" %s" , valtype2param(o));
+        linelen += (printlen > 0) ? printlen : MAX_OPT_HELP_WIDTH;
     }
 
-    *p = ' ';
-
-    if ((int)(p - start) >= MAX_OPT_HELP_WIDTH) {
-        *p = '\0';
-        opt_printf_stderr("%s\n", start);
+    if (linelen >= MAX_OPT_HELP_WIDTH || linelen > width) {
+        opt_printf_stderr("%s", "\n");
         memset(start, ' ', sizeof(start));
+        linelen = 0;
     }
 
+    width -= linelen;
+
     start[width] = '\0';
     opt_printf_stderr("%s  %s\n", start, help);
 }