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

login
register
mail settings
Submitter Brad Figg
Date April 22, 2011, 8:47 p.m.
Message ID <1303505237-12625-1-git-send-email-brad.figg@canonical.com>
Download mbox | patch
Permalink /patch/92584/
State New
Headers show

Comments

Brad Figg - April 22, 2011, 8:47 p.m.
From: Eric Dumazet <eric.dumazet@gmail.com>

CVE-2010-4249

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

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>
---
 net/unix/garbage.c |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)
Tim Gardner - April 23, 2011, 12:52 p.m.
On 04/22/2011 02:47 PM, Brad Figg wrote:
> From: Eric Dumazet<eric.dumazet@gmail.com>
>
> CVE-2010-4249
>
> BugLink: http://bugs.launchpad.net/bugs/769182
>
> 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>
> ---
>   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 040f952..26d22aa 100644
> --- a/net/unix/garbage.c
> +++ b/net/unix/garbage.c
> @@ -168,9 +168,16 @@ static void maybe_unmark_and_push(struct sock *x)
>
>
>   static int gc_in_progress = 0;
> +#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 (atomic_read(&unix_tot_inflight)>  UNIX_INFLIGHT_TRIGGER_GC&&  !gc_in_progress)
> +		unix_gc();
>   	wait_event(unix_gc_wait, gc_in_progress == 0);
>   }
>

Looks reasonable. Was this a clean cherry-pick, or a backport ?

Acked-by: Tim Gardner <tim.gardner@canonical.com>
Brad Figg - April 23, 2011, 3:02 p.m.
On 04/23/2011 05:52 AM, Tim Gardner wrote:
> On 04/22/2011 02:47 PM, Brad Figg wrote:
>> From: Eric Dumazet<eric.dumazet@gmail.com>
>>
>> CVE-2010-4249
>>
>> BugLink: http://bugs.launchpad.net/bugs/769182
>>
>> 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>
>> ---
>> 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 040f952..26d22aa 100644
>> --- a/net/unix/garbage.c
>> +++ b/net/unix/garbage.c
>> @@ -168,9 +168,16 @@ static void maybe_unmark_and_push(struct sock *x)
>>
>>
>> static int gc_in_progress = 0;
>> +#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 (atomic_read(&unix_tot_inflight)> UNIX_INFLIGHT_TRIGGER_GC&& !gc_in_progress)
>> + unix_gc();
>> wait_event(unix_gc_wait, gc_in_progress == 0);
>> }
>>
>
> Looks reasonable. Was this a clean cherry-pick, or a backport ?
>
> Acked-by: Tim Gardner <tim.gardner@canonical.com>
>

It's a clean cherry-pick.
Brad Figg - April 25, 2011, 4:22 p.m.
On 04/22/2011 01:47 PM, Brad Figg wrote:
> From: Eric Dumazet<eric.dumazet@gmail.com>
>
> CVE-2010-4249
>
> BugLink: http://bugs.launchpad.net/bugs/769182
>
> 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>
> ---
>   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 040f952..26d22aa 100644
> --- a/net/unix/garbage.c
> +++ b/net/unix/garbage.c
> @@ -168,9 +168,16 @@ static void maybe_unmark_and_push(struct sock *x)
>
>
>   static int gc_in_progress = 0;
> +#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 (atomic_read(&unix_tot_inflight)>  UNIX_INFLIGHT_TRIGGER_GC&&  !gc_in_progress)
> +		unix_gc();
>   	wait_event(unix_gc_wait, gc_in_progress == 0);
>   }
>

applied
Tim Gardner - April 25, 2011, 4:29 p.m.
On 04/23/2011 09:02 AM, Brad Figg wrote:
> On 04/23/2011 05:52 AM, Tim Gardner wrote:
>> On 04/22/2011 02:47 PM, Brad Figg wrote:
>>> From: Eric Dumazet<eric.dumazet@gmail.com>
>>>
>>> CVE-2010-4249
>>>
>>> BugLink: http://bugs.launchpad.net/bugs/769182
>>>
>>> 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>
>>> ---
>>> 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 040f952..26d22aa 100644
>>> --- a/net/unix/garbage.c
>>> +++ b/net/unix/garbage.c
>>> @@ -168,9 +168,16 @@ static void maybe_unmark_and_push(struct sock *x)
>>>
>>>
>>> static int gc_in_progress = 0;
>>> +#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 (atomic_read(&unix_tot_inflight)> UNIX_INFLIGHT_TRIGGER_GC&&
>>> !gc_in_progress)
>>> + unix_gc();
>>> wait_event(unix_gc_wait, gc_in_progress == 0);
>>> }
>>>
>>
>> Looks reasonable. Was this a clean cherry-pick, or a backport ?
>>
>> Acked-by: Tim Gardner <tim.gardner@canonical.com>
>>
>
> It's a clean cherry-pick.
>

I guess my point was that if the patch is a clean cherry-pick, then it 
ought to have the upstream SHA1 embedded in the commit log by using the 
'-x' option to 'git cherry-pick'. iF it is a backport, then note the 
upstream SHA1 from which the backport originated.

rtg

Patch

diff --git a/net/unix/garbage.c b/net/unix/garbage.c
index 040f952..26d22aa 100644
--- a/net/unix/garbage.c
+++ b/net/unix/garbage.c
@@ -168,9 +168,16 @@  static void maybe_unmark_and_push(struct sock *x)
 
 
 static int gc_in_progress = 0;
+#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 (atomic_read(&unix_tot_inflight) > UNIX_INFLIGHT_TRIGGER_GC && !gc_in_progress)
+		unix_gc();
 	wait_event(unix_gc_wait, gc_in_progress == 0);
 }