aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2025-08-09 17:52:09 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2025-08-09 17:52:09 +0200
commit81274d8b3085d59bf5c01a35c17bac3d6952b53d (patch)
tree908a0ee3c9006f779c522b4c661b5c6ac43858ad /shell
parent4ce8afe6b2a989a0360c09a81c6bf9d43d6ba24a (diff)
downloadbusybox-w32-81274d8b3085d59bf5c01a35c17bac3d6952b53d.tar.gz
busybox-w32-81274d8b3085d59bf5c01a35c17bac3d6952b53d.tar.bz2
busybox-w32-81274d8b3085d59bf5c01a35c17bac3d6952b53d.zip
ash: eval: Reset handler when entering a subshell
Upstream commit: Date: Sun, 3 Mar 2019 21:57:50 +0800 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. function old new delta evalsubshell 169 183 +14 evalpipe 342 356 +14 argstr 1406 1416 +10 ash_main 1236 1226 -10 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 4/1 up/down: 65/-10) Total: 28 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell')
-rw-r--r--shell/ash.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/shell/ash.c b/shell/ash.c
index a88fb804a..2c501993b 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -493,6 +493,8 @@ struct globals_misc {
493 493
494 /* Rarely referenced stuff */ 494 /* Rarely referenced stuff */
495 495
496 struct jmploc main_handler;
497
496 /* Cached supplementary group array (for testing executable'ity of files) */ 498 /* Cached supplementary group array (for testing executable'ity of files) */
497 struct cached_groupinfo groupinfo; 499 struct cached_groupinfo groupinfo;
498 500
@@ -529,6 +531,7 @@ extern struct globals_misc *BB_GLOBAL_CONST ash_ptr_to_globals_misc;
529#define may_have_traps (G_misc.may_have_traps ) 531#define may_have_traps (G_misc.may_have_traps )
530#define trap (G_misc.trap ) 532#define trap (G_misc.trap )
531#define trap_ptr (G_misc.trap_ptr ) 533#define trap_ptr (G_misc.trap_ptr )
534#define main_handler (G_misc.main_handler )
532#define groupinfo (G_misc.groupinfo ) 535#define groupinfo (G_misc.groupinfo )
533#define random_gen (G_misc.random_gen ) 536#define random_gen (G_misc.random_gen )
534#define backgndpid (G_misc.backgndpid ) 537#define backgndpid (G_misc.backgndpid )
@@ -594,6 +597,14 @@ sigclearmask(void)
594 sigprocmask_allsigs(SIG_UNBLOCK); 597 sigprocmask_allsigs(SIG_UNBLOCK);
595} 598}
596 599
600/* Reset handler when entering a subshell */
601static void
602reset_exception_handler(void)
603{
604 exception_handler = &main_handler;
605}
606
607
597/* ============ Parser data */ 608/* ============ Parser data */
598 609
599/* 610/*
@@ -6720,6 +6731,7 @@ evalbackcmd(union node *n, struct backcmd *result
6720 jp = (ctl == CTLBACKQ) ? makejob(1) : NULL; 6731 jp = (ctl == CTLBACKQ) ? makejob(1) : NULL;
6721 if (forkshell(jp, n, FORK_NOJOB) == 0) { 6732 if (forkshell(jp, n, FORK_NOJOB) == 0) {
6722 /* child */ 6733 /* child */
6734 reset_exception_handler();
6723 FORCEINTON; 6735 FORCEINTON;
6724 close(pip[ip]); 6736 close(pip[ip]);
6725 /* ic is index of child end of pipe *and* fd to connect it to */ 6737 /* ic is index of child end of pipe *and* fd to connect it to */
@@ -9705,6 +9717,7 @@ evalsubshell(union node *n, int flags)
9705 if (backgnd) 9717 if (backgnd)
9706 flags &= ~EV_TESTED; 9718 flags &= ~EV_TESTED;
9707 nofork: 9719 nofork:
9720 reset_exception_handler();
9708 redirect(n->nredir.redirect, 0); 9721 redirect(n->nredir.redirect, 0);
9709 evaltreenr(n->nredir.n, flags); 9722 evaltreenr(n->nredir.n, flags);
9710 /* never returns */ 9723 /* never returns */
@@ -9817,6 +9830,7 @@ evalpipe(union node *n, int flags)
9817 } 9830 }
9818 if (forkshell(jp, lp->n, n->npipe.pipe_backgnd) == 0) { 9831 if (forkshell(jp, lp->n, n->npipe.pipe_backgnd) == 0) {
9819 /* child */ 9832 /* child */
9833 reset_exception_handler();
9820 INTON; 9834 INTON;
9821 if (pip[1] >= 0) { 9835 if (pip[1] >= 0) {
9822 close(pip[0]); 9836 close(pip[0]);
@@ -14851,7 +14865,6 @@ int ash_main(int argc UNUSED_PARAM, char **argv)
14851/* note: 'argc' is used only if embedded scripts are enabled */ 14865/* note: 'argc' is used only if embedded scripts are enabled */
14852{ 14866{
14853 volatile smallint state; 14867 volatile smallint state;
14854 struct jmploc jmploc;
14855 struct stackmark smark; 14868 struct stackmark smark;
14856 int login_sh; 14869 int login_sh;
14857 14870
@@ -14869,7 +14882,7 @@ int ash_main(int argc UNUSED_PARAM, char **argv)
14869#endif 14882#endif
14870 14883
14871 state = 0; 14884 state = 0;
14872 if (setjmp(jmploc.loc)) { 14885 if (setjmp(main_handler.loc)) {
14873 smallint e; 14886 smallint e;
14874 smallint s; 14887 smallint s;
14875 14888
@@ -14897,7 +14910,7 @@ int ash_main(int argc UNUSED_PARAM, char **argv)
14897 goto state3; 14910 goto state3;
14898 goto state4; 14911 goto state4;
14899 } 14912 }
14900 exception_handler = &jmploc; 14913 exception_handler = &main_handler;
14901 rootpid = getpid(); 14914 rootpid = getpid();
14902 14915
14903 init(); 14916 init();