On Fri, 19 Nov 2021 13:40:16 -0600 Eric Blake <ebl...@redhat.com> wrote:
> On Fri, Nov 19, 2021 at 03:56:21PM +0000, Kerin Millar wrote: > > On Fri, 19 Nov 2021 10:05:39 -0500 > > Marshall Whittaker <marshallwhitta...@gmail.com> wrote: > > > > > Fair. I'm not saying anyone has to change it, but I will call out what I > > > think is a design flaw. But this is going to turn into some philosophical > > > discussion as to whether it should have been done this way from the start. > > > That I don't know, and hold no responsibility for, as I'm not a bash dev, > > > I'm an exploit dev. Maybe an asshole too. > > > > You appear to be missing the implication; it has nothing in particular to > > do with bash. Consider the following Perl program. At no point is a shell > > involved. > > > > @args = glob('*'); > > system('rm', '-f', @args); # bad > > I had to double-check you via 'strace -f -e execve ...', but you are > right, for this particular example. But according to 'perldoc -f > system', there ARE instances where perl's system() involves a shell: > > Note that argument processing varies depending on the > number of arguments. If there is more than one argument in LIST, > or if LIST is an array with more than one value, starts the > program given by the first element of the list with arguments > given by the rest of the list. If there is only one scalar > argument, the argument is checked for shell metacharacters, and > if there are any, the entire argument is passed to the system's > command shell for parsing (this is "/bin/sh -c" on Unix > > although /bin/sh is not always bash. But that brings up a bug in perl(1): > > $ strace -f -e execve perl -e 'system("echo \$HOME")' > execve("/usr/bin/perl", ["perl", "-e", "system(\"echo \\$HOME\")"], > 0x7ffc3e642e58 /* 72 vars */) = 0 > strace: Process 1248831 attached > [pid 1248831] execve("/bin/sh", ["sh", "-c", "echo $HOME"], 0x55d3099d69d0 /* > 72 vars */) = 0 > /home/eblake > [pid 1248831] +++ exited with 0 +++ > --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=1248831, > si_uid=14986, si_status=0, si_utime=0, si_stime=0} --- > +++ exited with 0 +++ > > According to POSIX, perl should REALLY be passing a "--" argument > between "-c" and the scalar string given by the user; see > https://www.austingroupbugs.net/view.php?id=1440 While perl's system is not an implementation of system(3) per se, I concur. Good find. $ perl -E 'system("-h &")' sh: 0: Illegal option -h That does nobody any good. Indeed, it serves to remind me that even shebangs can be unsafe. $ mkdir -- -h $ printf '%s\n' '#!/bin/sh' > -h/script $ chmod +x -- -h/script $ -h/script sh: 0: Illegal option -h That's with dash as /bin/sh. The only defense would be to write the shebang as "#!/bin/sh --". -- Kerin Millar