Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 379879 - php-fpm cannot start with selinux
Summary: php-fpm cannot start with selinux
Status: RESOLVED FIXED
Alias: None
Product: Gentoo Linux
Classification: Unclassified
Component: Hardened (show other bugs)
Hardware: All Linux
: Normal normal (vote)
Assignee: Matthew Thode ( prometheanfire )
URL:
Whiteboard: sec-policy r14
Keywords:
Depends on:
Blocks:
 
Reported: 2011-08-19 17:08 UTC by Matthew Thode ( prometheanfire )
Modified: 2012-08-20 22:03 UTC (History)
3 users (show)

See Also:
Package list:
Runtime testing required: ---


Attachments
phpfpm.te (phpfpm.te,616 bytes, text/plain)
2011-08-21 06:44 UTC, Matthew Thode ( prometheanfire )
Details
should be good for upstream (phpfpm.te,1.97 KB, text/plain)
2011-08-25 22:33 UTC, Matthew Thode ( prometheanfire )
Details
file context (phpfpm.fc,440 bytes, text/plain)
2011-08-25 22:36 UTC, Matthew Thode ( prometheanfire )
Details
phpfpm.te (phpfpm.te,2.27 KB, text/plain)
2011-09-07 20:15 UTC, Matthew Thode ( prometheanfire )
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Matthew Thode ( prometheanfire ) archtester Gentoo Infrastructure gentoo-dev Security 2011-08-19 17:08:28 UTC
Log from manual start
type=AVC msg=audit(1313770602.418:222): avc:  denied  { read } for  pid=15808 comm="php-fpm" name=".index" dev=dm-0 ino=202154 scontext=system_u:system_r:initrc_t tcontext=system_u:object_r:snmpd_var_lib_t tclass=file
type=AVC msg=audit(1313770602.418:222): avc:  denied  { open } for  pid=15808 comm="php-fpm" name=".index" dev=dm-0 ino=202154 scontext=system_u:system_r:initrc_t tcontext=system_u:object_r:snmpd_var_lib_t tclass=file
type=SYSCALL msg=audit(1313770602.418:222): arch=c000003e syscall=2 success=yes exit=4 a0=72ffc7b8af70 a1=0 a2=1b6 a3=0 items=0 ppid=15807 pid=15808 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=2 comm="php-fpm" exe="/usr/lib64/php5.3/bin/php-fpm" subj=system_u:system_r:initrc_t key=(null)
type=AVC msg=audit(1313770602.458:223): avc:  denied  { name_bind } for  pid=15809 comm="php-fpm" src=9000 scontext=system_u:system_r:initrc_t tcontext=system_u:object_r:port_t tclass=tcp_socket
type=SYSCALL msg=audit(1313770602.458:223): arch=c000003e syscall=49 success=yes exit=0 a0=7 a1=72ffc7b8b230 a2=10 a3=72ffc7b8b0f4 items=0 ppid=15808 pid=15809 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=2 comm="php-fpm" exe="/usr/lib64/php5.3/bin/php-fpm" subj=system_u:system_r:initrc_t key=(null)

Log from init
type=AVC msg=audit(1313415302.726:39): avc:  denied  { read } for  pid=1838 comm="php-fpm" name=".index" dev=dm-0 ino=202154 scontext=system_u:system_r:initrc_t tcontext=system_u:object_r:snmpd_var_lib_t tclass=file
type=SYSCALL msg=audit(1313415302.726:39): arch=c000003e syscall=2 success=no exit=-13 a0=73a594da3c90 a1=0 a2=1b6 a3=0 items=0 ppid=1837 pid=1838 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=4294967295 comm="php-fpm" exe="/usr/lib64/php5.3/bin/php-fpm" subj=system_u:system_r:initrc_t key=(null)
type=AVC msg=audit(1313415302.726:40): avc:  denied  { write } for  pid=1838 comm="php-fpm" name=".index" dev=dm-0 ino=202154 scontext=system_u:system_r:initrc_t tcontext=system_u:object_r:snmpd_var_lib_t tclass=file
type=SYSCALL msg=audit(1313415302.726:40): arch=c000003e syscall=2 success=no exit=-13 a0=73a594da3b60 a1=241 a2=1b6 a3=1 items=0 ppid=1837 pid=1838 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=4294967295 comm="php-fpm" exe="/usr/lib64/php5.3/bin/php-fpm" subj=system_u:system_r:initrc_t key=(null)
type=AVC msg=audit(1313415303.105:41): avc:  denied  { name_bind } for  pid=1839 comm="php-fpm" src=9000 scontext=system_u:system_r:initrc_t tcontext=system_u:object_r:port_t tclass=tcp_socket
type=SYSCALL msg=audit(1313415303.105:41): arch=c000003e syscall=49 success=no exit=-13 a0=7 a1=73a594da3f50 a2=10 a3=73a594da3e14 items=0 ppid=1838 pid=1839 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=4294967295 comm="php-fpm" exe="/usr/lib64/php5.3/bin/php-fpm" subj=system_u:system_r:initrc_t key=(null)

Patch that fixes it:
module phpfpm 1.0;

require {
        type snmpd_var_lib_t;
        type port_t;
        type initrc_t;
        class tcp_socket name_bind;
        class file { read write open };
}

#============= initrc_t ==============
allow initrc_t port_t:tcp_socket name_bind;
allow initrc_t snmpd_var_lib_t:file { read write open };

Question:
Why does it need snmpd_var_lib_t?
Comment 1 Matthew Thode ( prometheanfire ) archtester Gentoo Infrastructure gentoo-dev Security 2011-08-19 19:04:35 UTC
Looks like it was access to this file.

202154 -rw-r--r--. 1 root root system_u:object_r:snmpd_var_lib_t 1984 Aug  1 17:27 /usr/share/snmp/mibs/.index

php had snmp support compiled in.
Comment 2 Matthew Thode ( prometheanfire ) archtester Gentoo Infrastructure gentoo-dev Security 2011-08-21 06:18:25 UTC
It also looks like the php-fpm processes cannot read the /var/www directory
I don't want to give initrc_t access to that (that is what php-fpm is running as)

system_u:system_r:initrc_t      nginx     1920  0.0  0.7 145160 15220 ?        S    Aug19   0:00 php-fpm: pool www

does php-fpm needs it's own domain?
Comment 3 Matthew Thode ( prometheanfire ) archtester Gentoo Infrastructure gentoo-dev Security 2011-08-21 06:25:04 UTC
Here is what I'm using for now to get php-fpm to work.


module phpfpm 1.1;

require {
        type snmpd_var_lib_t;
        type httpd_sys_content_t;
        type port_t;
        type initrc_t;
        class tcp_socket name_bind;
        class file { read write open ioctl };
        class dir { read write open ioctl };
}

#============= initrc_t ==============
allow initrc_t port_t:tcp_socket name_bind;
allow initrc_t snmpd_var_lib_t:file { read write open };
allow initrc_t httpd_sys_content_t:file { read write open ioctl };
allow initrc_t httpd_sys_content_t:dir { read write open ioctl };
Comment 4 Matthew Thode ( prometheanfire ) archtester Gentoo Infrastructure gentoo-dev Security 2011-08-21 06:31:24 UTC
Needed a bit more :|

module phpfpm 1.0;

require {
        type snmpd_var_lib_t;
        type httpd_sys_content_t;
        type port_t;
        type initrc_t;
        class tcp_socket name_bind;
        class file { read write open ioctl create};
        class dir { read write open ioctl add_name create remove_name };
}

#============= initrc_t ==============
allow initrc_t port_t:tcp_socket name_bind;
allow initrc_t snmpd_var_lib_t:file { read write open };
allow initrc_t httpd_sys_content_t:file { read write open ioctl create };
allow initrc_t httpd_sys_content_t:dir { read write open ioctl add_name create remove_name };
Comment 5 Matthew Thode ( prometheanfire ) archtester Gentoo Infrastructure gentoo-dev Security 2011-08-21 06:44:45 UTC
Created attachment 284091 [details]
phpfpm.te

There are probably more perms it needs, dunno yet.
Comment 6 Sven Vermeulen (RETIRED) gentoo-dev 2011-08-23 09:57:22 UTC
When using a strict policy, each daemon launched should be within its own domain.

Please see http://www.gentoo.org/proj/en/hardened/selinux-development.xml#doc_chap4 and http://www.gentoo.org/proj/en/hardened/selinux/selinux-handbook.xml?part=2&chap=5 for some help on creating your own new module (in this case, for phpfpm).
Comment 7 Matthew Thode ( prometheanfire ) archtester Gentoo Infrastructure gentoo-dev Security 2011-08-25 22:33:21 UTC
Created attachment 284669 [details]
should be good for upstream

Note the end of the file, I don't know why it asks for it.  Here is the ldd if you can figure it out swift.

ldd /usr/lib64/php5.3/bin/php-fpm
	linux-vdso.so.1 =>  (0x00006cbcc3937000)
	libc-client.so.1 => /usr/lib64/libc-client.so.1 (0x00006cbcc3406000)
	libz.so.1 => /lib64/libz.so.1 (0x00006cbcc31ed000)
	libdl.so.2 => /lib64/libdl.so.2 (0x00006cbcc2fe9000)
	libaspell.so.15 => /usr/lib64/libaspell.so.15 (0x00006cbcc2d1a000)
	libpq.so.5 => /usr/lib64/postgresql-9.0/lib64/libpq.so.5 (0x00006cbcc2aec000)
	libmcrypt.so.4 => /usr/lib64/libmcrypt.so.4 (0x00006cbcc28b5000)
	libonig.so.2 => /usr/lib64/libonig.so.2 (0x00006cbcc2648000)
	libt1.so.5 => /usr/lib64/libt1.so.5 (0x00006cbcc23e6000)
	libm.so.6 => /lib64/libm.so.6 (0x00006cbcc2165000)
	libfreetype.so.6 => /usr/lib64/libfreetype.so.6 (0x00006cbcc1ebc000)
	libXpm.so.4 => /usr/lib64/libXpm.so.4 (0x00006cbcc1ca9000)
	libpng14.so.14 => /usr/lib64/libpng14.so.14 (0x00006cbcc1a7e000)
	libjpeg.so.8 => /usr/lib64/libjpeg.so.8 (0x00006cbcc1840000)
	libdb-4.8.so => /usr/lib64/libdb-4.8.so (0x00006cbcc14b2000)
	libpthread.so.0 => /lib64/libpthread.so.0 (0x00006cbcc1295000)
	libgdbm.so.3 => /usr/lib64/libgdbm.so.3 (0x00006cbcc108e000)
	libcurl.so.4 => /usr/lib64/libcurl.so.4 (0x00006cbcc0e2e000)
	libbz2.so.1 => /lib64/libbz2.so.1 (0x00006cbcc0c1d000)
	libpcre.so.0 => /lib64/libpcre.so.0 (0x00006cbcc09e0000)
	librt.so.1 => /lib64/librt.so.1 (0x00006cbcc07d7000)
	libssl.so.1.0.0 => /usr/lib64/libssl.so.1.0.0 (0x00006cbcc056f000)
	libcrypto.so.1.0.0 => /usr/lib64/libcrypto.so.1.0.0 (0x00006cbcc0195000)
	libldap-2.4.so.2 => /usr/lib64/libldap-2.4.so.2 (0x00006cbcbff4c000)
	liblber-2.4.so.2 => /usr/lib64/liblber-2.4.so.2 (0x00006cbcbfd3c000)
	libresolv.so.2 => /lib64/libresolv.so.2 (0x00006cbcbfb25000)
	libnetsnmp.so.15 => /usr/lib64/libnetsnmp.so.15 (0x00006cbcbf84b000)
	libxml2.so.2 => /usr/lib64/libxml2.so.2 (0x00006cbcbf4de000)
	libc.so.6 => /lib64/libc.so.6 (0x00006cbcbf177000)
	libpam.so.0 => /lib64/libpam.so.0 (0x00006cbcbef68000)
	/lib64/ld-linux-x86-64.so.2 (0x00006cbcc371b000)
	libstdc++.so.6 => /usr/lib/gcc/x86_64-pc-linux-gnu/4.4.5/libstdc++.so.6 (0x00006cbcbec37000)
	libkrb5.so.3 => /usr/lib64/libkrb5.so.3 (0x00006cbcbe95b000)
	libcom_err.so.2 => /lib64/libcom_err.so.2 (0x00006cbcbe757000)
	libgssapi_krb5.so.2 => /usr/lib64/libgssapi_krb5.so.2 (0x00006cbcbe515000)
	libldap_r-2.4.so.2 => /usr/lib64/libldap_r-2.4.so.2 (0x00006cbcbe2c2000)
	libX11.so.6 => /usr/lib64/libX11.so.6 (0x00006cbcbdf6f000)
	libsasl2.so.2 => /usr/lib64/libsasl2.so.2 (0x00006cbcbdd54000)
	libcrypt.so.1 => /lib64/libcrypt.so.1 (0x00006cbcbdb1c000)
	libk5crypto.so.3 => /usr/lib64/libk5crypto.so.3 (0x00006cbcbd8f0000)
	libkeyutils.so.1 => /lib64/libkeyutils.so.1 (0x00006cbcbd6ed000)
	libgnutls.so.26 => /usr/lib64/libgnutls.so.26 (0x00006cbcbd433000)
	libtasn1.so.3 => /usr/lib64/libtasn1.so.3 (0x00006cbcbd221000)
	libgcrypt.so.11 => /usr/lib64/libgcrypt.so.11 (0x00006cbcbcf9d000)
	libgpg-error.so.0 => /usr/lib64/libgpg-error.so.0 (0x00006cbcbcd98000)
	libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00006cbcbcb81000)
	libkrb5support.so.0 => /usr/lib64/libkrb5support.so.0 (0x00006cbcbc977000)
	libxcb.so.1 => /usr/lib64/libxcb.so.1 (0x00006cbcbc753000)
	libXau.so.6 => /usr/lib64/libXau.so.6 (0x00006cbcbc54f000)
	libXdmcp.so.6 => /usr/lib64/libXdmcp.so.6 (0x00006cbcbc349000)
Comment 8 Matthew Thode ( prometheanfire ) archtester Gentoo Infrastructure gentoo-dev Security 2011-08-25 22:36:37 UTC
Created attachment 284673 [details]
file context

no need for interface context (yet)

I also think I need to allow access to apache_manage_all_user_content.  I don't use apache_home_dirs, so I don't know.
Comment 9 Matthew Thode ( prometheanfire ) archtester Gentoo Infrastructure gentoo-dev Security 2011-08-25 23:18:05 UTC
Since I need read access to etc_t because of nsswitch, do you think I should just make the files in /etc/php/fpm-php*/ * etc_t and get rid of phpfpm_etc_t?
Comment 10 Sven Vermeulen (RETIRED) gentoo-dev 2011-08-28 20:27:39 UTC
Generally, I would say "no". Using a separate type for your etc files is recommended. You might need to provide read access to other domains later (or even manage access for who-knows-what-management-tool) and you don't want this to etc_t.

Other questions I have from the first looks:
- can't phpfpm run in the httpd_t domain (from apache module)? Do you know of a reason not to?
- why does phpfpm_t need manage rights on httpd_sys_content_t? Manage = read/write + even more
- Are setuid/setgid necessary?
Comment 11 Matthew Thode ( prometheanfire ) archtester Gentoo Infrastructure gentoo-dev Security 2011-08-28 21:56:56 UTC
Other questions I have from the first looks:
- can't phpfpm run in the httpd_t domain (from apache module)? Do you know of a reason not to?
Don't give a domain that already has too many permissions even more.  Plus it needs to work with more then apache.

- why does phpfpm_t need manage rights on httpd_sys_content_t? Manage = read/write + even more
The reason I don't use a rw only option is because that interface does not exist.

- Are setuid/setgid necessary?
It changes owner to the user/group you tell it to (nginx for me)
Comment 12 Sven Vermeulen (RETIRED) gentoo-dev 2011-09-02 19:54:12 UTC
#web reading
apache_manage_sys_content(phpfpm_t)
#apache_manage_sys_content(initrc_t)
apache_read_sys_content(phpfpm_t)
#apache_read_sys_content(initrc_t)

This is counterintuitive. Either you need read access, or you need manage access. Again, I don't think you need manage access. If php-fpm needs write access, it should be handled through the file context of whatever application it needs write access to (cfr. the squirrelmail interfaces/types like httpd_squirrelmail_t).
Comment 13 Sven Vermeulen (RETIRED) gentoo-dev 2011-09-02 19:56:24 UTC
#create sockets for clients to connect to
allow phpfpm_t self:netlink_route_socket { write getattr read bind create nlmsg_read };

Any particular reason why this is necessary? netlink_route_socket is to address/manage the routing tables (amongst other network related changes) within the Linux kernel...
Comment 14 Matthew Thode ( prometheanfire ) archtester Gentoo Infrastructure gentoo-dev Security 2011-09-02 22:02:38 UTC
I thought I took the read out, and for the socket, I'll test without it.
Comment 15 Matthew Thode ( prometheanfire ) archtester Gentoo Infrastructure gentoo-dev Security 2011-09-07 20:15:11 UTC
Created attachment 285813 [details]
phpfpm.te

cleanup, still need to sort out what selinux as a whole is going to do for web servers in gentoo.
Comment 16 Sven Vermeulen (RETIRED) gentoo-dev 2011-12-31 12:50:41 UTC
Matt,

The phpfpm_etc_t might not be necessary. Unless it contains private information, it can remain as the (generic) etc_t since phpfpm_t already has files_read_etc_files privileges.

Your /usr line here might not always work:
/usr/lib(64)?/php.*/bin/php-fpm

SELinux tries to hit file context matches as closely as possible. When there is no direct match, it looks for the context match with the "furthest" glob expression. Since your first match here is the (64)? one, even a simple "/usr/lib/(.*)?" will have precedence on yours. My suggestion is to split it for now (but in the near future we'll use the file_contexts.subs file so that every /usr/lib/ is also seen as /usr/lib64/).

What is the php.* match for?

In the .te file, you have
  logging_log_filetrans(phpfpm_t, phpfpm_log_t, { file dir })
but in your file contexts I only see the need for a file, not a dir.

You probably want to add dev_read_urand as well. You'll notice it is already on your systems - that's thanks to the global_ssp boolean. But that one is only for Hardened systems, others will need dev_read_urand explicitly too.

I also think you need to create a .if file that offers at least a _admin function (the _admin is one we don't use in gentoo yet, but it is used for role-based access controls when additional roles are created). We'll need it in order to push it upstream.
Comment 17 Matthew Thode ( prometheanfire ) archtester Gentoo Infrastructure gentoo-dev Security 2012-03-27 19:50:35 UTC
got rid of phpfpm_etc_t

The lib thing is fixed now (so you said)

the php.* match is to match against multiple php versions

removed the dir

added udrand

I don't understand the interfaces, so I'll have to work with you on that.

As far as other testing goes, I'm gonna convert my system to use sockets instead of tcp/udp ports.  This will likely necitate more in the policy but we'll get to that later.
Comment 18 Sven Vermeulen (RETIRED) gentoo-dev 2012-06-24 07:31:37 UTC
Okay, I've added the module into our tree:

http://git.overlays.gentoo.org/gitweb/?p=proj/hardened-refpolicy.git;a=blob_plain;f=policy/modules/contrib/phpfpm.if;hb=HEAD

http://git.overlays.gentoo.org/gitweb/?p=proj/hardened-refpolicy.git;a=blob_plain;f=policy/modules/contrib/phpfpm.fc;hb=HEAD

http://git.overlays.gentoo.org/gitweb/?p=proj/hardened-refpolicy.git;a=blob_plain;f=policy/modules/contrib/phpfpm.te;hb=HEAD

I added one interface (phpfpm_admin) which you can assign to your administrative domain (like phpfpm_admin(sysadm_t)) to allow this user to manage the phpfpm environment (manage log files, pid files, tmp files and interact with the process through signals and such).
Comment 19 Matthew Thode ( prometheanfire ) archtester Gentoo Infrastructure gentoo-dev Security 2012-08-20 22:03:14 UTC
solved, we have sec-policy/selinux-phpfpm in tree now.