[linux] 01/01: unix: correctly track in-flight fds in sending process user_struct
debian-kernel at lists.debian.org
debian-kernel at lists.debian.org
Sat Feb 27 09:48:37 UTC 2016
This is an automated email from the git hooks/post-receive script.
benh pushed a commit to branch wheezy-security
in repository linux.
commit 9dc8c4b7a47cea855b85d3836d1956890df1ec06
Author: Ben Hutchings <ben at decadent.org.uk>
Date: Tue Feb 23 02:57:21 2016 +0000
unix: correctly track in-flight fds in sending process user_struct
Fixes a regression caused by the pending fix for CVE-2013-4312.
---
debian/changelog | 2 +
debian/config/defines | 5 +
...flight-fds-in-sending-process-user_struct.patch | 148 +++++++++++++++++++++
debian/patches/series | 1 +
4 files changed, 156 insertions(+)
diff --git a/debian/changelog b/debian/changelog
index 2e6e5fb..d5f3469 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -20,6 +20,8 @@ linux (3.2.73-2+deb7u3) UNRELEASED; urgency=medium
(regression in 3.2.73-2+deb7u1)
* pipe: Fix buffer offset after partially failed read (CVE-2016-0774)
* ALSA: usb-audio: avoid freeing umidi object twice (CVE-2016-2384)
+ * unix: correctly track in-flight fds in sending process user_struct
+ (CVE-2016-2550)
[ Salvatore Bonaccorso ]
* unix: properly account for FDs passed over unix sockets (CVE-2013-4312)
diff --git a/debian/config/defines b/debian/config/defines
index 8081852..3db32ec 100644
--- a/debian/config/defines
+++ b/debian/config/defines
@@ -77,6 +77,11 @@ ignore-changes:
module:sound/pci/emu10k1/*
# Apparently not used from OOT
skb_copy_and_csum_datagram_iovec
+# Not used by OOT modules
+ __scm_destroy
+ __scm_send
+ scm_detach_fds
+ scm_fp_dup
[base]
arches:
diff --git a/debian/patches/bugfix/all/unix-correctly-track-in-flight-fds-in-sending-process-user_struct.patch b/debian/patches/bugfix/all/unix-correctly-track-in-flight-fds-in-sending-process-user_struct.patch
new file mode 100644
index 0000000..50bab43
--- /dev/null
+++ b/debian/patches/bugfix/all/unix-correctly-track-in-flight-fds-in-sending-process-user_struct.patch
@@ -0,0 +1,148 @@
+From: Hannes Frederic Sowa <hannes at stressinduktion.org>
+Date: Wed, 3 Feb 2016 02:11:03 +0100
+Subject: unix: correctly track in-flight fds in sending process user_struct
+
+commit 415e3d3e90ce9e18727e8843ae343eda5a58fad6 upstream.
+
+The commit referenced in the Fixes tag incorrectly accounted the number
+of in-flight fds over a unix domain socket to the original opener
+of the file-descriptor. This allows another process to arbitrary
+deplete the original file-openers resource limit for the maximum of
+open files. Instead the sending processes and its struct cred should
+be credited.
+
+To do so, we add a reference counted struct user_struct pointer to the
+scm_fp_list and use it to account for the number of inflight unix fds.
+
+Fixes: 712f4aad406bb1 ("unix: properly account for FDs passed over unix sockets")
+Reported-by: David Herrmann <dh.herrmann at gmail.com>
+Cc: David Herrmann <dh.herrmann at gmail.com>
+Cc: Willy Tarreau <w at 1wt.eu>
+Cc: Linus Torvalds <torvalds at linux-foundation.org>
+Suggested-by: Linus Torvalds <torvalds at linux-foundation.org>
+Signed-off-by: Hannes Frederic Sowa <hannes at stressinduktion.org>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+[bwh: Backported to 3.2: adjust context]
+Signed-off-by: Ben Hutchings <ben at decadent.org.uk>
+---
+ include/net/af_unix.h | 4 ++--
+ include/net/scm.h | 1 +
+ net/core/scm.c | 7 +++++++
+ net/unix/af_unix.c | 4 ++--
+ net/unix/garbage.c | 8 ++++----
+ 5 files changed, 16 insertions(+), 8 deletions(-)
+
+--- a/include/net/af_unix.h
++++ b/include/net/af_unix.h
+@@ -6,8 +6,8 @@
+ #include <linux/mutex.h>
+ #include <net/sock.h>
+
+-extern void unix_inflight(struct file *fp);
+-extern void unix_notinflight(struct file *fp);
++extern void unix_inflight(struct user_struct *user, struct file *fp);
++extern void unix_notinflight(struct user_struct *user, struct file *fp);
+ extern void unix_gc(void);
+ extern void wait_for_unix_gc(void);
+ extern struct sock *unix_get_socket(struct file *filp);
+--- a/include/net/scm.h
++++ b/include/net/scm.h
+@@ -16,6 +16,7 @@ struct scm_fp_list {
+ struct list_head list;
+ short count;
+ short max;
++ struct user_struct *user;
+ struct file *fp[SCM_MAX_FD];
+ };
+
+--- a/net/core/scm.c
++++ b/net/core/scm.c
+@@ -80,6 +80,7 @@ static int scm_fp_copy(struct cmsghdr *c
+ *fplp = fpl;
+ fpl->count = 0;
+ fpl->max = SCM_MAX_FD;
++ fpl->user = NULL;
+ }
+ fpp = &fpl->fp[fpl->count];
+
+@@ -100,6 +101,10 @@ static int scm_fp_copy(struct cmsghdr *c
+ *fpp++ = file;
+ fpl->count++;
+ }
++
++ if (!fpl->user)
++ fpl->user = get_uid(current_user());
++
+ return num;
+ }
+
+@@ -124,6 +129,7 @@ void __scm_destroy(struct scm_cookie *sc
+ list_del(&fpl->list);
+ for (i=fpl->count-1; i>=0; i--)
+ fput(fpl->fp[i]);
++ free_uid(fpl->user);
+ kfree(fpl);
+ }
+
+@@ -340,6 +346,7 @@ struct scm_fp_list *scm_fp_dup(struct sc
+ for (i = 0; i < fpl->count; i++)
+ get_file(fpl->fp[i]);
+ new_fpl->max = new_fpl->count;
++ new_fpl->user = get_uid(fpl->user);
+ }
+ return new_fpl;
+ }
+--- a/net/unix/af_unix.c
++++ b/net/unix/af_unix.c
+@@ -1454,7 +1454,7 @@ static void unix_detach_fds(struct scm_c
+ UNIXCB(skb).fp = NULL;
+
+ for (i = scm->fp->count-1; i >= 0; i--)
+- unix_notinflight(scm->fp->fp[i]);
++ unix_notinflight(scm->fp->user, scm->fp->fp[i]);
+ }
+
+ static void unix_destruct_scm(struct sk_buff *skb)
+@@ -1520,7 +1520,7 @@ static int unix_attach_fds(struct scm_co
+ return -ENOMEM;
+
+ for (i = scm->fp->count - 1; i >= 0; i--)
+- unix_inflight(scm->fp->fp[i]);
++ unix_inflight(scm->fp->user, scm->fp->fp[i]);
+ return max_level;
+ }
+
+--- a/net/unix/garbage.c
++++ b/net/unix/garbage.c
+@@ -122,7 +122,7 @@ struct sock *unix_get_socket(struct file
+ * descriptor if it is for an AF_UNIX socket.
+ */
+
+-void unix_inflight(struct file *fp)
++void unix_inflight(struct user_struct *user, struct file *fp)
+ {
+ struct sock *s = unix_get_socket(fp);
+
+@@ -138,11 +138,11 @@ void unix_inflight(struct file *fp)
+ }
+ unix_tot_inflight++;
+ }
+- fp->f_cred->user->unix_inflight++;
++ user->unix_inflight++;
+ spin_unlock(&unix_gc_lock);
+ }
+
+-void unix_notinflight(struct file *fp)
++void unix_notinflight(struct user_struct *user, struct file *fp)
+ {
+ struct sock *s = unix_get_socket(fp);
+
+@@ -155,7 +155,7 @@ void unix_notinflight(struct file *fp)
+ list_del_init(&u->link);
+ unix_tot_inflight--;
+ }
+- fp->f_cred->user->unix_inflight--;
++ user->unix_inflight--;
+ spin_unlock(&unix_gc_lock);
+ }
+
diff --git a/debian/patches/series b/debian/patches/series
index 19b0d54..7f5a155 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1205,3 +1205,4 @@ bugfix/all/aufs-for-4.3-xino-handles-eintr-from-the-dying-proce.patch
bugfix/all/af_unix-guard-against-other-sk-in-unix_dgram_sendmsg.patch
bugfix/all/pipe-fix-buffer-offset-after-partially-failed-read.patch
bugfix/all/alsa-usb-audio-avoid-freeing-umidi-object-twice.patch
+bugfix/all/unix-correctly-track-in-flight-fds-in-sending-process-user_struct.patch
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/kernel/linux.git
More information about the Kernel-svn-changes
mailing list