On 26 Jan 2011 at 17:03, Pierre Ynard wrote:

> mprotect(0x4946b000, 3840, PROT_READ|PROT_WRITE) = -1 EACCES (Permission 
> denied)
> --- SIGSEGV (Segmentation fault) @ 0 (0) ---
> +++ killed by SIGSEGV +++
> zsh: segmentation fault  strace -f /usr/lib/vlc/vlc-cache-gen 
> /usr/lib/vlc/plugins
> Note the mprotect() error, as logged by the kernel:
> [1607219.198034] grsec: denied RWX mprotect of /lib/ld-2.11.2.so by
> /usr/lib/vlc/vlc-cache-gen[vlc-cache-gen:15667] uid/euid:0/0 gid/egid:0/0,
> parent /var/lib/dpkg/info/vlc-nox.postinst[vlc-nox.postins:15666] 
> uid/euid:0/0 gid/egid:0/0
> Disabling the mprotect() restriction feature makes the problem go away.
> [...]
> Feel free to forward the bug appropriately, but:
>  - Why is the dynamic loader crashing, instead of handling the error
>    gracefully?
>  - What's up with libSDL-1.2?
>  - It sucks that installation and/or start-up of VLC fails because of
>    one faulty module

this is a long standing bug in glibc and RELRO handling in ld.so. what happens 
is this:

1. ld.so maintains the current stack execution rights in a variable (most of 
the time
   they'd be rw-, i.e., non-executable)
2. said variable is marked to be stored in the RELRO segment of ld.so
3. when a dynamically linked program is started, ld.so performs all the 
relocations, etc
   then as a final step it mprotects the RELRO segments of all binaries 
(including itself)
   as actually read-only
4. PaX/MPROTECT enforces this read-only property in that it denies further 
   requests that would make any part of such RELRO segments writable again 
(which is
   kinda the whole idea behind RELRO)
5. later a library is dlopen'd that wants an executable stack (has a RWE 
GNU_STACK segment)
   so ld.so wants to update this internal variable as well but since it's in 
   segment, it makes that area writable temporarily. this step fails per 4 and 
since the
   mprotect return value is not checked, the attempt of actually writing to the 
   will cause a segfault.

now as you can see there's a cascade of failures here. the fundamental issue is 
whole broken concept of GNU_STACK but i guess debian folks are not about to 
it, so let's look at the next step: putting a writable variable into the RELRO 

it was originally done in the hope that an exploit wouldn't be able to modify 
it either
and therefore prevent a specific ret2libc class of attack that'd abuse ld.so to 
do the
attacker's bidding by creating an rwx stack (let's not digress into how 
pointless this
is). this would work if this variable didn't need to be modified *after* RELRO 
had taken place, but RWE GNU_STACK support for dlopen'd libraries requires 
exactly that
(which of course also circumvents GNU_STACK but let's not digress again ;). so 
what glibc
devs decided to do was to temporarily revert the RELRO segment's read-only 
status to update
the variable but for some reason they didn't check the return value of mprotect 
on grounds that 'it cannot fail' since it's called on a known valid region, etc 
there're many other reasons that can make mprotect fail).

so there you have it in a nutshell. probably the quickest 'fix' is to at least 
add a check
for mprotect's return value but that still won't let this libSDL library to 
load under PaX
and MPROTECT (whether it really needs an executable stack or is just 
incorrectly marked due
to some unmarked .S files is another angle you can investigate).


 PaX Team

pkg-multimedia-maintainers mailing list

Reply via email to