summaryrefslogtreecommitdiff
path: root/bin/ksh
diff options
context:
space:
mode:
authorOtto Moerbeek <otto@cvs.openbsd.org>2004-12-22 18:57:29 +0000
committerOtto Moerbeek <otto@cvs.openbsd.org>2004-12-22 18:57:29 +0000
commit5dfaac9f1500daf82bfcb146882a1dc9de88e430 (patch)
tree001ffd476fe39a714df5a3c6fb93472388197080 /bin/ksh
parent417f256310e4ca6f040929ed5a3a5932198f83d6 (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.c4
-rw-r--r--bin/ksh/exec.c19
-rw-r--r--bin/ksh/expr.c6
-rw-r--r--bin/ksh/lex.c4
-rw-r--r--bin/ksh/main.c26
-rw-r--r--bin/ksh/proto.h4
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__));