Problem in a nutshell: SELinux does not protect files and directories labeled as httpd_sys_content_t from being written, deleted or changed when new/custom document root is created.

I have reproduced this behavior twice on different server builds. Environment is clean, fresh install of CentOS 7. Patched completely via yum. epl repo installed. apache, php, mysql (mariadb), phpmyadmin installed.

SELinux is enabled by default on CentOS 7. getenforce and sestatus both confirm that SELinux is running.

I have created a plain virtualhost in apache with its document root set to: /web/sites/test1

At first, everything works as expected. SELinux will not allow apache to display that website until I did the following:

semanage fcontext --add --type httpd_sys_content_t "/web(/.*)?"
semanage fcontext --add --type httpd_sys_content_t "/web/sites(/.*)?"
restorecon -Rv /web

As expected, after doing that, the virtualhost worked.

However, the strange behavior is that upon installing wordpress in that virtualhost, I'm able to upload images and such via wordpress even though the httpd_sys_content_t context should not allow this (according to my understanding).

I have confirmed that all files in the wordpress directory are labeled correctly as type: httpd_sys_content_t

Yet wordpress is still able to write to the directory (so long as old-fashioned file permissions allow it).

I have come up with one solution: Typical/expected behavior is restored upon doing a full filesystem relabeling:

touch /.autorelabel

Upon reboot, I must use the httpd_sys_rw_content_t context as I would expect. But I would like to more clearly understand why such a step is necessary since I've read that a full relabeling should rarely (if ever) be necessary. Is there some easier, less drastic means of getting SELinux to behave as expected?

To be more concise: Should I expect to have to do a "touch /.autorelabel" in a situation like this? Is there a better way? Should it just work without anything else done (and this is therefore a bug with CentOS 7 'out of the box')?

  • While /web/sites/test1/wp-content is set to either 777 or is set to be owned by apache, wordpress can upload to it despite the context of all wordpress files/directories being "only" httpd_sys_content_t rather than httpd_sys_rw_content_t. To my understanding, this is unexpected behavior. And expected behavior (uploading being denied) is only established upon doing a "touch /.autorelable" and rebooting. After full filesystem relabel, uploading is blocked until /web/sites/test1/wp-content is recursively given the httpd_sys_rw_content_t context. At which point, it works (expected behavior). – SELinux Learner Aug 14 '15 at 22:04
  • More concise: My understanding is that SELinux, with the website files confirmed to have the httpd_sys_content_t context assigned, should be blocking uploading of files even with 777 permissions assigned and/or apache assigned as owner. But it's not blocking uploading until after a full filesytem relabeling is done. – SELinux Learner Aug 14 '15 at 22:20

@dawud's comments are incorrect. DAC permissions are checked first. If they deny access, then the process receives permission denied. If DAC allows access, then the selinux MAC policy is checked. If DAC allows access but MAC denies access, then access is denied. DAC can never override MAC. Diagram

Your Wordpress plugin should be labeled with httpd_sys_script_exec_t and therefore run as httpd_sys_script_t. I used apol, the policy analysis tool, to look at the policy on a CentOS VM. Turns out that when the httpd_enable_cgi and httpd_unified booleans are enabled, allow rules are switched on that give processes with the httpd_sys_script_t label full access to objects labeled with httpd_sys_content_t.

Below are the offending rules that get switched on (indicated by the [Enabled] comments). Note that httpdcontent is an SELinux attribute assigned in the policy to all the httpd_sys*content_t labels, so these rules apply to all of them.

allow httpd_sys_script_t httpdcontent : dir { ioctl read write create getattr setattr lock unlink link rename add_name remove_name reparent search rmdir open } ;  [Enabled]
allow httpd_sys_script_t httpdcontent : file { ioctl read write create getattr setattr lock append unlink link rename entrypoint open } ;  [Enabled]
allow httpd_sys_script_t httpdcontent : lnk_file { ioctl read write create getattr setattr lock append unlink link rename } ;  [Enabled]

Also switched on are type transition rules that cause new objects created by an httpd_sys_script_t process in an httpd_sys_content_t-labeled directory to be labeled with httpd_sys_rw_content_t.

type_transition httpd_sys_script_t httpd_sys_content_t : dir httpd_sys_rw_content_t;  [Enabled]
type_transition httpd_sys_script_t httpd_sys_content_t : file httpd_sys_rw_content_t;  [Enabled]
type_transition httpd_sys_script_t httpd_sys_content_t : lnk_file httpd_sys_rw_content_t;  [Enabled]

I checked the Red Hat Apache SELinux docs and found this:

When enabled, this Boolean allows httpd_t complete access to all of the httpd types (that is to execute, read, or write sys_content_t). When disabled, there is separation in place between web content that is read-only, writeable or executable. Disabling this Boolean ensures an extra level of security but adds the administrative overhead of having to individually label scripts and other web content based on the file access that each should have.

Try switching off httpd_unified and see if things behave the way you'd expect.

  • Thanks for clarification Mike. In answer to your question: The files uploaded by wordpress are arriving with httpd_sys_rw_content_t context assigned (note the "RW"). All the way up to the "uploads" directory which wordpress also creates the first time an image is uploaded. Can't figure out why it's able/allowed to actually create that directory either of course. – SELinux Learner Aug 17 '15 at 20:00
  • Tried to replicate this behavior in CentOS 6. That's behaving even stranger. I can't get a identically-configured CentOS 6 stack to even honor SELinux restrictions at all even after a full relabel. It just allows wordpress to upload at will. – SELinux Learner Aug 17 '15 at 20:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.