ld-linux.so allows readable ELF programs on the filesystem to be executed
regardless of their eXecute permission status.
Steps to Reproduce:
1.Make an [ELF] program (or copy one)
2.chmod ugo-x program
4.Amaze your friends!
ld-linux executes the [ELF] program, despite lack of execute permission (and
probably also mount -o noexec!)
Not executed the program. :)
This appears to be a problem in general: getting around the x bit by
constructing a program/exploiting a program to do it for you, and is likely only
truly combatable on a case-by-case basis. In this case, ld-linux should be
fixed to check for x permission. There are likely similar problems with bash
and other shells.
It'd be nice if there were a magic wand to make the kernel enforce the x bit,
but it's hard to do without checking to see if a file is a "program" (for some
definition of "program") [though this could potentially be done by using the
general idea behind part of exec(), i.e. letting each registered program type
vet the file ["is my type"at open() w/read. For files recognized , maybe Linux
kernel should make the permission check at open() succeed if ((not_an_executable
&& read_set) || (an_executable && exec_set && read_set))]
But then you might inconvenience other programs, and you will still leave behind
unknown-to-the-kernel program types (e.g. certain scripts/VMs).
I can confirm the behavior here.
> ld-linux executes the [ELF] program, despite lack of execute permission (and
> probably also mount -o noexec!)
Actually, with noexec it will refuse to load.
(In reply to comment #2)
> > ld-linux executes the [ELF] program, despite lack of execute permission (and
> > probably also mount -o noexec!)
> Actually, with noexec it will refuse to load.
How does this fix the initial problem? Being able to execute -x binaries?
Quite right about the noexec, btw:
-r--r--r-- 1 someuser someuser 8700 Dec 1 12:57 small-read
./small-read: error while loading shared libraries: ./small-read: failed to map
segment from shared object: Operation not permitted
that said, the eXecute issue still remains.
I don't agree that this is RESOLVED at all, however. The security of the
eXectue bit is dubious atm.
> How does this fix the initial problem? Being able to execute -x binaries?
You're the one who closed this bug :) From your comment I assume this was a
mistake, so consider it reopened.
Brix: as I stated, the problem goes beyond binaries and is going to be a Hard
problem to solve well. For now, simply making ld-linux check is sufficient to
stop this <i>particular</i> hole, but one can still execute, for example, a perl
script in /usr/local/bin despite the script being -x:
$ dir /usr/local/bin/foo.pl
-r--r--r-- 1 solarion solarion 51 Dec 1 13:13 /usr/local/bin/foo.pl
$ file /usr/local/bin/foo.pl
/usr/local/bin/foo.pl: perl script text executable
bash: /usr/local/bin/foo.pl: Permission denied
$ perl /usr/local/bin/foo.pl
It's also interesting to note that bash is a good citizen: it checks permissions:
$ dir /usr/local/bin/a.out
-rw-r--r-- 1 solarion solarion 49 Oct 3 2000 /usr/local/bin/a.out
$ file /usr/local/bin/a.out
/usr/local/bin/a.out: Bourne shell script text executable
$ bash /usr/local/bin/a.out
Use ./a.out instead.
/usr/local/bin/a.out: line 4: ./a.out: Permission denied
[as an aside, /usr/local/bin/a.out in every user's path is an evil thing to do
in a multiuser environment, but helpful on your own machine ;]
(In reply to comment #5)
> You're the one who closed this bug :) From your comment I assume this was a
> mistake, so consider it reopened.
Errr... oops. :)
1/ First of all, I've missed why it this filed to Gentoo bugzilla. This is
*absolutely not* a Gentoo-specific problem.
2/ This has been known for a long time, and used to work even with noexec
mounted partitions, later on this has been fixed in kernel (about two years ago)
and you cannot bypass noexec mount in this way any more.
3/ If you don't like the current behaviour, then use PaX/SELinux/whatever else
to get the desired behaviour...
Why not remove perl, python and ruby interpreters then?
Because you can always pass them the scripts as stdin
perl < /path/to/a/perl/script (-x)
python < /path/to/a/python/script (-x)
ruby < /path/to/a/ruby/script (-x)
It's an unsolvable problem from that pov.
I agree with jakub on this.