From 7c8b268a127f3ed0c569ee05c693ada6b8c07b37 Mon Sep 17 00:00:00 2001 From: Brooks Davis Date: Tue, 15 Oct 2019 16:05:17 +0000 Subject: [PATCH] rpcgen: make compiler arglist allocation dynamic Limit argmax to an absurdly large value prevent overflow (no overflow possible on FreeBSD due to ARG_MAX). In CheriBSD we exceed the 19 non-NULL arguments in the static array. Add a simple size doubling allocator and increase the default to 32. GC remnants of support for fixed arguments. Reviewed by: archardson (prior version), James Clarke (prior version) MFC after: 1 week Sponsored by: DARPA, AFRL Differential Revision: https://reviews.freebsd.org/D21971 --- usr.bin/rpcgen/rpc_main.c | 61 +++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 31 deletions(-) diff --git a/usr.bin/rpcgen/rpc_main.c b/usr.bin/rpcgen/rpc_main.c index 34755349d214..698017c969f2 100644 --- a/usr.bin/rpcgen/rpc_main.c +++ b/usr.bin/rpcgen/rpc_main.c @@ -93,18 +93,12 @@ static int allnc = nitems(allnv); */ static void addarg(const char *); /* add another argument to the list */ static void insarg(int, const char *); /* insert arg at specified location */ -static void clear_args(void); /* clear argument list */ static void checkfiles(const char *, const char *); /* check if out file already exists */ - - -#define ARGLISTLEN 20 -#define FIXEDARGS 0 - -static char *arglist[ARGLISTLEN]; -static int argcount = FIXEDARGS; - +static char **arglist; +static int argcount = 0; +static int argmax = 0; int nonfatalerrors; /* errors */ int inetdflag = 0; /* Support for inetd is disabled by default, use -I */ @@ -141,7 +135,6 @@ main(int argc, const char *argv[]) struct commandline cmd; (void) memset((char *)&cmd, 0, sizeof (struct commandline)); - clear_args(); if (!parseargs(argc, argv, &cmd)) usage(); /* @@ -273,16 +266,6 @@ add_warning(void) f_print(fout, " */\n\n"); } -/* clear list of arguments */ -static void -clear_args(void) -{ - int i; - for (i = FIXEDARGS; i < ARGLISTLEN; i++) - arglist[i] = NULL; - argcount = FIXEDARGS; -} - /* prepend C-preprocessor and flags before arguments */ static void prepend_cpp(void) @@ -924,22 +907,41 @@ do_registers(int argc, const char *argv[]) return (1); } +/* + * Extend the argument list + */ +static void +moreargs(void) +{ + char **newarglist; + + argmax = argmax == 0 ? 32 : argmax << 1; + if (argmax > INT_MAX / 4) { + warnx("refusing to allocate too many arguments"); + crash(); + } + newarglist = realloc(arglist, argmax * sizeof(*arglist)); + if (newarglist == NULL) { + warnx("unable to allocate arglist"); + crash(); + } + free(arglist); + arglist = newarglist; +} + /* * Add another argument to the arg list */ static void addarg(const char *cp) { - if (argcount >= ARGLISTLEN) { - warnx("too many defines"); - crash(); - /*NOTREACHED*/ - } + if (argcount >= argmax) + moreargs(); + if (cp != NULL) arglist[argcount++] = xstrdup(cp); else arglist[argcount++] = NULL; - } /* @@ -950,11 +952,8 @@ insarg(int place, const char *cp) { int i; - if (argcount >= ARGLISTLEN) { - warnx("too many defines"); - crash(); - /*NOTREACHED*/ - } + if (argcount >= argmax) + moreargs(); /* Move up existing arguments */ for (i = argcount - 1; i >= place; i--)