|From:||Vasiliy Kulikov <segooon-AT-gmail.com>|
|Subject:||RLIMIT_NPROC check in set_user()|
|Date:||Sun, 12 Jun 2011 17:09:54 +0400|
|Cc:||Linus Torvalds <torvalds-AT-linux-foundation.org>, Greg Kroah-Hartman <gregkh-AT-suse.de>, Andrew Morton <akpm-AT-linux-foundation.org>, "David S. Miller" <davem-AT-davemloft.net>, Jiri Slaby <jslaby-AT-suse.cz>, James Morris <jmorris-AT-namei.org>, Neil Brown <neilb-AT-suse.de>, kernel-hardening-AT-lists.openwall.com|
Hi, I'd want to start a discussion of RLIMIT_NPROC check in set_user(). 8 years ago set_user() was forced to check whether RLIMIT_NPROC limit is reached, and, if so, abort set_user(): http://lkml.org/lkml/2003/7/13/226  Before the patch setuid() and similar were not able to fail because of the reached limit. So, some daemons running as root, dropping root and switching uid/gid to some user were able to greatly exceed the limit of processes running as this user. The patch has solved this problem. But it also unexpectedly created new security threat. Many poorly written programs running as root (or owning CAP_SYS_ADMIN) don't expect setuid() failure and don't check its return code. If it fails, they still assume the uid has changed, but actually it has not, which leads to very sad consequences. In times of Linux 2.4 the initial problem (the lack of RLIMIT_NPROC check) was solved in -ow patches by introducing the check in execve(), not in setuid()/setuid() helpers as a process after dropping privileges usually does execve() call. While strictly speaking it is not a full fix (it doesn't limit the number of not-execve'd but setuid'ed processes) it works just fine for most of programs. Another possible workaround is not moving the check from setuid() to execve(), but sending SIGSEGV to the current process if setuid() failed . This should solve the problem of poor programs and looks like not breaking legitimate applications that handle setuid() failure as they usually just print error message to the logfile/stderr and exit. Also as it is a horribly rare case (setuid() failure), more complicated code path might be not tested very well. I want to repeat myself: I don't consider checking RLIMIT_NPROC in setuid() as a bug (a lack of syscalls return code checking is a real bug), but as a pouring oil on the flames of programs doing poorly written privilege dropping. I believe the situation may be improved by relatively small ABI changes that shouldn't be visible to normal programs. The first solution is reverting  and introducing similar check in execve(), just like in -ow patch for 2.4. The second solution is applying  and sending SIGSEGV in case of privileges dropping failure. I'd be happy to hear opinions about improving the fixes above or alternative fixes. Related references:  - http://lkml.org/lkml/2003/7/13/226  - https://lkml.org/lkml/2006/8/19/129 Thanks, -- Vasiliy
Copyright © 2011, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds