[klibc] [klibc:update-dash] dash: eval: Reset handler when entering a subshell

klibc-bot for Herbert Xu herbert at gondor.apana.org.au
Sat Mar 28 14:49:40 PDT 2020


Commit-ID:  3f314ab5fe4a08b6e8d0ce34465298ba20f90def
Gitweb:     http://git.kernel.org/?p=libs/klibc/klibc.git;a=commit;h=3f314ab5fe4a08b6e8d0ce34465298ba20f90def
Author:     Herbert Xu <herbert at gondor.apana.org.au>
AuthorDate: Sun, 3 Mar 2019 21:57:50 +0800
Committer:  Ben Hutchings <ben at decadent.org.uk>
CommitDate: Sat, 28 Mar 2020 21:42:55 +0000

[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 at inlv.org>
Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
Signed-off-by: Ben Hutchings <ben at decadent.org.uk>

---
 usr/dash/eval.c |  4 ++++
 usr/dash/main.c | 11 ++++++++---
 usr/dash/main.h |  1 +
 3 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/usr/dash/eval.c b/usr/dash/eval.c
index 1aad31a0..6ee2e1a7 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 6b3a0909..b2712cbd 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 19e49835..51f1604c 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);


More information about the klibc mailing list