diff options
author | Otto Moerbeek <otto@cvs.openbsd.org> | 2004-12-22 18:57:29 +0000 |
---|---|---|
committer | Otto Moerbeek <otto@cvs.openbsd.org> | 2004-12-22 18:57:29 +0000 |
commit | 5dfaac9f1500daf82bfcb146882a1dc9de88e430 (patch) | |
tree | 001ffd476fe39a714df5a3c6fb93472388197080 /bin/ksh | |
parent | 417f256310e4ca6f040929ed5a3a5932198f83d6 (diff) |
Fix a use-after-free, that causs core dumps if a shell is killed
running with strict malloc.conf options. Problem spotted by hshoexer@;
fix by me with some help from millert@.
ok millert@ hshoexer@ krw@ deraadt@
Diffstat (limited to 'bin/ksh')
-rw-r--r-- | bin/ksh/c_sh.c | 4 | ||||
-rw-r--r-- | bin/ksh/exec.c | 19 | ||||
-rw-r--r-- | bin/ksh/expr.c | 6 | ||||
-rw-r--r-- | bin/ksh/lex.c | 4 | ||||
-rw-r--r-- | bin/ksh/main.c | 26 | ||||
-rw-r--r-- | bin/ksh/proto.h | 4 |
6 files changed, 32 insertions, 31 deletions
diff --git a/bin/ksh/c_sh.c b/bin/ksh/c_sh.c index ef25f3d9a1b..d78624e0030 100644 --- a/bin/ksh/c_sh.c +++ b/bin/ksh/c_sh.c @@ -1,4 +1,4 @@ -/* $OpenBSD: c_sh.c,v 1.25 2004/12/22 18:48:56 millert Exp $ */ +/* $OpenBSD: c_sh.c,v 1.26 2004/12/22 18:57:28 otto Exp $ */ /* * built-in Bourne commands @@ -538,7 +538,7 @@ c_exitreturn(char **wp) how = LSHELL; } - quitenv(); /* get rid of any i/o redirections */ + quitenv(NULL); /* get rid of any i/o redirections */ unwind(how); /*NOTREACHED*/ return 0; diff --git a/bin/ksh/exec.c b/bin/ksh/exec.c index c09ccd7a3ec..b2c87d64f3b 100644 --- a/bin/ksh/exec.c +++ b/bin/ksh/exec.c @@ -1,4 +1,4 @@ -/* $OpenBSD: exec.c,v 1.38 2004/12/22 17:14:34 millert Exp $ */ +/* $OpenBSD: exec.c,v 1.39 2004/12/22 18:57:28 otto Exp $ */ /* * execute command tree @@ -166,7 +166,7 @@ execute(struct op *volatile t, i = sigsetjmp(e->jbuf, 0); if (i) { sigprocmask(SIG_SETMASK, &omask, (sigset_t *) 0); - quitenv(); + quitenv(NULL); unwind(i); /*NOTREACHED*/ } @@ -264,7 +264,7 @@ execute(struct op *volatile t, if ((e->flags&EF_BRKCONT_PASS) || (i != LBREAK && i != LCONTIN)) { - quitenv(); + quitenv(NULL); unwind(i); } else if (i == LBREAK) { rv = 0; @@ -301,7 +301,7 @@ execute(struct op *volatile t, if ((e->flags&EF_BRKCONT_PASS) || (i != LBREAK && i != LCONTIN)) { - quitenv(); + quitenv(NULL); unwind(i); } else if (i == LBREAK) { rv = 0; @@ -363,7 +363,7 @@ execute(struct op *volatile t, Break: exstat = rv; - quitenv(); /* restores IO */ + quitenv(NULL); /* restores IO */ if ((flags&XEXEC)) unwind(LEXIT); /* exit child */ if (rv != 0 && !(flags & XERROK)) { @@ -616,11 +616,11 @@ comexec(struct op *t, struct tbl *volatile tp, char **ap, volatile int flags) case LEXIT: case LLEAVE: case LSHELL: - quitenv(); + quitenv(NULL); unwind(i); /*NOTREACHED*/ default: - quitenv(); + quitenv(NULL); internal_errorf(1, "CFUNC %d", i); } break; @@ -1188,8 +1188,7 @@ herein(const char *content, int sub) i = 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 */ } @@ -1205,7 +1204,7 @@ herein(const char *content, int sub) } else shf_puts(content, shf); - quitenv(); + quitenv(NULL); if (shf_close(shf) == EOF) { close(fd); diff --git a/bin/ksh/expr.c b/bin/ksh/expr.c index dc96d981974..34c8901cc83 100644 --- a/bin/ksh/expr.c +++ b/bin/ksh/expr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: expr.c,v 1.15 2004/12/22 17:14:34 millert Exp $ */ +/* $OpenBSD: expr.c,v 1.16 2004/12/22 18:57:28 otto Exp $ */ /* * Korn expression evaluation @@ -175,7 +175,7 @@ v_evaluate(struct tbl *vp, const char *expr, volatile int error_ok) /* 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; @@ -203,7 +203,7 @@ v_evaluate(struct tbl *vp, const char *expr, volatile int error_ok) /* can fail if readonly */ setstr(vp, str_val(v), error_ok); - quitenv(); + quitenv(NULL); return 1; } diff --git a/bin/ksh/lex.c b/bin/ksh/lex.c index 7623122a389..762298e8eda 100644 --- a/bin/ksh/lex.c +++ b/bin/ksh/lex.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lex.c,v 1.29 2004/12/22 17:14:34 millert Exp $ */ +/* $OpenBSD: lex.c,v 1.30 2004/12/22 18:57:28 otto Exp $ */ /* * lexical analysis and source input @@ -1154,7 +1154,7 @@ set_prompt(int to, Source *s) } else prompt = str_save(substitute(ps1, 0), saved_atemp); - quitenv(); + quitenv(NULL); break; case PS2: /* command continuation */ prompt = str_val(global("PS2")); diff --git a/bin/ksh/main.c b/bin/ksh/main.c index 2c63385602a..904ca59f8e1 100644 --- a/bin/ksh/main.c +++ b/bin/ksh/main.c @@ -1,4 +1,4 @@ -/* $OpenBSD: main.c,v 1.34 2004/12/22 17:14:34 millert Exp $ */ +/* $OpenBSD: main.c,v 1.35 2004/12/22 18:57:28 otto Exp $ */ /* * startup, main loop, environments and error handling @@ -397,9 +397,7 @@ include(const char *name, int argc, char **argv, int intr_ok) newenv(E_INCL); i = 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; @@ -433,8 +431,7 @@ include(const char *name, int argc, char **argv, int intr_ok) 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; @@ -498,12 +495,12 @@ shell(Source *volatile s, volatile int toplevel) 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*/ } @@ -556,7 +553,7 @@ shell(Source *volatile s, volatile int toplevel) reclaim(); } - quitenv(); + quitenv(NULL); source = old_source; return exstat; } @@ -591,7 +588,7 @@ unwind(int i) /* Fall through... */ default: - quitenv(); + quitenv(NULL); } } } @@ -613,7 +610,7 @@ newenv(int type) } void -quitenv(void) +quitenv(struct shf *shf) { struct env *ep = e; int fd; @@ -628,7 +625,6 @@ quitenv(void) 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. @@ -654,8 +650,14 @@ quitenv(void) } } } + if (shf) + shf_close(shf); + reclaim(); exit(exstat); } + if (shf) + shf_close(shf); + reclaim(); e = e->oenv; afree(ep, ATEMP); diff --git a/bin/ksh/proto.h b/bin/ksh/proto.h index 5ff22e956aa..1dabd8a1e1e 100644 --- a/bin/ksh/proto.h +++ b/bin/ksh/proto.h @@ -1,4 +1,4 @@ -/* $OpenBSD: proto.h,v 1.22 2004/12/22 17:18:51 millert Exp $ */ +/* $OpenBSD: proto.h,v 1.23 2004/12/22 18:57:28 otto Exp $ */ /* * prototypes for PD-KSH @@ -164,7 +164,7 @@ int command(const char *); int shell(Source *volatile, int volatile); void unwind(int) __attribute__((__noreturn__)); void newenv(int); -void quitenv(void); +void quitenv(struct shf *shf); void cleanup_parents_env(void); void cleanup_proc_env(void); void aerror(Area *, const char *) __attribute__((__noreturn__)); |