From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 23916 invoked by alias); 16 Aug 2017 14:51:12 -0000 Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Workers List List-Post: List-Help: X-Seq: 41553 Received: (qmail 8402 invoked by uid 1010); 16 Aug 2017 14:51:12 -0000 X-Qmail-Scanner-Diagnostics: from know-smtprelay-omc-9.server.virginmedia.net by f.primenet.com.au (envelope-from , uid 7791) with qmail-scanner-2.11 (clamdscan: 0.99.2/21882. spamassassin: 3.4.1. Clear:RC:0(80.0.253.73):SA:0(-4.7/5.0):. Processed in 3.353803 secs); 16 Aug 2017 14:51:12 -0000 X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-4.7 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2,SPF_PASS,T_DKIM_INVALID autolearn=ham autolearn_force=no version=3.4.1 X-Envelope-From: p.w.stephenson@ntlworld.com X-Qmail-Scanner-Mime-Attachments: | X-Qmail-Scanner-Zip-Files: | X-Originating-IP: [86.21.219.59] X-Authenticated-User: p.w.stephenson@ntlworld.com X-Spam: 0 X-Authority: v=2.1 cv=aJkN0uJm c=1 sm=1 tr=0 a=utowdAHh8RITBM/6U1BPxA==:117 a=utowdAHh8RITBM/6U1BPxA==:17 a=L9H7d07YOLsA:10 a=9cW_t1CCXrUA:10 a=s5jvgZ67dGcA:10 a=kj9zAlcOel0A:10 a=x7bEGLp0ZPQA:10 a=q2GGsy2AAAAA:8 a=hD80L64hAAAA:8 a=zKgnr2VfwSH0jXdymZwA:9 a=xxh2vz_9ateZN7SM:21 a=KSa4AZOmLcNMtjkA:21 a=CjuIK1q_8ugA:10 a=z9dJwno5l634igLiVhy-:22 Date: Mon, 14 Aug 2017 20:19:39 +0100 From: Peter Stephenson To: Zsh hackers list Subject: Re: fd used for saving redirected fds leaked to child processes Message-ID: <20170814201939.22ba0dcb@ntlworld.com> In-Reply-To: References: <20170813161207.GA6530@chaz.gmail.com> <20170813194939.7a96bc4b@ntlworld.com> <20170814100956.363c7ea8@pwslap01u.europe.root.pri> X-Mailer: Claws Mail 3.11.1 (GTK+ 2.24.28; x86_64-redhat-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ntlworld.com; s=meg.feb2017; t=1502738381; bh=vRzB/NQXYf3oh13VU5KWDHjJZNblcgZ/l8da6W7lNmg=; h=Date:From:To:Subject:In-Reply-To:References; b=eakqxK0wxNGxtJqmMymTXkcfJqODC+gB7P2smRXa/32SRfieV4dJv9FtoNd6DJUEv sHfQYnZfJJ4KAr+B4BjHC8Yg5pYFW1vHbTiMvmW2ycHw3xjceBiNmkwEewxYdkqCk8 KifvKB0V5hiAJsZmguYf33709jXdyjQc+8SbvQtO9fRpWWccEPV7VpbG/DcYW0qmK7 0nHaY3Ru+TXfQ8gp3zb+9GGMOBO80AfnEjMHZoF2yfBln/OofEV5w/pk1lJ7bWI2QW SGqIE3qayH70CfkycWfd8XDil6Zierawhreev8tajxp1u6O8//Z2jTFLzu7GcHzj4Y qxxE1VIEKCdCA== On Mon, 14 Aug 2017 07:49:52 -0700 Bart Schaefer wrote: > On Mon, Aug 14, 2017 at 2:09 AM, Peter Stephenson > wrote: > > > > We need to expose the entire hierarchy for this particular case, but > > that looks like a stack or a linked list, which seems a little > > heavyweight for this case. > > Another flag in the fdtable array? This does that --- this looks easy. It didn't seem convenient to optimise, since once one set of saved fds is restored, exposing any in an enclosing scope, there's no way of working out which the new highest number is without an exhaustive search. pws diff --git a/Src/exec.c b/Src/exec.c index f339dd6..9996dff 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -972,7 +972,7 @@ enum { static void entersubsh(int flags) { - int sig, monitor, job_control_ok; + int i, sig, monitor, job_control_ok; if (!(flags & ESUB_KEEPTRAP)) for (sig = 0; sig < SIGCOUNT; sig++) @@ -1083,6 +1083,14 @@ entersubsh(int flags) opts[MONITOR] = 0; opts[USEZLE] = 0; zleactive = 0; + /* + * If we've saved fd's for later restoring, we're never going + * to restore them now, so just close them. + */ + for (i = 10; i <= max_zsh_fd; i++) { + if (fdtable[i] & FDT_SAVED_MASK) + zclose(i); + } if (flags & ESUB_PGRP) clearjobtab(monitor); get_usage(); @@ -2318,6 +2326,9 @@ addfd(int forked, int *save, struct multio **mfds, int fd1, int fd2, int rflag, return; } save[fd1] = fdN; + DPUTS(fdtable[fdN] != FDT_INTERNAL, + "Saved file descriptor not marked as internal"); + fdtable[fdN] |= FDT_SAVED_MASK; } } } @@ -3575,7 +3586,8 @@ execcmd_exec(Estate state, Execcmd_params eparams, } if (!bad && fn->fd1 <= max_zsh_fd) { if (fn->fd1 >= 10 && - fdtable[fn->fd1] == FDT_INTERNAL) + (fdtable[fn->fd1] & FDT_TYPE_MASK) == + FDT_INTERNAL) bad = 3; } } @@ -4270,7 +4282,7 @@ closem(int how) for (i = 10; i <= max_zsh_fd; i++) if (fdtable[i] != FDT_UNUSED && - (how == FDT_UNUSED || fdtable[i] == how)) { + (how == FDT_UNUSED || (fdtable[i] & FDT_TYPE_MASK) == how)) { if (i == SHTTY) SHTTY = -1; zclose(i); diff --git a/Src/zsh.h b/Src/zsh.h index ccd11db..f42ada7 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -456,6 +456,18 @@ enum { #define FDT_PROC_SUBST 7 #endif +/* + * Mask to get the basic FDT type. + */ +#define FDT_TYPE_MASK 15 + +/* + * Bit flag that fd is saved for later restoration. + * Currently this is only use with FDT_INTERNAL. We use this fact so as + * not to have to mask checks against other types. + */ +#define FDT_SAVED_MASK 16 + /* Flags for input stack */ #define INP_FREE (1<<0) /* current buffer can be free'd */ #define INP_ALIAS (1<<1) /* expanding alias or history */