[kernel/f13/master] CVE-2010-4249 unix socket local dos
Chuck Ebbert
cebbert at fedoraproject.org
Tue Dec 14 13:55:30 UTC 2010
commit 7a0a7db74d4ad42a5bdd9e2d1a2ab3708e0303e1
Author: Chuck Ebbert <cebbert at redhat.com>
Date: Tue Dec 14 08:54:54 2010 -0500
CVE-2010-4249 unix socket local dos
af_unix-limit-unix_tot_inflight.patch | 48 ++++++++++++++++++++++
kernel.spec | 7 +++
scm-lower-SCM-MAX-FD.patch | 70 +++++++++++++++++++++++++++++++++
3 files changed, 125 insertions(+), 0 deletions(-)
---
diff --git a/af_unix-limit-unix_tot_inflight.patch b/af_unix-limit-unix_tot_inflight.patch
new file mode 100644
index 0000000..0721a3d
--- /dev/null
+++ b/af_unix-limit-unix_tot_inflight.patch
@@ -0,0 +1,48 @@
+From: Eric Dumazet <eric.dumazet at gmail.com>
+Date: Wed, 24 Nov 2010 17:15:27 +0000 (-0800)
+Subject: af_unix: limit unix_tot_inflight
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fdavem%2Fnet-2.6.git;a=commitdiff_plain;h=9915672d41273f5b77f1b3c29b391ffb7732b84b
+
+af_unix: limit unix_tot_inflight
+
+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 at gmail.com>
+Signed-off-by: Eric Dumazet <eric.dumazet at gmail.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+
+diff --git a/net/unix/garbage.c b/net/unix/garbage.c
+index c8df6fd..40df93d 100644
+--- a/net/unix/garbage.c
++++ b/net/unix/garbage.c
+@@ -259,9 +259,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);
+ }
+
diff --git a/kernel.spec b/kernel.spec
index 8b60080..76b8c11 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -895,6 +895,9 @@ Patch13914: do_exit-make-sure-that-we-run-with-get_fs-user_ds.patch
Patch13915: perf_events-fix-perf_counter_mmap-hook-in-mprotect.patch
# CVE-2010-4162
Patch13916: bio-take-care-not-overflow-page-count-when-mapping-copying-user-data.patch
+# CVE-2010-4249
+Patch13917: af_unix-limit-unix_tot_inflight.patch
+Patch13918: scm-lower-SCM-MAX-FD.patch
%endif
@@ -1714,6 +1717,9 @@ ApplyPatch do_exit-make-sure-that-we-run-with-get_fs-user_ds.patch
ApplyPatch perf_events-fix-perf_counter_mmap-hook-in-mprotect.patch
# CVE-2010-4162
ApplyPatch bio-take-care-not-overflow-page-count-when-mapping-copying-user-data.patch
+# CVE-2010-4249
+ApplyPatch af_unix-limit-unix_tot_inflight.patch
+ApplyPatch scm-lower-SCM-MAX-FD.patch
# END OF PATCH APPLICATIONS
@@ -2338,6 +2344,7 @@ fi
%changelog
* Tue Dec 14 2010 Chuck Ebbert <cebbert at redhat.com>
- CVE-2010-4162 bio: integer overflow page count when mapping/copying user data
+- CVE-2010-4249 unix socket local dos
* Fri Dec 10 2010 Chuck Ebbert <cebbert at redhat.com>
- CVE-2010-2962: arbitrary kernel memory write via i915 GEM ioctl
diff --git a/scm-lower-SCM-MAX-FD.patch b/scm-lower-SCM-MAX-FD.patch
new file mode 100644
index 0000000..c5799b7
--- /dev/null
+++ b/scm-lower-SCM-MAX-FD.patch
@@ -0,0 +1,70 @@
+From: Eric Dumazet <eric.dumazet at gmail.com>
+Date: Tue, 23 Nov 2010 14:09:15 +0000 (+0000)
+Subject: scm: lower SCM_MAX_FD
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fdavem%2Fnet-next-2.6.git;a=commitdiff_plain;h=bba14de98753cb6599a2dae0e520714b2153522d
+
+scm: lower SCM_MAX_FD
+
+Lower SCM_MAX_FD from 255 to 253 so that allocations for scm_fp_list are
+halved. (commit f8d570a4 added two pointers in this structure)
+
+scm_fp_dup() should not copy whole structure (and trigger kmemcheck
+warnings), but only the used part. While we are at it, only allocate
+needed size.
+
+Signed-off-by: Eric Dumazet <eric.dumazet at gmail.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+
+diff --git a/include/net/scm.h b/include/net/scm.h
+index 3165650..745460f 100644
+--- a/include/net/scm.h
++++ b/include/net/scm.h
+@@ -10,11 +10,12 @@
+ /* Well, we should have at least one descriptor open
+ * to accept passed FDs 8)
+ */
+-#define SCM_MAX_FD 255
++#define SCM_MAX_FD 253
+
+ struct scm_fp_list {
+ struct list_head list;
+- int count;
++ short count;
++ short max;
+ struct file *fp[SCM_MAX_FD];
+ };
+
+diff --git a/net/core/scm.c b/net/core/scm.c
+index 413cab8..bbe4544 100644
+--- a/net/core/scm.c
++++ b/net/core/scm.c
+@@ -79,10 +79,11 @@ static int scm_fp_copy(struct cmsghdr *cmsg, struct scm_fp_list **fplp)
+ return -ENOMEM;
+ *fplp = fpl;
+ fpl->count = 0;
++ fpl->max = SCM_MAX_FD;
+ }
+ fpp = &fpl->fp[fpl->count];
+
+- if (fpl->count + num > SCM_MAX_FD)
++ if (fpl->count + num > fpl->max)
+ return -EINVAL;
+
+ /*
+@@ -331,11 +332,12 @@ struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl)
+ if (!fpl)
+ return NULL;
+
+- new_fpl = kmalloc(sizeof(*fpl), GFP_KERNEL);
++ new_fpl = kmemdup(fpl, offsetof(struct scm_fp_list, fp[fpl->count]),
++ GFP_KERNEL);
+ if (new_fpl) {
+- for (i=fpl->count-1; i>=0; i--)
++ for (i = 0; i < fpl->count; i++)
+ get_file(fpl->fp[i]);
+- memcpy(new_fpl, fpl, sizeof(*fpl));
++ new_fpl->max = new_fpl->count;
+ }
+ return new_fpl;
+ }
More information about the scm-commits
mailing list