diff --git a/NEWS b/NEWS index 7b9f485480eb..36e9908f337a 100644 --- a/NEWS +++ b/NEWS @@ -8,6 +8,9 @@ Any uppercase BUG_* names are modernish shell bug IDs. - If a shell function and a built-in command by the same name exist, 'whence -a' and 'type -a' now report both. +- Fixed a bug that caused file descriptors opened with 'redirect' or 'exec' + to survive a subshell environment after exiting it. + 2020-07-19: - Fixed a crash that occured in the '.' command when using kshdb. diff --git a/src/cmd/ksh93/sh/io.c b/src/cmd/ksh93/sh/io.c index 04817c63675a..26ba79c86b07 100644 --- a/src/cmd/ksh93/sh/io.c +++ b/src/cmd/ksh93/sh/io.c @@ -1422,7 +1422,17 @@ int sh_redirect(Shell_t *shp,struct ionod *iop, int flag) sh_iosave(shp,fn,indx,tname?fname:(trunc?Empty:0)); } else if(sh_subsavefd(fn)) + { + if(fd==fn) + { + if((r=sh_fcntl(fd,F_DUPFD,10)) > 0) + { + fd = r; + sh_close(fn); + } + } sh_iosave(shp,fn,indx|IOSUBSHELL,tname?fname:0); + } } if(fd<0) { diff --git a/src/cmd/ksh93/tests/io.sh b/src/cmd/ksh93/tests/io.sh index bfb4b0600635..73f7fc8628a9 100755 --- a/src/cmd/ksh93/tests/io.sh +++ b/src/cmd/ksh93/tests/io.sh @@ -567,5 +567,15 @@ result=$("$SHELL" -ic 'echo >(true) >/dev/null' 2>&1) "$SHELL" -c 'true 9>&20000000000000000000' 2> /dev/null [[ $? == 1 ]] || err_exit "Out of range file descriptors cause redirections to segfault" +# ====== +# A file descriptor opened with 'exec' or 'redirect' leaked out of a subshell. +exec 3>&- # close FD 3 just in case +(exec 3>"$tmp/fdleak.txt") +{ echo bug >&3; } 2>/dev/null +if [[ -s "$tmp/fdleak.txt" ]] +then exec 3>&- + err_exit "Open file descriptor leaks out of subshell" +fi + # ====== exit $((Errors<125?Errors:125))