From Bugzilla Helper: User-Agent: Mozilla/5.0 (X11; U; Linux i686; rv:1.7.3) Gecko/20040914 Firefox/0.10 Description of problem: Running latest Rawhide, firefox, thunderbird, mozilla and gaim fail to start when running in strict/enforcing mode. Trying to start any of these apps produce an AVC showing them trying to get write access to /lib/ld-2.3.3.so: Sep 24 08:19:22 fedora kernel: audit(1096039162.721:0): avc: denied { write } for pid=5656 path=/lib/ld-2.3.3.so dev=hda2 ino=3178536 scontext=user_u:user_r:user_t tcontext=system_u:object_r:ld_so_t tclass=file Running in strict/permissive mode, these apps successfully start and run, and show no modification to /lib/ld-2.3.so. [Konqueror works: it does NOT produce this access violation.] Version-Release number of selected component (if applicable): glibc-2.3.3-55 How reproducible: Always Steps to Reproduce: 1. Install Rawhide 2. Try to start firefox, thunderbird, 3. Additional info:
Created attachment 104305 [details] strace of gaim failing to start under strict/enforcing
Created attachment 104306 [details] strace of gaim starting under strict/permissive
More info. Above 2 attachments are the output of 'strace /usr/bin/gaim', the first under strict/enforcing (it fails), the second under strict/permissive (it succeeds). Under strict/enforcing, gaim fails when a call to 'mprotect()' fails. This same call succeeds when gaim is running in strict/permissive mode. This appears to be where the 'write' AVC to /lib/ld-2.3.3.so is produced.
This looks to me like a policy bug. To the area in question kernel has mmaped /lib/ld-linux.so.2 with MAP_PRIVATE | MAP_DENYWRITE | MAP_FIXED, PROT_READ | PROT_WRITE. Later on, the dynamic linker mprotects this to prevent writes to it: mprotect(0x591000, 4096, PROT_READ) = 0 and later on it wants to make it writable again, in order to change one word in there: mprotect(0x591000, 3788, PROT_READ|PROT_WRITE) = -1 EACCES (Permission denied) but the policy doesn't allow that. Note that this is a MAP_PRIVATE mapping, i.e. writes to that area will not be written into the mmaped file and furthermore the process initially had permissions to write to that area, only when it voluntarily protected that area against writes, it suddenly can't restore it back.
Created attachment 104320 [details] Program showing the problem This program shows the problem. The second mprotect call fails with current kernels. It should not, since the memory area is mapped with MAP_PRIVATE. There is some value in not allowing to switch the permission back (intruders cannot modify the data) but this must be tested for differently. Check whether the mapping comes from a writable segment of the underlying file. This would require knowledge of the ELF file format which is probably too much to ask for.
Created attachment 104408 [details] mprotect test case I've reduced the test case to the attached code. Note that omitting the first mprotect() eliminates the problem: for some reason, mmap(PROT_READ) is causing different behavior to mmap(PROT_READ) followed by mprotect(PROT_READ).
Created attachment 104409 [details] patch to fix selinux mprotect hook selinux_file_mprotect has some obvious bugs that probably explain this issue. This patch is wholly untested, but should fix them. It calls selinux_file_mmap, which has two problems. First, the stacked security module will get both mmap and mprotect callbacks for an mprotect call, which is wrong. Secondly, the vm_flags value contains VM_* bits, and these do not match the MAP_* bits of the same name or function, so it passes bogus flags and causes every mprotect to be treated as if MAP_SHARED were in use. The patch shares the common code while not having one function call the other, and fixes these two bugs.
Created attachment 104410 [details] updated version of roland's patch Here's an updated version of Rolands patch which fixes a couple of compilation bugs. This does indeed seem to fix the problem. We need more testing & review and I'll submit it upstream.
*** Bug 133712 has been marked as a duplicate of this bug. ***
*** Bug 133958 has been marked as a duplicate of this bug. ***
Fixed with kernel-2.6.8-1.598