[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
ksh bug fixes
- To: tech_(_at_)_openbsd_(_dot_)_org
- Subject: ksh bug fixes
- From: "Todd C. Miller" <Todd_(_dot_)_Miller_(_at_)_courtesan_(_dot_)_com>
- Date: Fri, 10 Dec 2004 12:31:36 -0700
The following ksh diff needs wide testing. It does the following:
1) proper error message for bad substitution.
Before:
$ echo ${a[_(_at_)_]:foo}
ksh: : bad substitution
After:
$ echo ${a[_(_at_)_]:foo}
ksh: ${a[_(_at_)_]:foo}: bad substitution
2) fix a core dump for "echo ${a[_(_at_)_]:foo}".
3) fix a use-after-free bug (from otto@)
Index: bin/ksh/c_sh.c
===================================================================
RCS file: /home/cvs/openbsd/src/bin/ksh/c_sh.c,v
retrieving revision 1.17
diff -u -r1.17 c_sh.c
--- bin/ksh/c_sh.c 13 Mar 2003 09:03:07 -0000 1.17
+++ bin/ksh/c_sh.c 10 Dec 2004 19:26:07 -0000
@@ -558,7 +558,7 @@
how = LSHELL;
}
- quitenv(); /* get rid of any i/o redirections */
+ quitenv(NULL); /* get rid of any i/o redirections */
unwind(how);
/*NOTREACHED*/
return 0;
Index: bin/ksh/eval.c
===================================================================
RCS file: /home/cvs/openbsd/src/bin/ksh/eval.c,v
retrieving revision 1.17
diff -u -r1.17 eval.c
--- bin/ksh/eval.c 9 Dec 2004 11:32:07 -0000 1.17
+++ bin/ksh/eval.c 10 Dec 2004 19:26:08 -0000
@@ -292,12 +292,12 @@
char endc;
char *str, *end;
+ sp = varname - 2; /* restore sp */
end = (char *) wdscan(sp, CSUBST);
/* ({) the } or x is already skipped */
endc = *end;
*end = EOS;
- str = snptreef((char *) 0, 64, "%S",
- varname - 1);
+ str = snptreef(NULL, 64, "%S", sp);
*end = endc;
errorf("%s: bad substitution", str);
}
@@ -808,6 +808,7 @@
case '=': /* can't assign to a vector */
case '%': /* can't trim a vector (yet) */
case '#':
+ case '?':
return -1;
}
XPinit(wv, 32);
Index: bin/ksh/exec.c
===================================================================
RCS file: /home/cvs/openbsd/src/bin/ksh/exec.c,v
retrieving revision 1.31
diff -u -r1.31 exec.c
--- bin/ksh/exec.c 15 Dec 2003 05:25:52 -0000 1.31
+++ bin/ksh/exec.c 10 Dec 2004 19:26:07 -0000
@@ -213,7 +213,7 @@
i = ksh_sigsetjmp(e->jbuf, 0);
if (i) {
sigprocmask(SIG_SETMASK, &omask, (sigset_t *) 0);
- quitenv();
+ quitenv(NULL);
unwind(i);
/*NOTREACHED*/
}
@@ -319,7 +319,7 @@
if ((e->flags&EF_BRKCONT_PASS)
|| (i != LBREAK && i != LCONTIN))
{
- quitenv();
+ quitenv(NULL);
unwind(i);
} else if (i == LBREAK) {
rv = 0;
@@ -359,7 +359,7 @@
if ((e->flags&EF_BRKCONT_PASS)
|| (i != LBREAK && i != LCONTIN))
{
- quitenv();
+ quitenv(NULL);
unwind(i);
} else if (i == LBREAK) {
rv = 0;
@@ -429,7 +429,7 @@
Break:
exstat = rv;
- quitenv(); /* restores IO */
+ quitenv(NULL); /* restores IO */
if ((flags&XEXEC))
unwind(LEXIT); /* exit child */
if (rv != 0 && !(flags & XERROK)) {
@@ -688,11 +688,11 @@
case LEXIT:
case LLEAVE:
case LSHELL:
- quitenv();
+ quitenv(NULL);
unwind(i);
/*NOTREACHED*/
default:
- quitenv();
+ quitenv(NULL);
internal_errorf(1, "CFUNC %d", i);
}
break;
@@ -1471,8 +1471,7 @@
i = ksh_sigsetjmp(e->jbuf, 0);
if (i) {
source = osource;
- quitenv();
- shf_close(shf); /* after quitenv */
+ quitenv(shf);
close(fd);
return -2; /* special to iosetup(): don't print error */
}
@@ -1488,7 +1487,7 @@
} else
shf_puts(content, shf);
- quitenv();
+ quitenv(NULL);
if (shf_close(shf) == EOF) {
close(fd);
Index: bin/ksh/expr.c
===================================================================
RCS file: /home/cvs/openbsd/src/bin/ksh/expr.c,v
retrieving revision 1.9
diff -u -r1.9 expr.c
--- bin/ksh/expr.c 22 Oct 2003 07:40:38 -0000 1.9
+++ bin/ksh/expr.c 10 Dec 2004 19:26:07 -0000
@@ -183,7 +183,7 @@
/* Clear EXPRINEVAL in of any variables we were playing with */
if (curstate.evaling)
curstate.evaling->flag &= ~EXPRINEVAL;
- quitenv();
+ quitenv(NULL);
if (i == LAEXPR) {
if (error_ok == KSH_RETURN_ERROR)
return 0;
@@ -211,7 +211,7 @@
/* can fail if readonly */
setstr(vp, str_val(v), error_ok);
- quitenv();
+ quitenv(NULL);
return 1;
}
Index: bin/ksh/lex.c
===================================================================
RCS file: /home/cvs/openbsd/src/bin/ksh/lex.c,v
retrieving revision 1.22
diff -u -r1.22 lex.c
--- bin/ksh/lex.c 10 Nov 2004 21:13:54 -0000 1.22
+++ bin/ksh/lex.c 10 Dec 2004 19:26:07 -0000
@@ -1142,7 +1142,7 @@
} else
prompt = str_save(substitute(ps1, 0),
saved_atemp);
- quitenv();
+ quitenv(NULL);
}
#else /* KSH */
prompt = str_val(global("PS1"));
Index: bin/ksh/main.c
===================================================================
RCS file: /home/cvs/openbsd/src/bin/ksh/main.c,v
retrieving revision 1.28
diff -u -r1.28 main.c
--- bin/ksh/main.c 23 Aug 2004 14:56:32 -0000 1.28
+++ bin/ksh/main.c 10 Dec 2004 19:26:07 -0000
@@ -475,9 +475,7 @@
newenv(E_INCL);
i = ksh_sigsetjmp(e->jbuf, 0);
if (i) {
- if (s) /* Do this before quitenv(), which frees the memory */
- shf_close(s->u.shf);
- quitenv();
+ quitenv(s ? s->u.shf : NULL);
if (old_argv) {
e->loc->argv = old_argv;
e->loc->argc = old_argc;
@@ -511,8 +509,7 @@
s->u.shf = shf;
s->file = str_save(name, ATEMP);
i = shell(s, FALSE);
- shf_close(s->u.shf);
- quitenv();
+ quitenv(s->u.shf);
if (old_argv) {
e->loc->argv = old_argv;
e->loc->argc = old_argc;
@@ -579,12 +576,12 @@
case LLEAVE:
case LRETURN:
source = old_source;
- quitenv();
+ quitenv(NULL);
unwind(i); /* keep on going */
/*NOREACHED*/
default:
source = old_source;
- quitenv();
+ quitenv(NULL);
internal_errorf(1, "shell: %d", i);
/*NOREACHED*/
}
@@ -639,7 +636,7 @@
reclaim();
}
- quitenv();
+ quitenv(NULL);
source = old_source;
return exstat;
}
@@ -675,7 +672,7 @@
/* Fall through... */
default:
- quitenv();
+ quitenv(NULL);
}
}
}
@@ -698,7 +695,7 @@
}
void
-quitenv()
+quitenv(struct shf *shf)
{
register struct env *ep = e;
register int fd;
@@ -713,7 +710,6 @@
if (ep->savefd[2]) /* Clear any write errors */
shf_reopen(2, SHF_WR, shl_out);
}
- reclaim();
/* Bottom of the stack.
* Either main shell is exiting or cleanup_parents_env() was called.
@@ -742,8 +738,14 @@
chmem_allfree();
#endif /* MEM_DEBUG */
}
+ if (shf)
+ shf_close(shf);
+ reclaim();
exit(exstat);
}
+ if (shf)
+ shf_close(shf);
+ reclaim();
e = e->oenv;
afree(ep, ATEMP);
Index: bin/ksh/proto.h
===================================================================
RCS file: /home/cvs/openbsd/src/bin/ksh/proto.h,v
retrieving revision 1.12
diff -u -r1.12 proto.h
--- bin/ksh/proto.h 4 Nov 2004 19:20:07 -0000 1.12
+++ bin/ksh/proto.h 10 Dec 2004 19:26:07 -0000
@@ -173,7 +173,7 @@
int shell ARGS((Source *volatile s, int volatile toplevel));
void unwind ARGS((int i)) GCC_FUNC_ATTR(noreturn);
void newenv ARGS((int type));
-void quitenv ARGS((void));
+void quitenv ARGS((struct shf *));
void cleanup_parents_env ARGS((void));
void cleanup_proc_env ARGS((void));
void aerror ARGS((Area *ap, const char *msg))
Visit your host, monkey.org