From Bugzilla Helper: User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.4.1) Gecko/20031114 Description of problem: I have upgraded 3 systems previously running Red Hat 9 to Fedora Core 1. I also installed prelink on all of these systems. Today I noticed that one of my own applications no longer works: it gets a segmentation violation. I tried running it on the other systems, and to my surprise it worked fine on one system while it also crashed on another. The crash appears to happen inside the C library part of mmap(). When I use strace I see mmap2() being called and returning successfully, but when using ltrace the mmap() function hasn't returned yet. When linking my program statically it worked fine however... Also, when I disabled prelinking (after I ran /etc/cron.daily/prelink by hand) it worked fine too. Please note that the program itself wasn't prelinked yet. I made a small program to demonstrate the effect. Version-Release number of selected component (if applicable): prelink-0.3.0-13 How reproducible: Sometimes Steps to Reproduce: 1. Make sure prelinking is enabled 2. Compile mmap_bug.c with "gcc -Wall -O -g -o mmap_bug mmap_bug.c" 2. Run it with "./mmap_bug" 3. SEGV 4. Repeat with ltrace or strace or gdb Actual Results: The program crashes on some systems. Expected Results: It should have worked just fine (no output expected). Additional info:
Created attachment 96684 [details] Example test program
Hmm, it looks like I spoke too soon... It still crashes sometimes, even with prelinking disabled. After some more investigation, it looks like the Exec-shield functionality has something to do with it too. On my system with Exec-shield enabled and prelink disabled, it still crashes. I understand why too now, because the fixed memory mapping of 4 MB at address 0 my program makes sometimes overlaps with the place where the C library is mapped. Using setarch fixes this issue, and also disabling Exec-shield globally. However, this doesn't work for a prelinked library. I guess I just can't use prelinking in this case, unless I can somehow make it exclude certain memory ranges... (I *need* the memory mapping at address 0 since this is some kind of emulator).
Exec-shield places libraries below the binary (starting from 1MB+4KB up to the beginning of the binary). If your program needs to use MAP_FIXED on a region not given by the kernel to you (e.g. MAP_FIXED on previously returned address from mmap without MAP_FIXED if the region is smaller or equal is always ok), then you need to tell the system about it. The best way is to create a p_flags 0 PT_LOAD segment with p_filesz 0 and p_memsz equal to the size of the region you want to reserve, p_vaddr equal to the start address. Then it will work even with exec-shield, prelinking etc. ATM it is not exactly trivial to create such PT_LOAD segments, it needs quite many changes to the linker script (see PHDRS linker script command), but it is on my TODO list to simplify this. Alternatively, you need to disable exec-shield for that particular program. With rawhide glibc and maybe already rawhide kernel (am not sure whether the patch is in there already) if you build your program as PIE and disable exec-shield for it, it should load even prelinked libraries high. Or, if you don't want exec-shield system-wide, you can add --no-exec-shield option to /etc/sysconfig/prelink and force reprelinking.