From patchwork Sun Mar 3 13:57:50 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Herbert Xu X-Patchwork-Id: 10837039 X-Patchwork-Delegate: herbert@gondor.apana.org.au Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 79A8014DE for ; Sun, 3 Mar 2019 13:58:09 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4E55D2A2DE for ; Sun, 3 Mar 2019 13:58:09 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2AACC2A2E8; Sun, 3 Mar 2019 13:58:09 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 457CC2A2DE for ; Sun, 3 Mar 2019 13:58:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726283AbfCCN6H (ORCPT ); Sun, 3 Mar 2019 08:58:07 -0500 Received: from orcrist.hmeau.com ([104.223.48.154]:57500 "EHLO deadmen.hmeau.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726186AbfCCN6H (ORCPT ); Sun, 3 Mar 2019 08:58:07 -0500 Received: from gondobar.mordor.me.apana.org.au ([192.168.128.4] helo=gondobar) by deadmen.hmeau.com with esmtps (Exim 4.89 #2 (Debian)) id 1h0Rcr-0001qG-Vu; Sun, 03 Mar 2019 21:57:58 +0800 Received: from herbert by gondobar with local (Exim 4.89) (envelope-from ) id 1h0Rck-0006WC-47; Sun, 03 Mar 2019 21:57:50 +0800 Date: Sun, 3 Mar 2019 21:57:50 +0800 From: Herbert Xu To: Harald van Dijk Cc: Martijn Dekker , DASH shell mailing list Subject: [v2 PATCH] eval: Reset handler when entering a subshell Message-ID: <20190303135750.hztabicgnifqarut@gondor.apana.org.au> References: <7f1b21c0-d3e7-2f5f-70d5-a4c51b775547@inlv.org> <60da258a-1f73-affc-b564-41fe5ed05764@gigawatt.nl> <20190228062740.qscdy4cqb2ur4h4c@gondor.apana.org.au> <7f21b01c-26d5-3233-6829-baa3b595fe0d@gigawatt.nl> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <7f21b01c-26d5-3233-6829-baa3b595fe0d@gigawatt.nl> User-Agent: NeoMutt/20170113 (1.7.2) Sender: dash-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: dash@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP On Sat, Mar 02, 2019 at 01:28:44PM +0000, Harald van Dijk wrote: > > That is *a* real bug here, not *the* real bug. This leaves the buggy > behaviour of the "command" built-in intact in the test case I included in > the message you replied to. I don't quite understand. Could you explain what is still buggy after the following patch? > For fixing the one bug, it is a sensible approach, but keep in mind that > when a fork is omitted because of EV_EXIT, so too will the reset of handler. > You may be able to get away with that as long as you do not propagate > EV_EXIT in any cases where a cleanup action might cause problems. Good point. Here is a revised patch to fix the nofork case too. ---8<-- 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 Signed-off-by: Herbert Xu diff --git a/src/eval.c b/src/eval.c index 1aad31a..6ee2e1a 100644 --- a/src/eval.c +++ b/src/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/src/main.c b/src/main.c index 6b3a090..b2712cb 100644 --- a/src/main.c +++ b/src/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/src/main.h b/src/main.h index 19e4983..51f1604 100644 --- a/src/main.h +++ b/src/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);