How to discard stderr in restricted Bash shell?
You can close stderr as in:
ls /blah 2>&-
While that will work in most cases, it may cause problems as poorly written applications may end up opening a new file which would automatically get 2
as the file descriptor and could end up writing error messages where you wouldn't want them to.
That also means that any write to stderr done by the application would return with an error (EBADF) which may affect their behavior.
As pipes are allowed, you could provide with a command that discards all its input. Here, using grep -v '^'
(but you could use tail -n 0
or sed d
or a script called discard
that does cat > /dev/null
):
{ ls /blah 2>&1 >&3 | grep -v '^'; } 3>&1
Alternatively, you could have whatever starts that restricted shell start it with the fd 3 (for instance) redirected to /dev/null
(rbash 3> /dev/null
), so you can then do within the restricted shell:
ls /blah 2>&3
Which is allowed:
$ rbash -c 'ls /blah 2>&3' 3> /dev/null
$
You can check whether redirection to /dev/null
is allowed/works or not with:
if true 2>&- > /dev/null; then
echo allowed
fi
You can check whether the shell is restricted or not with:
case $- in
(*r*) echo restricted
esac
From man rbash
it looks like any redirect is prohibited: (the following are disallowed or not performed)redirecting output using the >, >|, <>, >&, &>, and >> redirection operators
It does look like you can spawn another shell script to do the redirect because When a command that is found to be a shell script is executed, rbash turns off any restrictions in the shell spawned to execute the script.
So, while you couldn't $ foo 2>/dev/null
it looks like you could run $ bar
where bar contains
#/bin/bash
foo 2>/dev/null
It would have to be set up in advance from a full bash environment because rbash also disallowed specifying command names containing /
which looks like it would prohibit your current directory./bar
but not the implicit /bin/bar
Please note: I haven't tried this yet