Latest working kernel version: 2.6.16.27 Earliest failing kernel version: 2.4.21 Distribution: suse Hardware Environment: x86_64 Software Environment: Problem Description: if the read bit of a binary executable is off, then open() on /dev/stdin fails with a EACCES error. Steps to reproduce: A short program that calls open on /dev/stdin: cat open_stdin.c #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int main(int argc, char **argv) { open("/dev/stdin",O_RDONLY); return 0; } tracing system calls with normal operation shows that this completes successfully. But: chmod -r open_stdin strace ./open_stdin execve("./open_stdin", ["./open_stdin"], [/* 96 vars */]) = 0 brk(0) = 0x501000 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2b25d01b6000 uname({sys="Linux", node="lush", ...}) = 0 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) ... (open's on .so's deleted) ... open("/etc/ld.so.cache", O_RDONLY) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=158841, ...}) = 0 mmap(NULL, 158841, PROT_READ, MAP_PRIVATE, 3, 0) = 0x2b25d01b7000 close(3) = 0 open("/lib64/libc.so.6", O_RDONLY) = 3 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0P\322\1\0"..., 832) = 832 fstat(3, {st_mode=S_IFREG|0755, st_size=1475924, ...}) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2b25d01de000 mmap(NULL, 2289896, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x2b25d02b8000 madvise(0x2b25d02b8000, 2289896, MADV_SEQUENTIAL|0x1) = 0 mprotect(0x2b25d03df000, 1044480, PROT_NONE) = 0 mmap(0x2b25d04de000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x126000) = 0x2b25d04de000 mmap(0x2b25d04e3000, 16616, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x2b25d04e3000close(3) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2b25d04e8000 arch_prctl(ARCH_SET_FS, 0x2b25d04e86d0) = 0 mprotect(0x2b25d04de000, 12288, PROT_READ) = 0 munmap(0x2b25d01b7000, 158841) = 0 open("/dev/stdin", O_RDONLY) = -1 EACCES (Permission denied) The last line shows a Permission denied error on opening /dev/stdin. If a normal filesystem (i.e. not-/dev/) filename is used, the open works normally. I have reproduced this on 2.4 and 2.6 kernels Just a guess here: is an error flag from attempting to read the binary not getting cleared and is being reported when trying to open stdin?
Reply-To: akpm@linux-foundation.org (switched to email. Please respond via emailed reply-to-all, not via the bugzilla web interface). On Wed, 19 Mar 2008 13:15:36 -0700 (PDT) bugme-daemon@bugzilla.kernel.org wrote: > http://bugzilla.kernel.org/show_bug.cgi?id=10284 > > Summary: executables with read bit 'off' cannot open /dev/stdin > Product: File System > Version: 2.5 > KernelVersion: 2.6.16.27-0.9-smp > Platform: All > OS/Version: Linux > Tree: Mainline > Status: NEW > Severity: normal > Priority: P1 > Component: devfs > AssignedTo: fs_devfs@kernel-bugs.osdl.org > ReportedBy: joe@fruitfly.org > > > Latest working kernel version: 2.6.16.27 > Earliest failing kernel version: 2.4.21 > Distribution: suse > Hardware Environment: x86_64 > Software Environment: > Problem Description: if the read bit of a binary executable is off, then > open() > on /dev/stdin fails with a EACCES error. This is, umm, unexpected? > Steps to reproduce: > A short program that calls open on /dev/stdin: > > cat open_stdin.c > #include <stdio.h> > #include <stdlib.h> > #include <sys/types.h> > #include <sys/stat.h> > #include <fcntl.h> > > int main(int argc, char **argv) { > open("/dev/stdin",O_RDONLY); > return 0; > } > > tracing system calls with normal operation shows that this completes > successfully. But: > > chmod -r open_stdin > strace ./open_stdin > execve("./open_stdin", ["./open_stdin"], [/* 96 vars */]) = 0 > brk(0) = 0x501000 > mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = > 0x2b25d01b6000 > uname({sys="Linux", node="lush", ...}) = 0 > access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or > directory) > ... (open's on .so's deleted) ... > open("/etc/ld.so.cache", O_RDONLY) = 3 > fstat(3, {st_mode=S_IFREG|0644, st_size=158841, ...}) = 0 > mmap(NULL, 158841, PROT_READ, MAP_PRIVATE, 3, 0) = 0x2b25d01b7000 > close(3) = 0 > open("/lib64/libc.so.6", O_RDONLY) = 3 > read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0P\322\1\0"..., 832) = > 832 > fstat(3, {st_mode=S_IFREG|0755, st_size=1475924, ...}) = 0 > mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = > 0x2b25d01de000 > mmap(NULL, 2289896, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = > 0x2b25d02b8000 > madvise(0x2b25d02b8000, 2289896, MADV_SEQUENTIAL|0x1) = 0 > mprotect(0x2b25d03df000, 1044480, PROT_NONE) = 0 > mmap(0x2b25d04de000, 20480, PROT_READ|PROT_WRITE, > MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x126000) = 0x2b25d04de000 > mmap(0x2b25d04e3000, 16616, PROT_READ|PROT_WRITE, > MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x2b25d04e3000close(3) > = 0 > mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = > 0x2b25d04e8000 > arch_prctl(ARCH_SET_FS, 0x2b25d04e86d0) = 0 > mprotect(0x2b25d04de000, 12288, PROT_READ) = 0 > munmap(0x2b25d01b7000, 158841) = 0 > open("/dev/stdin", O_RDONLY) = -1 EACCES (Permission denied) > > > The last line shows a Permission denied error on opening /dev/stdin. If a > normal filesystem (i.e. not-/dev/) filename is used, the open works normally. > > I have reproduced this on 2.4 and 2.6 kernels > Just a guess here: is an error flag from attempting to read the binary not > getting cleared and is being reported when trying to open stdin? >
On Wed, 2008-03-19 at 14:31 -0700, bugme-daemon@bugzilla.kernel.org wrote: > http://bugzilla.kernel.org/show_bug.cgi?id=10284 > > > > > > ------- Comment #1 from anonymous@kernel-bugs.osdl.org 2008-03-19 14:31 > ------- > Reply-To: akpm@linux-foundation.org > > > (switched to email. Please respond via emailed reply-to-all, not via the > bugzilla web interface). > > On Wed, 19 Mar 2008 13:15:36 -0700 (PDT) > bugme-daemon@bugzilla.kernel.org wrote: > > > http://bugzilla.kernel.org/show_bug.cgi?id=10284 > > > > Summary: executables with read bit 'off' cannot open /dev/stdin > > Product: File System > > Version: 2.5 > > KernelVersion: 2.6.16.27-0.9-smp > > Platform: All > > OS/Version: Linux > > Tree: Mainline > > Status: NEW > > Severity: normal > > Priority: P1 > > Component: devfs > > AssignedTo: fs_devfs@kernel-bugs.osdl.org > > ReportedBy: joe@fruitfly.org > > > > > > Latest working kernel version: 2.6.16.27 > > Earliest failing kernel version: 2.4.21 > > Distribution: suse > > Hardware Environment: x86_64 > > Software Environment: > > Problem Description: if the read bit of a binary executable is off, then > open() > > on /dev/stdin fails with a EACCES error. > > This is, umm, unexpected? > this is, well duh, unexpected. ./here_is_my_program_that_reads_a_file my_file works OK. ./here_is_my_program_that_reads_a_file /dev/stdin < my_file gets a permission denied error. This seems like normal behavior? If so, you should contact Sun. They've clearly gotten it wrong. > > Steps to reproduce: > > A short program that calls open on /dev/stdin: > > > > cat open_stdin.c > > #include <stdio.h> > > #include <stdlib.h> > > #include <sys/types.h> > > #include <sys/stat.h> > > #include <fcntl.h> > > > > int main(int argc, char **argv) { > > open("/dev/stdin",O_RDONLY); > > return 0; > > } > > > > tracing system calls with normal operation shows that this completes > > successfully. But: > > > > chmod -r open_stdin > > strace ./open_stdin > > execve("./open_stdin", ["./open_stdin"], [/* 96 vars */]) = 0 > > brk(0) = 0x501000 > > mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = > > 0x2b25d01b6000 > > uname({sys="Linux", node="lush", ...}) = 0 > > access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or > directory) > > ... (open's on .so's deleted) ... > > open("/etc/ld.so.cache", O_RDONLY) = 3 > > fstat(3, {st_mode=S_IFREG|0644, st_size=158841, ...}) = 0 > > mmap(NULL, 158841, PROT_READ, MAP_PRIVATE, 3, 0) = 0x2b25d01b7000 > > close(3) = 0 > > open("/lib64/libc.so.6", O_RDONLY) = 3 > > read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0P\322\1\0"..., 832) > = > > 832 > > fstat(3, {st_mode=S_IFREG|0755, st_size=1475924, ...}) = 0 > > mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = > > 0x2b25d01de000 > > mmap(NULL, 2289896, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = > > 0x2b25d02b8000 > > madvise(0x2b25d02b8000, 2289896, MADV_SEQUENTIAL|0x1) = 0 > > mprotect(0x2b25d03df000, 1044480, PROT_NONE) = 0 > > mmap(0x2b25d04de000, 20480, PROT_READ|PROT_WRITE, > > MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x126000) = 0x2b25d04de000 > > mmap(0x2b25d04e3000, 16616, PROT_READ|PROT_WRITE, > > MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x2b25d04e3000close(3) > > = 0 > > mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = > > 0x2b25d04e8000 > > arch_prctl(ARCH_SET_FS, 0x2b25d04e86d0) = 0 > > mprotect(0x2b25d04de000, 12288, PROT_READ) = 0 > > munmap(0x2b25d01b7000, 158841) = 0 > > open("/dev/stdin", O_RDONLY) = -1 EACCES (Permission denied) > > > > > > The last line shows a Permission denied error on opening /dev/stdin. If a > > normal filesystem (i.e. not-/dev/) filename is used, the open works > normally. > > > > I have reproduced this on 2.4 and 2.6 kernels > > Just a guess here: is an error flag from attempting to read the binary not > > getting cleared and is being reported when trying to open stdin? > > > >
On Wed, Mar 19, 2008 at 02:31:08PM -0700, Andrew Morton wrote: > > Problem Description: if the read bit of a binary executable is off, then > open() > > on /dev/stdin fails with a EACCES error. > > This is, umm, unexpected? I'm not sure it's unexpected. It's undesirable, certainly. > > open("/dev/stdin", O_RDONLY) = -1 EACCES (Permission denied) > > > > The last line shows a Permission denied error on opening /dev/stdin. If a > > normal filesystem (i.e. not-/dev/) filename is used, the open works > normally. > > > > I have reproduced this on 2.4 and 2.6 kernels > > Just a guess here: is an error flag from attempting to read the binary not > > getting cleared and is being reported when trying to open stdin? I think the guess is faulty. Could you show ls -l /dev/stdin ? On my system, it reports: lrwxrwxrwx 1 root root 15 2008-03-10 11:03 /dev/stdin -> /proc/self/fd/0 Wild guess: Users can't access /proc/ directories of executables with the read-bit clear in order to prevent users from reading the state anyway. I wonder how effective clearing the read-bit is these days. Don't we all have source to all the applications anyway? ;-)
On Wed, 2008-03-19 at 15:28 -0700, bugme-daemon@bugzilla.kernel.org wrote: > http://bugzilla.kernel.org/show_bug.cgi?id=10284 > > > > > > ------- Comment #3 from matthew@wil.cx 2008-03-19 15:28 ------- > On Wed, Mar 19, 2008 at 02:31:08PM -0700, Andrew Morton wrote: > > > Problem Description: if the read bit of a binary executable is off, then > open() > > > on /dev/stdin fails with a EACCES error. > > > > This is, umm, unexpected? > > I'm not sure it's unexpected. It's undesirable, certainly. > > > > open("/dev/stdin", O_RDONLY) = -1 EACCES (Permission denied) > > > > > > The last line shows a Permission denied error on opening /dev/stdin. If a > > > normal filesystem (i.e. not-/dev/) filename is used, the open works > normally. > > > > > > I have reproduced this on 2.4 and 2.6 kernels > > > Just a guess here: is an error flag from attempting to read the binary > not > > > getting cleared and is being reported when trying to open stdin? > > I think the guess is faulty. Could you show ls -l /dev/stdin ? On my > system, it reports: > > lrwxrwxrwx 1 root root 15 2008-03-10 11:03 /dev/stdin -> /proc/self/fd/0 > > Wild guess: Users can't access /proc/ directories of executables with the > read-bit clear in order to prevent users from reading the state anyway. > ls -l /dev/stdin lrwxrwxrwx 1 root root 15 2007-04-13 01:08 /dev/stdin -> /proc/self/fd/0 ls -l /proc/self/fd/0 lrwx------ 1 joe genome 64 2008-03-19 22:24 /proc/self/fd/0 -> /dev/pts/0 ls -l /dev/pts/0 crw--w---- 1 joe tty 136, 0 2008-03-19 22:31 /dev/pts/0 permissions look OK to me. In any case, why should toggling the read bit on the executable affect this? > I wonder how effective clearing the read-bit is these days. > Don't we all have source to all the applications anyway? ;-) > > I'll work on clearing the read bit if you work on rewriting the unix books.
On Wed, Mar 19, 2008 at 02:31:08PM -0700, Andrew Morton wrote: > (switched to email. Please respond via emailed reply-to-all, not via the > bugzilla web interface). Unfortunately, Joe seems not to be able to follow that instruction. He's left two comments in bugzilla which are not reflected in this email thread. > > KernelVersion: 2.6.16.27-0.9-smp > > A short program that calls open on /dev/stdin: > > > > cat open_stdin.c > > #include <stdio.h> > > #include <stdlib.h> > > #include <sys/types.h> > > #include <sys/stat.h> > > #include <fcntl.h> > > > > int main(int argc, char **argv) { > > open("/dev/stdin",O_RDONLY); > > return 0; > > } I've tried this program on 2.6.25-rc3-00093-g59e1338-dirty and it does not fail. > > open("/dev/stdin", O_RDONLY) = -1 EACCES (Permission denied) Specifically, my tests show: open-stdin-readable:open("/dev/stdin", O_RDONLY) = 3 open-stdin-unreadable:open("/dev/stdin", O_RDONLY) = 3 Joe, can you try a more recent kernel? Another thing to try would be opening /proc/self/fd/0 or /dev/pts/0 in your program and seeing whether those fail.
On Wed, 19 Mar 2008 19:56:50 -0600 Matthew Wilcox <matthew@wil.cx> wrote: > I've tried this program on 2.6.25-rc3-00093-g59e1338-dirty and it does > not fail. > > > > open("/dev/stdin", O_RDONLY) = -1 EACCES (Permission > > > denied) > > Specifically, my tests show: > > open-stdin-readable:open("/dev/stdin", O_RDONLY) = 3 > open-stdin-unreadable:open("/dev/stdin", O_RDONLY) = 3 > > Joe, can you try a more recent kernel? another interesting question is if you're using some special LSM/security stuff..
On Wed, 2008-03-19 at 18:57 -0700, bugme-daemon@bugzilla.kernel.org wrote: > http://bugzilla.kernel.org/show_bug.cgi?id=10284 > > > > > > ------- Comment #5 from matthew@wil.cx 2008-03-19 18:57 ------- > On Wed, Mar 19, 2008 at 02:31:08PM -0700, Andrew Morton wrote: > > (switched to email. Please respond via emailed reply-to-all, not via the > > bugzilla web interface). > > Unfortunately, Joe seems not to be able to follow that instruction. > He's left two comments in bugzilla which are not reflected in this email > thread. > I'm honestly puzzled by this remark. What two comments are you referring to? > > > KernelVersion: 2.6.16.27-0.9-smp > > > A short program that calls open on /dev/stdin: > > > > > > cat open_stdin.c > > > #include <stdio.h> > > > #include <stdlib.h> > > > #include <sys/types.h> > > > #include <sys/stat.h> > > > #include <fcntl.h> > > > > > > int main(int argc, char **argv) { > > > open("/dev/stdin",O_RDONLY); > > > return 0; > > > } > > I've tried this program on 2.6.25-rc3-00093-g59e1338-dirty and it does > not fail. > > > > open("/dev/stdin", O_RDONLY) = -1 EACCES (Permission denied) > > Specifically, my tests show: > > open-stdin-readable:open("/dev/stdin", O_RDONLY) = 3 > open-stdin-unreadable:open("/dev/stdin", O_RDONLY) = 3 > > Joe, can you try a more recent kernel? > > Another thing to try would be opening /proc/self/fd/0 or /dev/pts/0 > in your program and seeing whether those fail. > > I'm collecting data from the available systems here. I'm trying to the /dev/stdin or the device file that /dev/stdin points to. I chase the link untill it terminates. Chasing the link is different on the different machines. In all cases ls -l shows owner read/write permissions on the device. There are no special security modules installed and these are all out-of-the-box kernels. With the read bit set on the binary it works in all cases. old kernel 2.4.21-231-smp i686 SUSE distribution with read bit clear: /dev/stdin EACCESS /dev/fd/0 EACCESS /dev/pts/5 success 2.6.8-24-default i686 SUSE distribution with read bit clear: /dev/stdin success /dev/fd/0 success /dev/pts/5 success 2.6.16.27-0.9-smp x86_64 SUSE distribution. with read bit clear: /dev/stdin EACCESS /proc/self/fd/0 EACCESS /dev/pts/0 success 2.6.22-14-generic i686 Ubuntu with read bit clear: /dev/stdin success /proc/self/fd/0 success /dev/pts/10 success In summary: broken in my 2.4 kernel, fixed in 2.6.8, broke in 2.6.16 and fixed in 2.6.22