1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-02-15 04:32:24 +00:00

do not save file desc state for subshares (re: 6304dfce, fb755163)

The >&- redirection subshell leak fixed in 6304dfce still existed
for shared-state ${ command substitutions; } a.k.a. subshares,
which cannot be forked.

I previously noticed that sh_subsavefd() saves the FD state even
for subshares. That seems logically incorrect as subshares share
their state with the invoking environment by definition.

src/cmd/ksh93/sh/subshell.c: sh_subsavefd():
- Sure enough, adding a check for !sh.subshare fixes the bug.
- Use the sh.subshell counter and not the subshell data pointer to
  check for a virtual subshell. If the shell is reinitialised in a
  fork to execute a new script (see 0af81992), any parent virtual
  subshell data is currently not cleared as it is locally scoped to
  subshell.c, so that check would be incorrect then.

src/cmd/ksh93/sh/io.c: sh_redirect:
- Remove now-redundant (and actually incorrectly placed) check for
  sh.subshare added in fb755163.
This commit is contained in:
Martijn Dekker 2022-02-11 03:17:45 +00:00
parent 6304dfce41
commit 1cdd963f53
3 changed files with 9 additions and 2 deletions

View file

@ -1468,7 +1468,7 @@ int sh_redirect(struct ionod *iop, int flag)
}
else if(sh_subsavefd(fn))
{
if(fd==fn && !sh.subshare)
if(fd==fn)
{
if((r=sh_fcntl(fd,F_DUPFD,10)) > 0)
{

View file

@ -442,7 +442,7 @@ int sh_subsavefd(register int fd)
{
register struct subshell *sp = subshell_data;
register int old=0;
if(sp)
if(sh.subshell && !sh.subshare)
{
old = !(sp->fdsaved&(1<<fd));
sp->fdsaved |= (1<<fd);

View file

@ -953,6 +953,13 @@ got=$(
)
[[ $got == 'test' ]] || err_exit "issue 161 hypothetical bug 2" \
"(expected 'test', got $(printf %q "$got"))"
got=$(
exec 4>&1
foo=${ { redirect 4>&1; } 6<&2 4<&-; }
echo "test" >&4 # => 4: cannot open [Bad file descriptor]
)
[[ $got == 'test' ]] || err_exit "File descriptor is unexpectedly closed after exec in shared-state command substitution" \
"(expected 'test', got $(printf %q "$got"))"
# ======
exit $((Errors<125?Errors:125))