Well, I don't think it works in 2.6.32.60 and 3.2.44 as it used to in 2.6.27.x with GRKERNSEC_EXECVE. Of course it's not grsecurity fault (though I did not bother to check it on vanilla kernel yet), but it may be worthwhile to revisit GRKERNSEC_EXECVE usefulness.
Check this out (tested on 3.2.44 with grsecurity-2.9.1-3.2.44-201304262227.patch and also confirmed on 2.6.32.60 with a pretty recent grsec patch):
- Code: Select all
root@myhost:~# su - -s/bin/bash testuser
testuser@myhost:~$
testuser@myhost:~$ ulimit -u 1
testuser@myhost:~$ ls
-su: fork: retry: Resource temporarily unavailable
-su: fork: retry: Resource temporarily unavailable
-su: fork: retry: Resource temporarily unavailable
-su: fork: retry: Resource temporarily unavailable
-su: fork: Resource temporarily unavailable
testuser@myhost:~$
So far so good. So in another screen window on root account I do the same as above. The result is obviously identical. I leave the two su sessions open and I open a third screen window with root shell. I do:
- Code: Select all
root@myhost:~# ps uxaw|egrep '^testuser'
testuser 15981 0.0 0.0 4448 1508 pts/10 S 21:10 0:00 su - -s/bin/bash testuser
testuser 15982 0.0 0.0 3068 1412 pts/10 S+ 21:10 0:00 -su
testuser 16408 0.0 0.0 4452 1512 pts/9 S 21:10 0:00 su - -s/bin/bash testuser
testuser 16409 0.0 0.0 3068 1408 pts/9 S+ 21:10 0:00 -su
The processes are there, no cheating. I go back to one of my testuser's shells and I type in:
- Code: Select all
szjtest@myhost:~$ exec ls -ld .
drwxr-s--- 10 testuser testuser 4096 Mar 7 22:38 .
root@myhost:~#
The su session is over, I get back the root shell. The point is that with GRKERNSEC_EXECVE working the way I always relied on it the 'exec ls -ld' would not have been executed since the rlimits were checked in the execve call. That is how it did the great job for me in suexec under 2.6.27.60 - my improved suexec after changing the gid/uid set rlimits based on the environment variables passed. Then it called execv() to run the requested CGI script. If the new process violated the process count limit, the execv() would fail. In 3.2.44 users can proliferate as many CGI scripts as they like and the only limitation is that they will not be able to fork when above the limit (at least there the process limit is checked properly). It was simply not possible in 2.6.27.x with GRKERNSEC_EXECVE.
[UPDATE]
I found a forsaken 2.6.27.something with GRKERNSEC_EXECVE and confirmed, that it worked properly. You don't even need to launch 2 concurrent sessions as su seems to use up two processes for the user (as indicated in the ps output above).
- Code: Select all
verylamehost:~# su - -s/bin/bash nobody
No directory, logging in with HOME=/
nobody@verylamehost:/$ ulimit -u 1
nobody@verylamehost:/$ ls
-su: fork: Resource temporarily unavailable
nobody@verylamehost:/$ exec ls
-su: /bin/ls: Resource temporarily unavailable
-su: /bin/ls: Success [yeah, you wish!]
nobody@verylamehost:/$ [still nobody]
Since we noticed that su uses up two processes, we can make another test to be 100% sure there is no flaws in our thinking:
- Code: Select all
verylamehost:~# su - -s/bin/bash nobody
No directory, logging in with HOME=/
nobody@verylamehost:/$ ulimit -u 2 [higher limit this time]
nobody@verylamehost:/$ ls
-su: fork: Resource temporarily unavailable
nobody@verylamehost:/$ exec ls [ should work since we'll stay in the 2 process limit ]
bin boot dev etc home lib lost+found mnt opt proc root sbin srv sys tmp usr var
verylamehost:~# [ nobody's shell is gone, we're back to root's shell ]