Bug 177663 - execmem allows PROT_WRITE, execmod denies ~PROT_WRITE
execmem allows PROT_WRITE, execmod denies ~PROT_WRITE
Product: Fedora
Classification: Fedora
Component: kernel (Show other bugs)
i386 Linux
medium Severity medium
: ---
: ---
Assigned To: James Morris
Depends On:
  Show dependency treegraph
Reported: 2006-01-12 14:11 EST by John Reiser
Modified: 2007-11-30 17:11 EST (History)
4 users (show)

See Also:
Fixed In Version: 2.6.18-1.2200.fc5
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Last Closed: 2006-10-18 18:42:55 EDT
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---

Attachments (Terms of Use)
mprotect.c: add PROT_WRITE, modify .text, remove PROT_WRITE (1.77 KB, text/plain)
2006-01-12 14:13 EST, John Reiser
no flags Details
Wrap execheap, execstack, and execmod checks with a test for VM_EXEC (2.35 KB, patch)
2006-01-19 07:51 EST, Stephen Smalley
no flags Details | Diff

  None (edit)
Description John Reiser 2006-01-12 14:11:37 EST
From Bugzilla Helper:
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8) Gecko/20060103 Fedora/1.5-4 Firefox/1.5

Description of problem:
A random user program is allowed by execmem to enable PROT_WRITE on its own .text (and modification of the code succeeds), but later is denied by execmod to remove PROT_WRITE from the pages that already have been modified.  SELinux mode is targeted enforcing.

This seems backwards.  First, reducing privileges should be allowed always, so removing PROT_WRITE should succeed.  Second, although the main goal of targeted enforcing mode is protection of system demons and/or server processes, I was under the impression that a random user process was to be discouraged from modifying pages that were PROT_EXEC & ~PROT_WRITE.  So enabling PROT_WRITE on a page that is only PROT_READ | PROT_EXEC should have failed.

Version-Release number of selected component (if applicable):

How reproducible:

Steps to Reproduce:
1. Compile and run the attached program.

Actual Results:  Execmem allows adding PROT_WRITE to a page that is PROT_READ | PROT_EXEC, and modification of the page succeeds.

Execmod denies removing PROT_WRITE from the same page.

Expected Results:  Adding PROT_WRITE to a page that is PROT_READ | PROT_EXEC only, should be denied.

Removing PROT_WRITE from any page that has it, should be allowed always.

Additional info:

Comment 1 John Reiser 2006-01-12 14:13:31 EST
Created attachment 123133 [details]
mprotect.c: add PROT_WRITE, modify .text, remove PROT_WRITE
Comment 3 Stephen Smalley 2006-01-19 07:47:10 EST
Point of clarification:  If the allow_execmem boolean was turned off
(/usr/bin/setsebool allow_execmem=0, and use -P if you want this setting saved
for subsequent reboots), then the initial attempt to add PROT_WRITE would have
failed.  Targeted policy presently leaves it on by default for unconfined_t, as
you would otherwise have significant breakage for many users, but you can
disable it for your system via the boolean.  Note also that the "targeted"
domains confined by that targeted policy should not have that permission, so
they should fail on this test (e.g. chcon -t httpd_exec_t mprotect-bug; runcon
-t initrc_t -- runcon -t httpd_t ./mprotect-bug fails).

On the latter point about removing PROT_WRITE, you are correct that the current
behavior is non-ideal.  I'll attach a patch in a moment.
Comment 4 Stephen Smalley 2006-01-19 07:51:22 EST
Created attachment 123425 [details]
Wrap execheap, execstack, and execmod checks with a test for VM_EXEC
Comment 5 Rahul Sundaram 2006-02-20 06:09:56 EST

These bugs are being closed since a large number of updates have been released
after the FC5 test1 and test2 releases. Kindly update your system by running yum
update as root user or try out the third and final test version of FC5 being
released in a short while and verify if the bugs are still present on the system
.Reopen or file new bug reports as appropriate after confirming the presence of
this issue. Thanks
Comment 6 Dave Jones 2006-10-16 17:44:20 EDT
A new kernel update has been released (Version: 2.6.18-1.2200.fc5)
based upon a new upstream kernel release.

Please retest against this new kernel, as a large number of patches
go into each upstream release, possibly including changes that
may address this problem.

This bug has been placed in NEEDINFO state.
Due to the large volume of inactive bugs in bugzilla, if this bug is
still in this state in two weeks time, it will be closed.

Should this bug still be relevant after this period, the reporter
can reopen the bug at any time. Any other users on the Cc: list
of this bug can request that the bug be reopened by adding a
comment to the bug.

In the last few updates, some users upgrading from FC4->FC5
have reported that installing a kernel update has left their
systems unbootable. If you have been affected by this problem
please check you only have one version of device-mapper & lvm2
installed.  See bug 207474 for further details.

If this bug is a problem preventing you from installing the
release this version is filed against, please see bug 169613.

If this bug has been fixed, but you are now experiencing a different
problem, please file a separate bug for the new problem.

Thank you.
Comment 7 John Reiser 2006-10-17 16:05:29 EDT
Under kernel-2.6.18-1.2200.fc5 with targeted enforcing policy, and running the
mprotect.c testcase of Comment #1, then removing PROT_WRITE succeeds; so half of
the problem has been fixed.  However, adding PROT_WRITE to a page that is
PROT_READ|PROT_EXEC only, still succeeds [and gets no error], even after [as
root] "/usr/sbin/setsebool allow_execmem=0; /usr/sbin/getsebool allow_execmem"
shows that "allow_execmem --> off".  So that half of the problem persists: you
can defeat the intended "don't allow execmem" by starting with
PROT_READ|PROT_EXEC only (no PROT_WRITE), then adding PROT_WRITE using mprotect().

The output from running the testcase was
$ ./mprotect
turn on  PROT_WRITE: 0,  errno=0
00e4a000-00e4b000 r-xp 00e4a000 00:00 0          [vdso]
08048000-08049000 rwxp 00000000 03:0c 822431     /home/jreiser/mprotect
08049000-0804a000 rwxp 00000000 03:0c 822431     /home/jreiser/mprotect
47c78000-47c91000 r-xp 00000000 03:0c 1671197    /lib/ld-2.4.so
47c91000-47c92000 r-xp 00018000 03:0c 1671197    /lib/ld-2.4.so
47c92000-47c93000 rwxp 00019000 03:0c 1671197    /lib/ld-2.4.so
47c95000-47dc2000 r-xp 00000000 03:0c 1671344    /lib/libc-2.4.so
47dc2000-47dc4000 r-xp 0012d000 03:0c 1671344    /lib/libc-2.4.so
47dc4000-47dc5000 rwxp 0012f000 03:0c 1671344    /lib/libc-2.4.so
47dc5000-47dc8000 rwxp 47dc5000 00:00 0
b7f64000-b7f66000 rw-p b7f64000 00:00 0
b7f75000-b7f76000 rw-p b7f75000 00:00 0
bfb9f000-bfbb4000 rw-p bfb9f000 00:00 0          [stack]
*(char *)main = 0x0
turn off PROT_WRITE: 0,  errno=0

Installed packages are:
Comment 8 John Reiser 2006-10-17 16:08:51 EDT
Administrivia: reset "needinfo?" that was set erroneously by bugzilla.
Comment 9 Stephen Smalley 2006-10-18 09:31:19 EDT
getsebool allow_execstack
setsebool allow_execstack=0
(allow_execstack => execmem)
Comment 10 John Reiser 2006-10-18 18:42:55 EDT
OK, comment #9 above works.  With targeted enforcing policy, and turning off
both allow_execmem and allow_execstack, then the testcase of comment #1 sees the
desired behavior under kernel 2.6.18-1.2200.fc5.  Namely, adding PROT_WRITE
fails with EACCES, and turning off PROT_WRITE succeeds.  [Obviously the
statement "*(char *)main = 0;" gets SIGSEGV once the attempt to turn on
PROT_WRITE has failed; so comment out that statement.]

Installed packages are:

Note You need to log in before you can comment on or make changes to this bug.