From 5c08c7d35d540c885277cac0fba5ccbe79b1205d Mon Sep 17 00:00:00 2001 From: Akinori MUSHA Date: Sun, 3 Feb 2002 10:01:49 +0000 Subject: [PATCH] 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 --- bin/test/test.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/bin/test/test.c b/bin/test/test.c index a6713a67b0d9..bf33ac2f61d4 100644 --- a/bin/test/test.c +++ b/bin/test/test.c @@ -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