danwalsh


Dan Walsh's Blog

Got SELinux?


Previous Entry Add to Memories Share Next Entry
How can I allow a process to listing all processes on a system.
danwalsh
SELinux blocks lots of domains from listing all processes on the system. 

Lots of useful information can be optained from reading the process info on a machine, so we would like to block this by default.  But sometimes users/policy writers really need to allow their domains to be able to list the processes on a system.

Ole on the Fedora SELinux Users Mail list asked:

I have a problem with SELinux not allowing PHP to list other users' processes with the "ps" command.
If I disable SELinux with "setenforce 0" it works immediately.
Is it possible to allow PHP to do this without disabling SELinux completely?

Processes are listed by reading all of the contents of /proc.  SELinux linux labels everything in /proc based on the label of the process.

ps -eZ | grep sshd | head -1
system_u:system_r:sshd_t:s0-s0:c0.c1023 853 ?  00:00:00 sshd

ls -lZ /proc/853 | head -1
dr-xr-xr-x. root root system_u:system_r:sshd_t:s0-s0:c0.c1023 attr


If you want a confined process to run ps, it needs to list /proc/PID, it needs to read certain files in this directory, needs to read symbolic links in this directory and needs to getattr on the process.   When writing policy we have added a macro for this access.

define(`ps_process_pattern',`
    allow $1 $2:dir list_dir_perms;
    allow $1 $2:file read_file_perms;
    allow $1 $2:lnk_file read_lnk_file_perms;
    allow $1 $2:process getattr;
')


If we wanted to allow one process type (myuser_t) to read another process /proc data on sshd (sshd_t), we would need to write a line like:

ps_process_pattern(myuser_t, sshd_t)

What if I want to allow a type to list all processes types?

In SELinux policy language we use attributes are used to group multiple types together. 
SELinux calls processes "domains".  When we write policy we always give process types the domain attribute.

So if you wanted to allow a process myuser_t to  list all the processes on a system, you would write a rule like.

ps_process_pattern(myuser_t, domain)

Dominic Grift answered Ole question by suggesting he install a local policy module that looked like:
policy_module(mytest, 1.0.0)
gen_require(` 
  type httpd_t; 
  attribute domain; 
')
ps_process_pattern(httpd_t, domain)

This works great.  Note that the apache daemon runs all php scripts within its process space, to they run as httpd_t.

Another solution would be to use an interface that we have defined in policy to allow this, domain_read_all_domains_state.  

The /usr/share/selinux/devel/include/kernel/domain.if interface file defines several interfaces that can be used to interact with all domains.  An alternative policy module could have been written:

policy_module(mytest, 1.0.0)
gen_require(` 
  type httpd_t; 
')
domain_read_all_domains_state(httpd_t)


Re: PHP to list all processes with ps -aux

Ryan Graff

2012-05-16 04:07 am (UTC)

This is some hardcore stuff man!

I got it in there ok but it still doesn't want to allow me to list all processes with php. :P

I made the file with that text in it, make ran with no errors and the module installed fine too.

I'm still stuck where setenforce 0 lets me do it and 1 turns it right back off. :(

I also rebooted the whole thing just to make sure.

Thank you very much for your help Sir!

If you have any other insight that would be awesome! But I guess I have some other issue.


Re: PHP to list all processes with ps -aux

danwalsh

2012-05-16 05:02 am (UTC)

Send me your current avc's, dwalsh@redhat.com, when ps fails.

ausearch -m avc -ts recent

Re: PHP to list all processes with ps -aux

Ryan Graff

2012-05-16 05:51 pm (UTC)

Ok, there's a lot all from the same time stamp so I put it in a file for you here: http://resistdesign.com/files/temp/AVCs.txt

Re: PHP to list all processes with ps -aux

danwalsh

2012-05-17 08:46 pm (UTC)

This just means you are doing it with a separate process or a cgi process

#===========================================cut =========================================
policy_module(mytest, 1.0.0)
gen_require(`
type httpd_sys_script_t;
')
domain_read_all_domains_state(httpd_sys_script_t)
#========================================== cut =========================================

cat > mytest.te
^v
^d

# make -f /usr/share/selinux/devel/Makefile
# semodule -i mytest.pp

You are viewing danwalsh