Patchwork [1/6] af_unix: limit unix_tot_inflight CVE-2010-4249

login
register
mail settings
Submitter Paolo Pisati
Date July 4, 2011, 2:08 p.m.
Message ID <1309788494-2307-2-git-send-email-paolo.pisati@canonical.com>
Download mbox | patch
Permalink /patch/103102/
State New
Headers show

Comments

Paolo Pisati - July 4, 2011, 2:08 p.m.
From: Eric Dumazet <eric.dumazet@gmail.com>

CVE-2010-4249

BugLink: http://bugs.launchpad.net/bugs/769182

commit upstream 9915672d41273f5b77f1b3c29b391ffb7732b84b

Vegard Nossum found a unix socket OOM was possible, posting an exploit
program.

My analysis is we can eat all LOWMEM memory before unix_gc() being
called from unix_release_sock(). Moreover, the thread blocked in
unix_gc() can consume huge amount of time to perform cleanup because of
huge working set.

One way to handle this is to have a sensible limit on unix_tot_inflight,
tested from wait_for_unix_gc() and to force a call to unix_gc() if this
limit is hit.

This solves the OOM and also reduce overall latencies, and should not
slowdown normal workloads.

Reported-by: Vegard Nossum <vegard.nossum@gmail.com>
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Brad Figg <brad.figg@canonical.com>
Signed-off-by: Paolo Pisati <paolo.pisati@canonical.com>
---
 net/unix/garbage.c |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)
Stefan Bader - July 4, 2011, 2:48 p.m.
On 04.07.2011 16:08, paolo.pisati@canonical.com wrote:
> From: Eric Dumazet <eric.dumazet@gmail.com>
> 
> CVE-2010-4249
> 
> BugLink: http://bugs.launchpad.net/bugs/769182
> 
> commit upstream 9915672d41273f5b77f1b3c29b391ffb7732b84b
> 
> Vegard Nossum found a unix socket OOM was possible, posting an exploit
> program.
> 
> My analysis is we can eat all LOWMEM memory before unix_gc() being
> called from unix_release_sock(). Moreover, the thread blocked in
> unix_gc() can consume huge amount of time to perform cleanup because of
> huge working set.
> 
> One way to handle this is to have a sensible limit on unix_tot_inflight,
> tested from wait_for_unix_gc() and to force a call to unix_gc() if this
> limit is hit.
> 
> This solves the OOM and also reduce overall latencies, and should not
> slowdown normal workloads.
> 
> Reported-by: Vegard Nossum <vegard.nossum@gmail.com>
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
> Signed-off-by: David S. Miller <davem@davemloft.net>

Only adding this as there was another comment on another patch. Below this would
look like Brad did something before and you applied it. Or did you pick it up
from a later ubuntu branch and not from upstream?

> Signed-off-by: Brad Figg <brad.figg@canonical.com>
> Signed-off-by: Paolo Pisati <paolo.pisati@canonical.com>
> ---
>  net/unix/garbage.c |    7 +++++++
>  1 files changed, 7 insertions(+), 0 deletions(-)
> 
> diff --git a/net/unix/garbage.c b/net/unix/garbage.c
> index 07499a5..dc2cb61 100644
> --- a/net/unix/garbage.c
> +++ b/net/unix/garbage.c
> @@ -269,9 +269,16 @@ static void inc_inflight_move_tail(struct unix_sock *u)
>  }
>  
>  static bool gc_in_progress = false;
> +#define UNIX_INFLIGHT_TRIGGER_GC 16000
>  
>  void wait_for_unix_gc(void)
>  {
> +	/*
> +	 * If number of inflight sockets is insane,
> +	 * force a garbage collect right now.
> +	 */
> +	if (unix_tot_inflight > UNIX_INFLIGHT_TRIGGER_GC && !gc_in_progress)
> +		unix_gc();
>  	wait_event(unix_gc_wait, gc_in_progress == false);
>  }
>
Paolo Pisati - July 4, 2011, 2:54 p.m.
On 07/04/2011 04:48 PM, Stefan Bader wrote:

> 
> Only adding this as there was another comment on another patch. Below this would
> look like Brad did something before and you applied it. Or did you pick it up
> from a later ubuntu branch and not from upstream?

this came from lucid/master, that's where the Sign-off came from.

Patch

diff --git a/net/unix/garbage.c b/net/unix/garbage.c
index 07499a5..dc2cb61 100644
--- a/net/unix/garbage.c
+++ b/net/unix/garbage.c
@@ -269,9 +269,16 @@  static void inc_inflight_move_tail(struct unix_sock *u)
 }
 
 static bool gc_in_progress = false;
+#define UNIX_INFLIGHT_TRIGGER_GC 16000
 
 void wait_for_unix_gc(void)
 {
+	/*
+	 * If number of inflight sockets is insane,
+	 * force a garbage collect right now.
+	 */
+	if (unix_tot_inflight > UNIX_INFLIGHT_TRIGGER_GC && !gc_in_progress)
+		unix_gc();
 	wait_event(unix_gc_wait, gc_in_progress == false);
 }