Skip to content

Commit 02a0056

Browse files
committed
eval: Reset handler when entering a subshell
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 <[email protected]> Signed-off-by: Herbert Xu <[email protected]>
1 parent 86a841b commit 02a0056

File tree

3 files changed

+13
-3
lines changed

3 files changed

+13
-3
lines changed

src/eval.c

+4
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
* Evaluate a command.
4242
*/
4343

44+
#include "main.h"
4445
#include "shell.h"
4546
#include "nodes.h"
4647
#include "syntax.h"
@@ -492,6 +493,7 @@ evalsubshell(union node *n, int flags)
492493
if (backgnd)
493494
flags &=~ EV_TESTED;
494495
nofork:
496+
reset_handler();
495497
redirect(n->nredir.redirect, 0);
496498
evaltreenr(n->nredir.n, flags);
497499
/* never returns */
@@ -574,6 +576,7 @@ evalpipe(union node *n, int flags)
574576
}
575577
}
576578
if (forkshell(jp, lp->n, n->npipe.backgnd) == 0) {
579+
reset_handler();
577580
INTON;
578581
if (pip[1] >= 0) {
579582
close(pip[0]);
@@ -630,6 +633,7 @@ evalbackcmd(union node *n, struct backcmd *result)
630633
sh_error("Pipe call failed");
631634
jp = makejob(n, 1);
632635
if (forkshell(jp, n, FORK_NOJOB) == 0) {
636+
reset_handler();
633637
FORCEINTON;
634638
close(pip[0]);
635639
if (pip[1] != 1) {

src/main.c

+8-3
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ int *dash_errno;
7171
short profile_buf[16384];
7272
extern int etext();
7373
#endif
74+
static struct jmploc main_handler;
7475

7576
STATIC void read_profile(const char *);
7677
STATIC char *find_dot_file(char *);
@@ -90,7 +91,6 @@ main(int argc, char **argv)
9091
{
9192
char *shinit;
9293
volatile int state;
93-
struct jmploc jmploc;
9494
struct stackmark smark;
9595
int login;
9696

@@ -102,7 +102,7 @@ main(int argc, char **argv)
102102
monitor(4, etext, profile_buf, sizeof profile_buf, 50);
103103
#endif
104104
state = 0;
105-
if (unlikely(setjmp(jmploc.loc))) {
105+
if (unlikely(setjmp(main_handler.loc))) {
106106
int e;
107107
int s;
108108

@@ -137,7 +137,7 @@ main(int argc, char **argv)
137137
else
138138
goto state4;
139139
}
140-
handler = &jmploc;
140+
handler = &main_handler;
141141
#ifdef DEBUG
142142
opentrace();
143143
trputs("Shell args: "); trargs(argv);
@@ -353,3 +353,8 @@ exitcmd(int argc, char **argv)
353353
exraise(EXEXIT);
354354
/* NOTREACHED */
355355
}
356+
357+
void reset_handler(void)
358+
{
359+
handler = &main_handler;
360+
}

src/main.h

+1
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,4 @@ extern int *dash_errno;
5252
void readcmdfile(char *);
5353
int dotcmd(int, char **);
5454
int exitcmd(int, char **);
55+
void reset_handler(void);

0 commit comments

Comments
 (0)