Feh / nocache

minimize caching effects
BSD 2-Clause "Simplified" License
554 stars 53 forks source link

Segmentation fault with SELinux #1

Closed ghost closed 12 years ago

ghost commented 12 years ago

Hi,

Have you had the opportunity to test nocache on an OS with SELinux installed? When I use it on a RHEL5 (64bit) system, with SELinux installed but disabled, I get a segmentation fault shortly after libsepol (from SELinux) is loaded:

# LD_PRELOAD=/usr/lib64/nocache.so strace -f /bin/ls
execve("/bin/ls", ["/bin/ls"], [/* 28 vars */]) = 0
...
open("/lib64/libsepol.so.1", O_RDONLY)  = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\340<\240\34<\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=247528, ...}) = 0
mmap(0x3c1ca00000, 2383168, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x3c1ca00000
mprotect(0x3c1ca3b000, 2097152, PROT_NONE) = 0
mmap(0x3c1cc3b000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3b000) = 0x3c1cc3b000
mmap(0x3c1cc3c000, 40256, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x3c1cc3c000
close(3)                                = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2ae9698ba000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2ae9698bb000
arch_prctl(ARCH_SET_FS, 0x2ae9698bb390) = 0
mprotect(0x3c1d414000, 4096, PROT_READ) = 0
mprotect(0x37fd002000, 4096, PROT_READ) = 0
mprotect(0x3c1c146000, 16384, PROT_READ) = 0
mprotect(0x3d6f607000, 4096, PROT_READ) = 0
mprotect(0x3c1bc19000, 4096, PROT_READ) = 0
munmap(0x2ae9698a9000, 61160)           = 0
set_tid_address(0x2ae9698bb420)         = 10941
set_robust_list(0x2ae9698bb430, 0x18)   = 0
rt_sigaction(SIGRTMIN, {0x3c1d205350, [], SA_RESTORER|SA_SIGINFO, 0x3c1d20de60}, NULL, 8) = 0
rt_sigaction(SIGRT_1, {0x3c1d2052a0, [], SA_RESTORER|SA_RESTART|SA_SIGINFO, 0x3c1d20de60}, NULL, 8) = 0
rt_sigprocmask(SIG_UNBLOCK, [RTMIN RT_1], NULL, 8) = 0
getrlimit(RLIMIT_STACK, {rlim_cur=10240*1024, rlim_max=RLIM_INFINITY}) = 0
access("/etc/selinux/", F_OK)           = 0
--- SIGSEGV (Segmentation fault) @ 0 (0) ---
+++ killed by SIGSEGV +++

I can use nocache with other binaries not linked against libsepol, on the same machine.

Would you know why this happens, and how to fix it?

Thank you.

And thank you for nocache :)

Feh commented 12 years ago

Hi, Eric-Olivier!

Although SELinux is not enabled as far as I can see, my /bin/ls is nevertheless linked against it. I see the same strace as yours.

Would you know why this happens, and how to fix it?

After a little bit of digging, I know why it doesn't work. It's simply that dlsym() returns a NULL pointer for every lookup of the original function.

You can verify that this is the cause of your segfaults like this:

1) Recompile with debug flags: make -B CFLAGS=-g 2) Allow core dumps: ulimit -c unlimited 3) Make the program crash and dump a core: ./nocache ls 4) Inspect the core using gdb: gdb /bin/ls core 5) Move one frame up and look what _original_fopen is:

(gdb) up

1 0x00007f6c46c2867b in fopen (path=0x7f6c46a1ed7d "/proc/filesystems", mode=0x7f6c46a1ec6b "r") at nocache.c:182

182 if((fp = _original_fopen(path, mode)) != NULL)

(gdb) p _originalfopen $1 = (FILE (_)(const char , const char )) 0

As to why this happens and how to fix it, I'm at a loss, sorry.

Julius

ghost commented 12 years ago

Hi Julius,

Thank you very much for your effort. You might want to add calls to dlerror() in nocache.c's init() function to fail a bit more gracefully :)

I tried to search for issues between SELinux and dlsym() but could not find anything that could explain what happens. I tried on a CentOS 6 system as well and the same thing happens, although binaries are now linked against libselinux instead of libsepol.

I may ask for help on a SELinux mailing list. I will let you know if I can find anything useful.

Thank you for your help.

Feh commented 12 years ago

Hi, Eric-Olivier!

Yeah, I did that while investigating. The thing is: the errors don't show up. I pushed some error handling fixes with 5de2538b362ff6f86e9697168a02c8096f5d0eec, anyway, it might help in some other situations.

I may ask for help on a SELinux mailing list. I will let you know if I can find anything useful.

Thanks!

Julius

Feh commented 12 years ago

I believe this is fixed with e6df5f6. (See issue #2 for details.)

Thanks!