Hide Forgot
Description of problem: I have a mod_python scripts that has "import ctypes" and nothing else. This fails with a "memory" error which results in this snipped from httpd: open("/dev/shm/ffiOG04Hl", O_RDWR|O_CREAT|O_EXCL, 0600) = 18 unlink("/dev/shm/ffiOG04Hl") = 0 ftruncate(18, 4096) = 0 mmap(NULL, 4096, PROT_READ|PROT_EXEC, MAP_SHARED, 18, 0) = -1 EACCES (Permission denied) close(18) = 0 Version-Release number of selected component (if applicable): selinux-policy-3.10.0-69.fc16.noarch selinux-policy-targeted-3.10.0-69.fc16.noarch How reproducible: Always Steps to Reproduce: 1. yum install mod_python and make sure you have an accessible httpd running 2. Create /etc/httpd/conf.d/bug.conf containing this: LoadModule python_module modules/mod_python.so <Location /bug> SetHandler python-program PythonPath "sys.path + ['/var/www/html' ]" PythonHandler bug PythonDebug On </Location> and /var/www/html/bug.py containing just one line: import ctypes 3. Restart httpd and run curl http://localhost/bug Actual results: An error ending with "Memory Error" arising from the import Expected results: AttributeError: module '/var/www/html/bug.py' contains no 'handler' (You can put a handler in if you like with the intention of getting no error at all, but this is only to reproduce the problem after all.) Additional info: From way back, bug 582009 and bug 522731 both mention this. Setting httpd_tmp_exec does work around the problem, though it would seem that this is not the right thing to do.
I believe this is the only solution, you need to be able to create a file that you can write and execute to allow this access. I think this stuff was added to prevent an execmod/execstack avc?
What's odd is that this was a problem around F11 and pygments (which is what does the import ctypes) works just fine from mod_python in F15. I wonder if libffi changed? Does it really need the shared memory to be executable?
Bingo: in libffi/src/closures.c: ------------------------ #if FFI_MMAP_EXEC_SELINUX #include <sys/statfs.h> #include <stdlib.h> static int selinux_enabled = -1; static int selinux_enabled_check (void) { struct statfs sfs; FILE *f; char *buf = NULL; size_t len = 0; if (statfs ("/selinux", &sfs) >= 0 && (unsigned int) sfs.f_type == 0xf97cff8cU) return 1; ... --------------------- That should be /sys/fs/selinux for F16 ... creating a symbolic link from that to /selinux makes libffi work as expected. Changing the component to libffi. Thanks Dan.
is_selinux_enabled() within libselinux is a better way to check this, if you are linking against libselinux. If not then searching for selinuxfs in /proc/filesystems would be a better check to see if the kernel has selinux support. # grep selinuxfs /proc/filesystems nodev selinuxfs /selinux has moved to /sys/fs/selinux in F16. Note that just searching for selinuxfs or the existance of /sys/fs/selinux is not considered enough of a check of whether or not SELinux is fully enabled, which is why I would suggest using is_selinux_enabeled()
(In reply to comment #4) > Note that just searching for selinuxfs or the existance of /sys/fs/selinux is > not considered enough of a check of whether or not SELinux is fully enabled, > which is why I would suggest using is_selinux_enabeled() Hi Dan, libffi author here... Is there a way to tell whether or not SELinux will allow write/exec regions that doesn't involve creation of spurious SELinux errors? See this thread for context: http://sourceware.org/ml/libffi-discuss/2012/msg00180.html Thanks! AG
Well other then we are trying to prevent this. We do not want to allow apps to allocate memory for both write and execute, since this an attack vector for buffer overflow attacks. http://www.akkadia.org/drepper/selinux-mem.html In most cases if it is considered critical that an app do this, then we allow the user to set a boolean to allow this like httpd_execmem or allow_execmem. Anyways your question was about telling if SELinux would allow or deny it. You would have to know the type of the app that is running. For example if you were checking to see if apache allows it, you would check httpd_t and execmem permission. sesearch -CA -s httpd_t -p execmem DT allow httpd_t httpd_t : process { execmem execstack } ; [ httpd_execmem ] This says that it would be allowed but only if the httpd_execmem boolean was turned on and currently it is not. D - tells you whether it is enabled or disabled. sesearch -CA -s unconfined_t -p execmem EF allow unconfined_t unconfined_t : process execmem ; [ allow_execmem ] This is checking for the default user, unconfined_t and it says if the allow_execmem In this case it is enabled "E"
(In reply to comment #6) > Anyways your question was about telling if SELinux would allow or > deny it. You would have to know the type of the app that is running. > For example if you were checking to see if apache allows it, you > would check httpd_t and execmem permission. > > sesearch -CA -s httpd_t -p execmem > DT allow httpd_t httpd_t : process { execmem execstack } ; [ httpd_execmem ] > > This says that it would be allowed but only if the httpd_execmem > boolean was turned on and currently it is not. D - tells you whether > it is enabled or disabled. > > sesearch -CA -s unconfined_t -p execmem > EF allow unconfined_t unconfined_t : process execmem ; [ allow_execmem ] > > This is checking for the default user, unconfined_t and it says if the > allow_execmem In this case it is enabled "E" Yabbut, how to do this programmatically? This is a library, and we want to know if the current process is allowed execmem. Andrew.
Can't you just assume that execmem is not allowed? After all, selinux prevents it simply because it's a particularly rich source of security errors. Otherwise it's like not wearing a seatbelt unless he law demands it: it's no less of a safety feature whether it's legally required or not.
Andrew you can make yourself a resource manage and ask the policy if your current policy allows you to execmem. #include <stdio.h> #include <errno.h> #include <selinux/selinux.h> void main(int argc, char *argv) { int rc; security_context_t con; getcon(&con); rc = selinux_check_access(con, con, "process", "execmem", NULL); switch (rc) { case 0: printf("Allowed\n"); break; case -1: perror("Unknown"); break; default: printf("Denied\n"); } }
(In reply to comment #9) > Andrew you can make yourself a resource manage and ask the policy if your > current policy allows you to execmem. Aha! That is exactly what we need. Thank you very much.
This message is a reminder that Fedora 16 is nearing its end of life. Approximately 4 (four) weeks from now Fedora will stop maintaining and issuing updates for Fedora 16. It is Fedora's policy to close all bug reports from releases that are no longer maintained. At that time this bug will be closed as WONTFIX if it remains open with a Fedora 'version' of '16'. Package Maintainer: If you wish for this bug to remain open because you plan to fix it in a currently maintained version, simply change the 'version' to a later Fedora version prior to Fedora 16's end of life. Bug Reporter: Thank you for reporting this issue and we are sorry that we may not be able to fix it before Fedora 16 is end of life. If you would still like to see this bug fixed and are able to reproduce it against a later version of Fedora, you are encouraged to click on "Clone This Bug" and open it against that version of Fedora. Although we aim to fix as many bugs as possible during every release's lifetime, sometimes those efforts are overtaken by events. Often a more recent Fedora release includes newer upstream software that fixes bugs or makes them obsolete. The process we are following is described here: http://fedoraproject.org/wiki/BugZappers/HouseKeeping
Fedora 16 changed to end-of-life (EOL) status on 2013-02-12. Fedora 16 is no longer maintained, which means that it will not receive any further security or bug fix updates. As a result we are closing this bug. If you can reproduce this bug against a currently maintained version of Fedora please feel free to reopen this bug against that version. Thank you for reporting this bug and we are sorry it could not be fixed.