|
|
Hi, Thorsten Glaser pointed me at a bug in our ksh, derived from pdksh,
which can trigger a segfault via access to an invalid stack pointer.
With this patch, it changes it to point to a heap allocation.
In effect, what needs testing is general regression; i.e. there should
be no functionality affected by this patch, it just fixes cases which
trigger the segfault. So to help, apply it and notify me of any ksh
segfaults or erroneous behavior, thanks.
The crash can be reproduced with the following:
$ ksh -c 'f() { time >/dev/null; }; f; f() { }'
And finally the patch. The first bit is for catching errors and not
part of the patch per se (actually from millert@):
Index: alloc.c
===================================================================
RCS file: /cvs/src/bin/ksh/alloc.c,v
retrieving revision 1.7
diff -u -p -r1.7 alloc.c
--- alloc.c 19 Feb 2004 18:51:17 -0000 1.7
+++ alloc.c 15 Jul 2008 16:16:32 -0000
@@ -99,15 +99,22 @@ aresize(void *ptr, size_t size, Area *ap
return L2P(l2);
}
+#include <assert.h>
void
afree(void *ptr, Area *ap)
{
- struct link *l;
+ struct link *l, *l2;
if (!ptr)
return;
l = P2L(ptr);
+
+ for (l2 = ap->freelist; l2 != NULL; l2 = l2->next) {
+ if (l == l2)
+ break;
+ }
+ assert(l2 != NULL);
if (l->prev)
l->prev->next = l->next;
Index: c_sh.c
===================================================================
RCS file: /cvs/src/bin/ksh/c_sh.c,v
retrieving revision 1.37
diff -u -p -r1.37 c_sh.c
--- c_sh.c 3 Sep 2007 13:54:23 -0000 1.37
+++ c_sh.c 15 Jul 2008 16:16:32 -0000
@@ -719,7 +719,6 @@ timex(struct op *t, int f)
struct timeval usrtime, systime, tv0, tv1;
int tf = 0;
extern struct timeval j_usrtime, j_systime; /* computed by j_wait */
- char opts[1];
gettimeofday(&tv0, NULL);
getrusage(RUSAGE_SELF, &ru0);
@@ -735,11 +734,8 @@ timex(struct op *t, int f)
*/
timerclear(&j_usrtime);
timerclear(&j_systime);
- if (t->left->type == TCOM)
- t->left->str = opts;
- opts[0] = 0;
rv = execute(t->left, f | XTIME);
- tf |= opts[0];
+ tf |= t->left->str[0];
gettimeofday(&tv1, NULL);
getrusage(RUSAGE_SELF, &ru1);
getrusage(RUSAGE_CHILDREN, &cru1);
Index: syn.c
===================================================================
RCS file: /cvs/src/bin/ksh/syn.c,v
retrieving revision 1.27
diff -u -p -r1.27 syn.c
--- syn.c 10 Apr 2006 14:38:59 -0000 1.27
+++ syn.c 15 Jul 2008 16:16:32 -0000
@@ -364,6 +364,11 @@ get_command(int cf)
case TIME:
syniocf &= ~(KEYWORD|ALIAS);
t = pipeline(0);
+ if (t) {
+ t->str = alloc(sizeof(char) * 2, ATEMP);
+ t->str[0] = '\0'; /* TF_* flags */
+ t->str[1] = '\0';
+ }
t = block(TTIME, t, NOBLOCK, NOWORDS);
break;
|
|