All of lore.kernel.org
 help / color / mirror / Atom feed
* [kernel-hardening] rlimit_nproc check
@ 2011-06-09 14:17 Vasiliy Kulikov
  2011-06-12  2:28 ` Solar Designer
  0 siblings, 1 reply; 5+ messages in thread
From: Vasiliy Kulikov @ 2011-06-09 14:17 UTC (permalink / raw)
  To: kernel-hardening

[-- Attachment #1: Type: text/plain, Size: 444 bytes --]

Solar, all -

I found 8-years old patch that enables RLIMIT_NPROC check at setuid (and
similar) calls:

http://lkml.org/lkml/2003/7/13/226

So, checking it on execve() is a bit redundant.  But it means that
setuid() may fail if it follows setrlimit() call and the target user
has already reached the limit (asserted on the test C program).  If the
limit is defined in pam_limit, the attack becomes real.


Thanks,

-- 
Vasiliy

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [kernel-hardening] rlimit_nproc check
  2011-06-09 14:17 [kernel-hardening] rlimit_nproc check Vasiliy Kulikov
@ 2011-06-12  2:28 ` Solar Designer
  2011-06-12 13:12   ` Vasiliy Kulikov
  2011-06-19 13:34   ` Vasiliy Kulikov
  0 siblings, 2 replies; 5+ messages in thread
From: Solar Designer @ 2011-06-12  2:28 UTC (permalink / raw)
  To: kernel-hardening

Vasiliy -

On Thu, Jun 09, 2011 at 06:17:45PM +0400, Vasiliy Kulikov wrote:
> I found 8-years old patch that enables RLIMIT_NPROC check at setuid (and
> similar) calls:
> 
> http://lkml.org/lkml/2003/7/13/226
> 
> So, checking it on execve() is a bit redundant.  But it means that
> setuid() may fail if it follows setrlimit() call and the target user
> has already reached the limit (asserted on the test C program).  If the
> limit is defined in pam_limit, the attack becomes real.

Right.  Dealing with setuid() failing to drop privs yet returning, which
many apps don't expect, is definitely something we (you) need to do
under this project.  In Linux 2.4.x-ow, I simply do:

--- linux-2.4.37.9.orig/kernel/sys.c	2010-02-01 21:04:46 +0000
+++ linux-2.4.37.9/kernel/sys.c	2010-02-18 14:04:42 +0000
@@ -514,8 +514,10 @@ static int set_user(uid_t new_ruid, int 
 	struct user_struct *new_user;
 
 	new_user = alloc_uid(new_ruid);
-	if (!new_user)
+	if (!new_user) {
+		force_sig(SIGSEGV, current);
 		return -EAGAIN;
+	}
 	switch_uid(new_user);
 
 	if(dumpclear)

As an option, you could propose to revert that 8-year old change and
introduce the check on execve().  Unrealistic?

The requirements are:

1. setuid(2) must not fail and return, when it was invoked with
"appropriate privileges".  If it fails, it must not return.

This suggests that it should not fail very often, so maybe the
RLIMIT_NPROC check does not belong there.

2. The setuid-execve sequence should not successfully start the new
program when that would exceed RLIMIT_NPROC for the target UID.

Oh, by the way, here's what I found:

Subject: [PATCH] sched: Don't allow setuid to succeed if the user does not have rt bandwidth
http://lists.openwall.net/linux-kernel/2009/02/27/177

Thanks,

Alexander

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [kernel-hardening] rlimit_nproc check
  2011-06-12  2:28 ` Solar Designer
@ 2011-06-12 13:12   ` Vasiliy Kulikov
  2011-06-19 13:34   ` Vasiliy Kulikov
  1 sibling, 0 replies; 5+ messages in thread
From: Vasiliy Kulikov @ 2011-06-12 13:12 UTC (permalink / raw)
  To: kernel-hardening

Solar,

On Sun, Jun 12, 2011 at 06:28 +0400, Solar Designer wrote:
> As an option, you could propose to revert that 8-year old change and
> introduce the check on execve().  Unrealistic?

I've started a separate thread on LKML for it, we'll see ;)

> Oh, by the way, here's what I found:
> 
> Subject: [PATCH] sched: Don't allow setuid to succeed if the user does not have rt bandwidth
> http://lists.openwall.net/linux-kernel/2009/02/27/177

Yeah, but it was removed in 7c9414385ebfdd87cc542d4e7e3bb0dbb2d3ce25 as
a "2.6.34 scheduled cleanup".


Thanks,

-- 
Vasiliy

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [kernel-hardening] rlimit_nproc check
  2011-06-12  2:28 ` Solar Designer
  2011-06-12 13:12   ` Vasiliy Kulikov
@ 2011-06-19 13:34   ` Vasiliy Kulikov
  2011-06-23 17:11     ` Vasiliy Kulikov
  1 sibling, 1 reply; 5+ messages in thread
From: Vasiliy Kulikov @ 2011-06-19 13:34 UTC (permalink / raw)
  To: kernel-hardening

On Sun, Jun 12, 2011 at 06:28 +0400, Solar Designer wrote:
> Right.  Dealing with setuid() failing to drop privs yet returning, which
> many apps don't expect, is definitely something we (you) need to do
> under this project.  In Linux 2.4.x-ow, I simply do:
> 
> --- linux-2.4.37.9.orig/kernel/sys.c	2010-02-01 21:04:46 +0000
> +++ linux-2.4.37.9/kernel/sys.c	2010-02-18 14:04:42 +0000
> @@ -514,8 +514,10 @@ static int set_user(uid_t new_ruid, int 
>  	struct user_struct *new_user;
>  
>  	new_user = alloc_uid(new_ruid);
> -	if (!new_user)
> +	if (!new_user) {
> +		force_sig(SIGSEGV, current);
>  		return -EAGAIN;
> +	}
>  	switch_uid(new_user);
>  
>  	if(dumpclear)
> 
> As an option, you could propose to revert that 8-year old change and
> introduce the check on execve().  Unrealistic?

I have slightly another idea.  Introduce mechanism (e.g. sysctl
variable) to make all capabilities dropping function cause SIGSEGV if
actual dropping process fails for any of several reasons.

The initial list should look like this:

    set*{u,g}id
    {set,init}groups
    unshare
    prctl(PR_CAPBSET_DROP, ...)
    prctl(PR_SET_SECCOMP, ...)
    capset

But any such list looks a bit not complete because there are many
different functions that might drop some capabilities in some
situations, like close(), *chdir(), rlimit(), nice(), fcntl(), ioctl(),
chroot(), which are, well, might fail in very common situations without
any actual secuity risk.

So, IMO this solution might not be enough consistent for upstream
inclusion.


Thanks,

-- 
Vasiliy

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [kernel-hardening] rlimit_nproc check
  2011-06-19 13:34   ` Vasiliy Kulikov
@ 2011-06-23 17:11     ` Vasiliy Kulikov
  0 siblings, 0 replies; 5+ messages in thread
From: Vasiliy Kulikov @ 2011-06-23 17:11 UTC (permalink / raw)
  To: kernel-hardening

On Sun, Jun 19, 2011 at 17:34 +0400, Vasiliy Kulikov wrote:
> I have slightly another idea.  Introduce mechanism (e.g. sysctl
> variable) to make all capabilities dropping function cause SIGSEGV if
> actual dropping process fails for any of several reasons.
> 
> The initial list should look like this:
> 
>     set*{u,g}id
>     {set,init}groups
>     unshare
>     prctl(PR_CAPBSET_DROP, ...)
>     prctl(PR_SET_SECCOMP, ...)
>     capset
> [...]

The scheme actually is harmfull in some situations.  E.g. nfs daemon
with one process architecture switches to another user via setfsuid()
or similar, handles the request, switches back to the root.  If
setfsuid() fails (rlimit or some other reason) nfsd is DoS'ed by the
signal.  Any other daemon with similar architecture will be DoS'ed too.

So, the list of SIGKILL'able syscalls should be selected _very_
carefully (I don't know whether the safe list is nonempty).


Thanks,

-- 
Vasiliy Kulikov
http://www.openwall.com - bringing security into open computing environments

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2011-06-23 17:11 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-06-09 14:17 [kernel-hardening] rlimit_nproc check Vasiliy Kulikov
2011-06-12  2:28 ` Solar Designer
2011-06-12 13:12   ` Vasiliy Kulikov
2011-06-19 13:34   ` Vasiliy Kulikov
2011-06-23 17:11     ` Vasiliy Kulikov

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.