Page 1 of 1

grsec RLIMIT_NPROC handling incompatible with apache+suexec

PostPosted: Thu May 29, 2014 6:37 am
by zImage
This is discussed elsewhere: viewtopic.php?f=3&t=3446&p=14021#p14021

But I'm posting it as a new topic, because it actually breaks apache+suexec+limits in a major way. I'm even surprised this isn't reported already. Copy paste what's going on from the other thread:

After pathing with latest grsecurity the program (apache) flow is as follows:
Code: Select all
step syscall     uid     comment
-1   fork()      root    apache master process spawns a connection handling child
 0   setuid()    apache  privileges revoked (child has open fds etc.)
 1   fork()      apache  apache child prepares to serve a cgi by spawning another child (to be replaced later w/ execve())
 2   setrlimit() apache  the new apache child sets rlimit_nproc in accordance with httpd.conf for this user's vhost
 3   execve()    apache  the cgi child is replaced by the suexec binary (which is suid root)
 4   setuid()    root    suexec changes its uid in accordance with this user's vhost SuexecUserGroup directive
 5   execve()    user    actual cgi binary is called (e.g. php-cgi)

With default kernel behaviour we are getting failure at step 5, because PF_NPROC_EXCEEDED flag is raised at step 4.

With latest grsecurity we get failure at step 3, probably because PF_NPROC_EXCEEDED flag is raised at step 2. This is problematic, because at step 3 we are still not running as the final web user and limit is not enforced against this web user's process count.

Here's a strace excerpt:
Code: Select all
[pid  7523] clone(Process 7546 attached
[pid  7546] chdir("/home/user/www/") = 0
[pid  7546] setrlimit(RLIMIT_CPU, {rlim_cur=60, rlim_max=60}) = 0
[pid  7546] setrlimit(RLIMIT_NPROC, {rlim_cur=20, rlim_max=20}) = 0
[pid  7546] setrlimit(RLIMIT_AS, {rlim_cur=128000000, rlim_max=128000000}) = 0
[pid  7546] execve("suexec", ["suexec", "1110", "2099", "sleep.php"], [/* 26 vars */]) = -1 EAGAIN (Resource temporarily unavailable)

Our current solution is to just revert the patch.