Prevent redirecting internal processes to file descriptors above 2

The user may write for example:

    echo foo >&5

and fish would try to output to file descriptor 5, within the fish process
itself. This has unpredictable effects and isn't useful. Make this an
error.

Note that the reverse is "allowed" but ignored:

    echo foo 5>&1

this conceptually dup2s stdout to fd 5, but since no builtin writes to fd
5 we ignore it.
This commit is contained in:
ridiculousfish
2021-02-20 16:16:45 -08:00
parent 622f2868e1
commit 11a373f121
6 changed files with 61 additions and 17 deletions

View File

@@ -23,6 +23,9 @@ $helper print_fds </dev/null
$helper print_fds 3</dev/null
# CHECK: 0 1 2 3
$helper print_fds 5>&2
# CHECK: 0 1 2 5
# This attempts to trip a case where the file opened in fish
# has the same fd as the redirection. In this case, the dup2
# does not clear the CLO_EXEC bit.

View File

@@ -100,10 +100,35 @@ echo $status
read abc <&-
#CHECKERR: read: stdin is closed
# This one should output nothing.
echo derp >&-
# Verify that builtins, blocks, and functions may not write to arbitrary fds.
echo derp >&12
#CHECKERR: {{.*}} Redirection to fd 12 is only valid for external commands
#CHECKERR: echo derp >&12
#CHECKERR: ^
begin
echo derp
end <&42
#CHECKERR: {{.*}} Redirection to fd 42 is only valid for external commands
#CHECKERR: end <&42
#CHECKERR: ^
outnerr 2>&7
#CHECKERR: {{.*}} Redirection to fd 7 is only valid for external commands
#CHECKERR: outnerr 2>&7
#CHECKERR: ^
# Redirection to 0, 1, 2 is allowed. We don't test 0 since writing to stdin is weird and unpredictable.
echo hooray1 >&1
echo hooray2 >&2
#CHECK: hooray1
#CHECKERR: hooray2
# "Verify that pipes don't conflict with fd redirections"
# This code is very similar to eval. We go over a bunch of fads
# This code is very similar to eval. We go over a bunch of fds
# to make it likely that we will nominally conflict with a pipe
# fish is supposed to detect this case and dup the pipe to something else
echo "/bin/echo pipe 3 <&3 3<&-" | source 3<&0
@@ -113,9 +138,6 @@ echo "/bin/echo pipe 6 <&6 6<&-" | source 6<&0
echo "/bin/echo pipe 7 <&7 7<&-" | source 7<&0
echo "/bin/echo pipe 8 <&8 8<&-" | source 8<&0
echo "/bin/echo pipe 9 <&9 9<&-" | source 9<&0
echo "/bin/echo pipe 10 <&10 10<&-" | source 10<&0
echo "/bin/echo pipe 11 <&11 11<&-" | source 11<&0
echo "/bin/echo pipe 12 <&12 12<&-" | source 12<&0
#CHECK: pipe 3
#CHECK: pipe 4
#CHECK: pipe 5
@@ -123,6 +145,3 @@ echo "/bin/echo pipe 12 <&12 12<&-" | source 12<&0
#CHECK: pipe 7
#CHECK: pipe 8
#CHECK: pipe 9
#CHECK: pipe 10
#CHECK: pipe 11
#CHECK: pipe 12