]> git.ipfire.org Git - thirdparty/openssh-portable.git/commitdiff
upstream: make addargs() and replacearg() a little more robust and
authordjm@openbsd.org <djm@openbsd.org>
Sun, 20 Mar 2022 08:51:21 +0000 (08:51 +0000)
committerDamien Miller <djm@mindrot.org>
Sun, 20 Mar 2022 08:54:35 +0000 (19:54 +1100)
improve error reporting

make freeargs(NULL) a noop like the other free functions

ok dtucker as part of bz3403

OpenBSD-Commit-ID: 15f86da83176978b4d1d288caa24c766dfa2983d

misc.c

diff --git a/misc.c b/misc.c
index 417498deb7a2978f5184fa1b19aff03c45830f6d..85d22369505dc81ad0a55af304ef751cccfa960a 100644 (file)
--- a/misc.c
+++ b/misc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: misc.c,v 1.174 2022/02/11 00:43:56 dtucker Exp $ */
+/* $OpenBSD: misc.c,v 1.175 2022/03/20 08:51:21 djm Exp $ */
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  * Copyright (c) 2005-2020 Damien Miller.  All rights reserved.
@@ -1069,16 +1069,21 @@ addargs(arglist *args, char *fmt, ...)
        r = vasprintf(&cp, fmt, ap);
        va_end(ap);
        if (r == -1)
-               fatal("addargs: argument too long");
+               fatal_f("argument too long");
 
        nalloc = args->nalloc;
        if (args->list == NULL) {
                nalloc = 32;
                args->num = 0;
-       } else if (args->num+2 >= nalloc)
+       } else if (args->num > (256 * 1024))
+               fatal_f("too many arguments");
+       else if (args->num >= args->nalloc)
+               fatal_f("arglist corrupt");
+       else if (args->num+2 >= nalloc)
                nalloc *= 2;
 
-       args->list = xrecallocarray(args->list, args->nalloc, nalloc, sizeof(char *));
+       args->list = xrecallocarray(args->list, args->nalloc,
+           nalloc, sizeof(char *));
        args->nalloc = nalloc;
        args->list[args->num++] = cp;
        args->list[args->num] = NULL;
@@ -1095,10 +1100,12 @@ replacearg(arglist *args, u_int which, char *fmt, ...)
        r = vasprintf(&cp, fmt, ap);
        va_end(ap);
        if (r == -1)
-               fatal("replacearg: argument too long");
+               fatal_f("argument too long");
+       if (args->list == NULL || args->num >= args->nalloc)
+               fatal_f("arglist corrupt");
 
        if (which >= args->num)
-               fatal("replacearg: tried to replace invalid arg %d >= %d",
+               fatal_f("tried to replace invalid arg %d >= %d",
                    which, args->num);
        free(args->list[which]);
        args->list[which] = cp;
@@ -1109,13 +1116,15 @@ freeargs(arglist *args)
 {
        u_int i;
 
-       if (args->list != NULL) {
+       if (args == NULL)
+               return;
+       if (args->list != NULL && args->num < args->nalloc) {
                for (i = 0; i < args->num; i++)
                        free(args->list[i]);
                free(args->list);
-               args->nalloc = args->num = 0;
-               args->list = NULL;
        }
+       args->nalloc = args->num = 0;
+       args->list = NULL;
 }
 
 /*