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
This commit is contained in:
Brooks Davis 2019-10-15 16:05:17 +00:00
parent 67f8ab8ebb
commit 7c8b268a12

View File

@ -93,18 +93,12 @@ static int allnc = nitems(allnv);
*/ */
static void addarg(const char *); /* add another argument to the list */ static void addarg(const char *); /* add another argument to the list */
static void insarg(int, const char *); /* insert arg at specified location */ 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 *); static void checkfiles(const char *, const char *);
/* check if out file already exists */ /* check if out file already exists */
static char **arglist;
static int argcount = 0;
#define ARGLISTLEN 20 static int argmax = 0;
#define FIXEDARGS 0
static char *arglist[ARGLISTLEN];
static int argcount = FIXEDARGS;
int nonfatalerrors; /* errors */ int nonfatalerrors; /* errors */
int inetdflag = 0; /* Support for inetd is disabled by default, use -I */ 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; struct commandline cmd;
(void) memset((char *)&cmd, 0, sizeof (struct commandline)); (void) memset((char *)&cmd, 0, sizeof (struct commandline));
clear_args();
if (!parseargs(argc, argv, &cmd)) if (!parseargs(argc, argv, &cmd))
usage(); usage();
/* /*
@ -273,16 +266,6 @@ add_warning(void)
f_print(fout, " */\n\n"); 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 */ /* prepend C-preprocessor and flags before arguments */
static void static void
prepend_cpp(void) prepend_cpp(void)
@ -924,22 +907,41 @@ do_registers(int argc, const char *argv[])
return (1); 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 * Add another argument to the arg list
*/ */
static void static void
addarg(const char *cp) addarg(const char *cp)
{ {
if (argcount >= ARGLISTLEN) { if (argcount >= argmax)
warnx("too many defines"); moreargs();
crash();
/*NOTREACHED*/
}
if (cp != NULL) if (cp != NULL)
arglist[argcount++] = xstrdup(cp); arglist[argcount++] = xstrdup(cp);
else else
arglist[argcount++] = NULL; arglist[argcount++] = NULL;
} }
/* /*
@ -950,11 +952,8 @@ insarg(int place, const char *cp)
{ {
int i; int i;
if (argcount >= ARGLISTLEN) { if (argcount >= argmax)
warnx("too many defines"); moreargs();
crash();
/*NOTREACHED*/
}
/* Move up existing arguments */ /* Move up existing arguments */
for (i = argcount - 1; i >= place; i--) for (i = argcount - 1; i >= place; i--)