Work around a buffer overflow problem on argv that has been exposed

after making test(1) a sh(1) builtin; sh(1) coredumps when you run
something like this:

	sh -c 'test ! `true 1`'

The cause is that the test(1) code totally depends on the presence of
two extra cells at the end of argv that are filled with NULL's.  The
reason why the bug hasn't been exposed would be because the C startup
code kindly prepares argv with some extra zeroed cells for a program.

I know this is not the best fix, but since there are argv++'s without
boundary checks everywhere, I'd rather patch it up like this
(preparing a copy of argv with extra NULL's) for the moment.

MFC after:	3 days
This commit is contained in:
knu 2002-02-03 10:01:49 +00:00
parent 3a7a0d07b5
commit 698dda9a1e

View File

@ -172,7 +172,6 @@ static int getn(const char *);
static long long getq(const char *);
static int intcmp(const char *, const char *);
static int isoperand(void);
int main(int, char **);
static int newerf(const char *, const char *);
static int nexpr(enum token);
static int oexpr(enum token);
@ -184,8 +183,23 @@ static enum token t_lex(char *);
int
main(int argc, char **argv)
{
int res;
int i, res;
char *p;
char **nargv;
/*
* XXX copy the whole contents of argv to a newly allocated
* space with two extra cells filled with NULL's - this source
* code totally depends on their presence.
*/
if ((nargv = (char **)malloc((argc + 2) * sizeof(char *))) == NULL)
error("Out of space");
for (i = 0; i < argc; i++)
nargv[i] = argv[i];
nargv[i] = nargv[i + 1] = NULL;
argv = nargv;
if ((p = rindex(argv[0], '/')) == NULL)
p = argv[0];
@ -197,10 +211,6 @@ main(int argc, char **argv)
argv[argc] = NULL;
}
/* no expression => false */
if (--argc <= 0)
return 1;
#ifndef SHELL
(void)setlocale(LC_CTYPE, "");
#endif