aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2019-03-03 21:57:50 +0800
committerBen Hutchings <ben@decadent.org.uk>2020-03-28 21:42:55 +0000
commit3f314ab5fe4a08b6e8d0ce34465298ba20f90def (patch)
tree96cb72b4aae0e53908d2e2baeee49e9e45e33762
parent4bfffb1572c9d1b77538b5a3e92c27f91bd2ee99 (diff)
downloadklibc-3f314ab5fe4a08b6e8d0ce34465298ba20f90def.tar.gz
[klibc] dash: eval: Reset handler when entering a subshell
[ dash commit 02a00569ba60e502f876c36d894ba0cc2d0682b3 ] As it is a subshell can execute code that is only meant for the parent shell when it executes a longjmp that is caught by something like evalcommand. This patch fixes it by resetting the handler when entering a subshell. Reported-by: Martijn Dekker <martijn@inlv.org> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
-rw-r--r--usr/dash/eval.c4
-rw-r--r--usr/dash/main.c11
-rw-r--r--usr/dash/main.h1
3 files changed, 13 insertions, 3 deletions
diff --git a/usr/dash/eval.c b/usr/dash/eval.c
index 1aad31a0ff97a..6ee2e1a7c22c8 100644
--- a/usr/dash/eval.c
+++ b/usr/dash/eval.c
@@ -41,6 +41,7 @@
* Evaluate a command.
*/
+#include "main.h"
#include "shell.h"
#include "nodes.h"
#include "syntax.h"
@@ -492,6 +493,7 @@ evalsubshell(union node *n, int flags)
if (backgnd)
flags &=~ EV_TESTED;
nofork:
+ reset_handler();
redirect(n->nredir.redirect, 0);
evaltreenr(n->nredir.n, flags);
/* never returns */
@@ -574,6 +576,7 @@ evalpipe(union node *n, int flags)
}
}
if (forkshell(jp, lp->n, n->npipe.backgnd) == 0) {
+ reset_handler();
INTON;
if (pip[1] >= 0) {
close(pip[0]);
@@ -630,6 +633,7 @@ evalbackcmd(union node *n, struct backcmd *result)
sh_error("Pipe call failed");
jp = makejob(n, 1);
if (forkshell(jp, n, FORK_NOJOB) == 0) {
+ reset_handler();
FORCEINTON;
close(pip[0]);
if (pip[1] != 1) {
diff --git a/usr/dash/main.c b/usr/dash/main.c
index 6b3a0909f51d6..b2712cbd6779f 100644
--- a/usr/dash/main.c
+++ b/usr/dash/main.c
@@ -71,6 +71,7 @@ int *dash_errno;
short profile_buf[16384];
extern int etext();
#endif
+static struct jmploc main_handler;
STATIC void read_profile(const char *);
STATIC char *find_dot_file(char *);
@@ -90,7 +91,6 @@ main(int argc, char **argv)
{
char *shinit;
volatile int state;
- struct jmploc jmploc;
struct stackmark smark;
int login;
@@ -102,7 +102,7 @@ main(int argc, char **argv)
monitor(4, etext, profile_buf, sizeof profile_buf, 50);
#endif
state = 0;
- if (unlikely(setjmp(jmploc.loc))) {
+ if (unlikely(setjmp(main_handler.loc))) {
int e;
int s;
@@ -137,7 +137,7 @@ main(int argc, char **argv)
else
goto state4;
}
- handler = &jmploc;
+ handler = &main_handler;
#ifdef DEBUG
opentrace();
trputs("Shell args: "); trargs(argv);
@@ -353,3 +353,8 @@ exitcmd(int argc, char **argv)
exraise(EXEXIT);
/* NOTREACHED */
}
+
+void reset_handler(void)
+{
+ handler = &main_handler;
+}
diff --git a/usr/dash/main.h b/usr/dash/main.h
index 19e49835df72a..51f1604c1ba1a 100644
--- a/usr/dash/main.h
+++ b/usr/dash/main.h
@@ -52,3 +52,4 @@ extern int *dash_errno;
void readcmdfile(char *);
int dotcmd(int, char **);
int exitcmd(int, char **);
+void reset_handler(void);