NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
bin/51119: /bin/sh consumes fds when refusing to source an ELF binary (+FIX)
>Number: 51119
>Category: bin
>Synopsis: /bin/sh consumes fds when refusing to source an ELF binary (+FIX)
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: bin-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Fri May 06 21:45:00 +0000 2016
>Originator: Robert Elz
>Release: NetBSD 7.99.26 (all of NetBSD 5 6 7 & current to date)
>Organization:
>Environment:
System: NetBSD andromeda.noi.kre.to 7.99.26 NetBSD 7.99.26 (VBOX64-1.1-20160128) #43: Thu Jan 28 16:09:08 ICT 2016 kre%onyx.coe.psu.ac.th@localhost:/usr/obj/current/kernels/amd64/VBOX64 amd64
Architecture: x86_64
Machine: amd64
>Description:
Before reading a file, sh reads the first few bytes, to
determine if it is a binary (ELF, not just a binary file)
and if so, refuses to treat it as commands.
That's fine, but when it happens, the fd used is never closed.
Do it often enough, and your shell will have no fd's left.
It has been like this since this check was added in Feb 2007
(which means in all currently supported shells, plus NetBSD 5.)
>How-To-Repeat:
andromeda$ /bin/sh # this is a NetBSD 7.0_BETA /bin/sh
$ . /bin/sh
.: Cannot execute ELF binary /bin/sh
$ fstat -p $$
USER CMD PID FD MOUNT INUM MODE SZ|DV R/W
kre sh 25400 wd /home 4192948 drwxrwxr-x 2560 r
kre sh 25400 0 /dev/pts 31 crwx-w---- pts/14 rw
kre sh 25400 1 /dev/pts 31 crwx-w---- pts/14 rw
kre sh 25400 2 /dev/pts 31 crwx-w---- pts/14 rw
kre sh 25400 3 / 10338 -r-xr-xr-x 175372 r
kre sh 25400 1023 / 10428 crw-rw-rw- tty rw
$ . /bin/sh
.: Cannot execute ELF binary /bin/sh
$ fstat -p $$
USER CMD PID FD MOUNT INUM MODE SZ|DV R/W
kre sh 25400 wd /home 4192948 drwxrwxr-x 2560 r
kre sh 25400 0 /dev/pts 31 crwx-w---- pts/14 rw
kre sh 25400 1 /dev/pts 31 crwx-w---- pts/14 rw
kre sh 25400 2 /dev/pts 31 crwx-w---- pts/14 rw
kre sh 25400 3 / 10338 -r-xr-xr-x 175372 r
kre sh 25400 4 / 10338 -r-xr-xr-x 175372 r
kre sh 25400 1023 / 10428 crw-rw-rw- tty rw
$ . /bin/sh
.: Cannot execute ELF binary /bin/sh
$ fstat -p $$
USER CMD PID FD MOUNT INUM MODE SZ|DV R/W
kre sh 25400 wd /home 4192948 drwxrwxr-x 2560 r
kre sh 25400 0 /dev/pts 31 crwx-w---- pts/14 rw
kre sh 25400 1 /dev/pts 31 crwx-w---- pts/14 rw
kre sh 25400 2 /dev/pts 31 crwx-w---- pts/14 rw
kre sh 25400 3 / 10338 -r-xr-xr-x 175372 r
kre sh 25400 4 / 10338 -r-xr-xr-x 175372 r
kre sh 25400 5 / 10338 -r-xr-xr-x 175372 r
kre sh 25400 1023 / 10428 crw-rw-rw- tty rw
Notice fd's 3, then 4, then 5, just sitting there, all the same file:
$ ls -li /bin/sh
10338 -r-xr-xr-x 1 root wheel 175372 Dec 11 2014 /bin/sh
Note (from reading the source) that the same thing would happen
if (for some reason) it proved impossible to rewind the file.
(I do not currently know how to provoke that one though.)
>Fix:
As a workaround, if this has happened, it is possible to just
use fstat (as above) then
exec 3>&-
exec 4>&-
(etc) for any fd's the shell should not have open. (Don't close
the tty shown here on fd 1023 - especially in current sh's the
fds used for the controlling tty, and for reading files are likely
to be close together, and biggish numbers, so it would be easy to
mistakenly close the tty - that would do bad things to job control.)
Better, apply this patch, which will appear in current soon...
(in this form, or something very similar).
Index: input.c
===================================================================
RCS file: /cvsroot/src/bin/sh/input.c,v
retrieving revision 1.49
diff -u -r1.49 input.c
--- input.c 2 May 2016 01:46:31 -0000 1.49
+++ input.c 6 May 2016 21:38:01 -0000
@@ -404,11 +404,15 @@
*/
if (lseek(fd, 0, SEEK_SET) == 0) {
if (read(fd, magic, 4) == 4) {
- if (memcmp(magic, "\177ELF", 4) == 0)
+ if (memcmp(magic, "\177ELF", 4) == 0) {
+ (void)close(fd);
error("Cannot execute ELF binary %s", fname);
+ }
}
- if (lseek(fd, 0, SEEK_SET) != 0)
+ if (lseek(fd, 0, SEEK_SET) != 0) {
+ (void)close(fd);
error("Cannot rewind the file %s", fname);
+ }
}
fd2 = to_upper_fd(fd); /* closes fd, returns higher equiv */
Home |
Main Index |
Thread Index |
Old Index