Bug 10284 - executables with read bit 'off' cannot open /dev/stdin
Summary: executables with read bit 'off' cannot open /dev/stdin
Status: CLOSED PATCH_ALREADY_AVAILABLE
Alias: None
Product: File System
Classification: Unclassified
Component: devfs (show other bugs)
Hardware: All Linux
: P1 normal
Assignee: fs_devfs
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-03-19 13:15 UTC by Joe Carlson
Modified: 2008-03-22 20:01 UTC (History)
1 user (show)

See Also:
Kernel Version: 2.6.16.27-0.9-smp
Subsystem:
Regression: ---
Bisected commit-id:


Attachments

Description Joe Carlson 2008-03-19 13:15:35 UTC
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?
Comment 1 Anonymous Emailer 2008-03-19 14:31:11 UTC
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?
> 
Comment 2 Joe Carlson 2008-03-19 14:45:38 UTC
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?
> > 
> 
> 
Comment 3 Matthew Wilcox 2008-03-19 15:28:59 UTC
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?  ;-)
Comment 4 Joe Carlson 2008-03-19 16:06:52 UTC
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.
Comment 5 Matthew Wilcox 2008-03-19 18:57:10 UTC
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.
Comment 6 Arjan van de Ven 2008-03-19 21:04:08 UTC
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..
Comment 7 Joe Carlson 2008-03-20 10:12:43 UTC
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

Note You need to log in before you can comment on or make changes to this bug.