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 2019-10-15 16:05:17 +00:00
parent 36182cc5e9
commit 5f5e69540e

View File

@ -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--)