[linux] 01/01: Add some security fixes

debian-kernel at lists.debian.org debian-kernel at lists.debian.org
Thu Jan 14 23:39:53 UTC 2016


This is an automated email from the git hooks/post-receive script.

benh pushed a commit to branch jessie-security
in repository linux.

commit 965a4a7650ec925a27ba3d71470683a48d767fda
Author: Ben Hutchings <ben at decadent.org.uk>
Date:   Thu Jan 14 23:36:24 2016 +0000

    Add some security fixes
---
 debian/changelog                                   |  10 ++
 ...t-soft-lockup-when-sctp_accept-is-called-.patch | 190 +++++++++++++++++++++
 ...unsafe-ldisc-reference-via-ioctl-tiocgetd.patch |  63 +++++++
 ...sh-on-detecting-device-without-write_urbs.patch |  31 ++++
 debian/patches/series                              |   3 +
 5 files changed, 297 insertions(+)

diff --git a/debian/changelog b/debian/changelog
index effb94b..461dbaf 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,13 @@
+linux (3.16.7-ckt20-1+deb8u3) UNRELEASED; urgency=medium
+
+  * usb: serial: visor: fix crash on detecting device without write_urbs
+    (CVE-2015-7566)
+  * sctp: Prevent soft lockup when sctp_accept() is called during a timeout event
+    (CVE-2015-8767)
+  * tty: Fix unsafe ldisc reference via ioctl(TIOCGETD) (CVE-2016-0723)
+
+ -- Ben Hutchings <ben at decadent.org.uk>  Thu, 14 Jan 2016 23:36:13 +0000
+
 linux (3.16.7-ckt20-1+deb8u2) jessie-security; urgency=medium
 
   * [xen] Fix race conditions in back-end drivers (CVE-2015-8550, XSA-155)
diff --git a/debian/patches/bugfix/all/sctp-prevent-soft-lockup-when-sctp_accept-is-called-.patch b/debian/patches/bugfix/all/sctp-prevent-soft-lockup-when-sctp_accept-is-called-.patch
new file mode 100644
index 0000000..1d4dd1f
--- /dev/null
+++ b/debian/patches/bugfix/all/sctp-prevent-soft-lockup-when-sctp_accept-is-called-.patch
@@ -0,0 +1,190 @@
+From: Karl Heiss <kheiss at gmail.com>
+Date: Thu, 24 Sep 2015 12:15:07 -0400
+Subject: sctp: Prevent soft lockup when sctp_accept() is called during a
+ timeout event
+Origin: https://git.kernel.org/linus/635682a14427d241bab7bbdeebb48a7d7b91638e
+
+A case can occur when sctp_accept() is called by the user during
+a heartbeat timeout event after the 4-way handshake.  Since
+sctp_assoc_migrate() changes both assoc->base.sk and assoc->ep, the
+bh_sock_lock in sctp_generate_heartbeat_event() will be taken with
+the listening socket but released with the new association socket.
+The result is a deadlock on any future attempts to take the listening
+socket lock.
+
+Note that this race can occur with other SCTP timeouts that take
+the bh_lock_sock() in the event sctp_accept() is called.
+
+ BUG: soft lockup - CPU#9 stuck for 67s! [swapper:0]
+ ...
+ RIP: 0010:[<ffffffff8152d48e>]  [<ffffffff8152d48e>] _spin_lock+0x1e/0x30
+ RSP: 0018:ffff880028323b20  EFLAGS: 00000206
+ RAX: 0000000000000002 RBX: ffff880028323b20 RCX: 0000000000000000
+ RDX: 0000000000000000 RSI: ffff880028323be0 RDI: ffff8804632c4b48
+ RBP: ffffffff8100bb93 R08: 0000000000000000 R09: 0000000000000000
+ R10: ffff880610662280 R11: 0000000000000100 R12: ffff880028323aa0
+ R13: ffff8804383c3880 R14: ffff880028323a90 R15: ffffffff81534225
+ FS:  0000000000000000(0000) GS:ffff880028320000(0000) knlGS:0000000000000000
+ CS:  0010 DS: 0018 ES: 0018 CR0: 000000008005003b
+ CR2: 00000000006df528 CR3: 0000000001a85000 CR4: 00000000000006e0
+ DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+ DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
+ Process swapper (pid: 0, threadinfo ffff880616b70000, task ffff880616b6cab0)
+ Stack:
+ ffff880028323c40 ffffffffa01c2582 ffff880614cfb020 0000000000000000
+ <d> 0100000000000000 00000014383a6c44 ffff8804383c3880 ffff880614e93c00
+ <d> ffff880614e93c00 0000000000000000 ffff8804632c4b00 ffff8804383c38b8
+ Call Trace:
+ <IRQ>
+ [<ffffffffa01c2582>] ? sctp_rcv+0x492/0xa10 [sctp]
+ [<ffffffff8148c559>] ? nf_iterate+0x69/0xb0
+ [<ffffffff814974a0>] ? ip_local_deliver_finish+0x0/0x2d0
+ [<ffffffff8148c716>] ? nf_hook_slow+0x76/0x120
+ [<ffffffff814974a0>] ? ip_local_deliver_finish+0x0/0x2d0
+ [<ffffffff8149757d>] ? ip_local_deliver_finish+0xdd/0x2d0
+ [<ffffffff81497808>] ? ip_local_deliver+0x98/0xa0
+ [<ffffffff81496ccd>] ? ip_rcv_finish+0x12d/0x440
+ [<ffffffff81497255>] ? ip_rcv+0x275/0x350
+ [<ffffffff8145cfeb>] ? __netif_receive_skb+0x4ab/0x750
+ ...
+
+With lockdep debugging:
+
+ =====================================
+ [ BUG: bad unlock balance detected! ]
+ -------------------------------------
+ CslRx/12087 is trying to release lock (slock-AF_INET) at:
+ [<ffffffffa01bcae0>] sctp_generate_timeout_event+0x40/0xe0 [sctp]
+ but there are no more locks to release!
+
+ other info that might help us debug this:
+ 2 locks held by CslRx/12087:
+ #0:  (&asoc->timers[i]){+.-...}, at: [<ffffffff8108ce1f>] run_timer_softirq+0x16f/0x3e0
+ #1:  (slock-AF_INET){+.-...}, at: [<ffffffffa01bcac3>] sctp_generate_timeout_event+0x23/0xe0 [sctp]
+
+Ensure the socket taken is also the same one that is released by
+saving a copy of the socket before entering the timeout event
+critical section.
+
+Signed-off-by: Karl Heiss <kheiss at gmail.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+[bwh: Backported to 3.16: adjust context]
+---
+ net/sctp/sm_sideeffect.c | 42 +++++++++++++++++++++++-------------------
+ 1 file changed, 23 insertions(+), 19 deletions(-)
+
+diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
+index f554b9a..6098d4c 100644
+--- a/net/sctp/sm_sideeffect.c
++++ b/net/sctp/sm_sideeffect.c
+@@ -244,12 +244,13 @@ void sctp_generate_t3_rtx_event(unsigned long peer)
+ 	int error;
+ 	struct sctp_transport *transport = (struct sctp_transport *) peer;
+ 	struct sctp_association *asoc = transport->asoc;
+-	struct net *net = sock_net(asoc->base.sk);
++	struct sock *sk = asoc->base.sk;
++	struct net *net = sock_net(sk);
+ 
+ 	/* Check whether a task is in the sock.  */
+ 
+-	bh_lock_sock(asoc->base.sk);
+-	if (sock_owned_by_user(asoc->base.sk)) {
++	bh_lock_sock(sk);
++	if (sock_owned_by_user(sk)) {
+ 		pr_debug("%s: sock is busy\n", __func__);
+ 
+ 		/* Try again later.  */
+@@ -272,10 +273,10 @@ void sctp_generate_t3_rtx_event(unsigned long peer)
+ 			   transport, GFP_ATOMIC);
+ 
+ 	if (error)
+-		asoc->base.sk->sk_err = -error;
++		sk->sk_err = -error;
+ 
+ out_unlock:
+-	bh_unlock_sock(asoc->base.sk);
++	bh_unlock_sock(sk);
+ 	sctp_transport_put(transport);
+ }
+ 
+@@ -285,11 +286,12 @@ out_unlock:
+ static void sctp_generate_timeout_event(struct sctp_association *asoc,
+ 					sctp_event_timeout_t timeout_type)
+ {
+-	struct net *net = sock_net(asoc->base.sk);
++	struct sock *sk = asoc->base.sk;
++	struct net *net = sock_net(sk);
+ 	int error = 0;
+ 
+-	bh_lock_sock(asoc->base.sk);
+-	if (sock_owned_by_user(asoc->base.sk)) {
++	bh_lock_sock(sk);
++	if (sock_owned_by_user(sk)) {
+ 		pr_debug("%s: sock is busy: timer %d\n", __func__,
+ 			 timeout_type);
+ 
+@@ -312,10 +314,10 @@ static void sctp_generate_timeout_event(struct sctp_association *asoc,
+ 			   (void *)timeout_type, GFP_ATOMIC);
+ 
+ 	if (error)
+-		asoc->base.sk->sk_err = -error;
++		sk->sk_err = -error;
+ 
+ out_unlock:
+-	bh_unlock_sock(asoc->base.sk);
++	bh_unlock_sock(sk);
+ 	sctp_association_put(asoc);
+ }
+ 
+@@ -365,10 +367,11 @@ void sctp_generate_heartbeat_event(unsigned long data)
+ 	int error = 0;
+ 	struct sctp_transport *transport = (struct sctp_transport *) data;
+ 	struct sctp_association *asoc = transport->asoc;
+-	struct net *net = sock_net(asoc->base.sk);
++	struct sock *sk = asoc->base.sk;
++	struct net *net = sock_net(sk);
+ 
+-	bh_lock_sock(asoc->base.sk);
+-	if (sock_owned_by_user(asoc->base.sk)) {
++	bh_lock_sock(sk);
++	if (sock_owned_by_user(sk)) {
+ 		pr_debug("%s: sock is busy\n", __func__);
+ 
+ 		/* Try again later.  */
+@@ -389,10 +392,10 @@ void sctp_generate_heartbeat_event(unsigned long data)
+ 			   transport, GFP_ATOMIC);
+ 
+ 	 if (error)
+-		 asoc->base.sk->sk_err = -error;
++		sk->sk_err = -error;
+ 
+ out_unlock:
+-	bh_unlock_sock(asoc->base.sk);
++	bh_unlock_sock(sk);
+ 	sctp_transport_put(transport);
+ }
+ 
+@@ -403,10 +406,11 @@ void sctp_generate_proto_unreach_event(unsigned long data)
+ {
+ 	struct sctp_transport *transport = (struct sctp_transport *) data;
+ 	struct sctp_association *asoc = transport->asoc;
+-	struct net *net = sock_net(asoc->base.sk);
++	struct sock *sk = asoc->base.sk;
++	struct net *net = sock_net(sk);
+ 
+-	bh_lock_sock(asoc->base.sk);
+-	if (sock_owned_by_user(asoc->base.sk)) {
++	bh_lock_sock(sk);
++	if (sock_owned_by_user(sk)) {
+ 		pr_debug("%s: sock is busy\n", __func__);
+ 
+ 		/* Try again later.  */
+@@ -427,7 +431,7 @@ void sctp_generate_proto_unreach_event(unsigned long data)
+ 		   asoc->state, asoc->ep, asoc, transport, GFP_ATOMIC);
+ 
+ out_unlock:
+-	bh_unlock_sock(asoc->base.sk);
++	bh_unlock_sock(sk);
+ 	sctp_association_put(asoc);
+ }
+ 
diff --git a/debian/patches/bugfix/all/tty-fix-unsafe-ldisc-reference-via-ioctl-tiocgetd.patch b/debian/patches/bugfix/all/tty-fix-unsafe-ldisc-reference-via-ioctl-tiocgetd.patch
new file mode 100644
index 0000000..4545440
--- /dev/null
+++ b/debian/patches/bugfix/all/tty-fix-unsafe-ldisc-reference-via-ioctl-tiocgetd.patch
@@ -0,0 +1,63 @@
+From: Peter Hurley <peter at hurleysoftware.com>
+Subject: tty: Fix unsafe ldisc reference via ioctl(TIOCGETD)
+Date: Sun, 10 Jan 2016 22:40:55 -0800
+Origin: http://article.gmane.org/gmane.linux.kernel/2123249
+
+ioctl(TIOCGETD) retrieves the line discipline id directly from the
+ldisc because the line discipline id (c_line) in termios is untrustworthy;
+userspace may have set termios via ioctl(TCSETS*) without actually
+changing the line discipline via ioctl(TIOCSETD).
+
+However, directly accessing the current ldisc via tty->ldisc is
+unsafe; the ldisc ptr dereferenced may be stale if the line discipline
+is changing via ioctl(TIOCSETD) or hangup.
+
+Wait for the line discipline reference (just like read() or write())
+to retrieve the "current" line discipline id.
+
+Cc: <stable at vger.kernel.org>
+Signed-off-by: Peter Hurley <peter at hurleysoftware.com>
+---
+ drivers/tty/tty_io.c | 24 +++++++++++++++++++++++-
+ 1 file changed, 23 insertions(+), 1 deletion(-)
+
+--- a/drivers/tty/tty_io.c
++++ b/drivers/tty/tty_io.c
+@@ -2585,6 +2585,28 @@ static int tiocsetd(struct tty_struct *t
+ }
+ 
+ /**
++ *	tiocgetd	-	get line discipline
++ *	@tty: tty device
++ *	@p: pointer to user data
++ *
++ *	Retrieves the line discipline id directly from the ldisc.
++ *
++ *	Locking: waits for ldisc reference (in case the line discipline
++ *		is changing or the tty is being hungup)
++ */
++
++static int tiocgetd(struct tty_struct *tty, int __user *p)
++{
++	struct tty_ldisc *ld;
++	int ret;
++
++	ld = tty_ldisc_ref_wait(tty);
++	ret = put_user(ld->ops->num, p);
++	tty_ldisc_deref(ld);
++	return ret;
++}
++
++/**
+  *	send_break	-	performed time break
+  *	@tty: device to break on
+  *	@duration: timeout in mS
+@@ -2798,7 +2820,7 @@ long tty_ioctl(struct file *file, unsign
+ 	case TIOCGSID:
+ 		return tiocgsid(tty, real_tty, p);
+ 	case TIOCGETD:
+-		return put_user(tty->ldisc->ops->num, (int __user *)p);
++		return tiocgetd(tty, p);
+ 	case TIOCSETD:
+ 		return tiocsetd(tty, p);
+ 	case TIOCVHANGUP:
diff --git a/debian/patches/bugfix/all/usb-serial-visor-fix-crash-on-detecting-device-without-write_urbs.patch b/debian/patches/bugfix/all/usb-serial-visor-fix-crash-on-detecting-device-without-write_urbs.patch
new file mode 100644
index 0000000..4b6a5d6
--- /dev/null
+++ b/debian/patches/bugfix/all/usb-serial-visor-fix-crash-on-detecting-device-without-write_urbs.patch
@@ -0,0 +1,31 @@
+From: Vladis Dronov <vdronov at redhat.com>
+Subject: usb: serial: visor: fix crash on detecting device without write_urbs
+Date: Tue, 12 Jan 2016 15:10:50 +0100
+Origin: http://article.gmane.org/gmane.linux.usb.general/136045
+Bug: https://bugzilla.redhat.com/show_bug.cgi?id=1296466
+
+The visor driver crashes in clie_5_attach() when a specially crafted USB
+device without bulk-out endpoint is detected. This fix adds a check that
+the device has proper configuration expected by the driver.
+
+Reported-by: Ralf Spenneberg <ralf at spenneberg.net>
+Signed-off-by: Vladis Dronov <vdronov at redhat.com>
+---
+ drivers/usb/serial/visor.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/serial/visor.c
++++ b/drivers/usb/serial/visor.c
+@@ -597,8 +597,10 @@ static int clie_5_attach(struct usb_seri
+ 	 */
+ 
+ 	/* some sanity check */
+-	if (serial->num_ports < 2)
+-		return -1;
++	if (serial->num_bulk_out < 2) {
++		dev_err(&serial->interface->dev, "missing bulk out endpoints\n");
++		return -ENODEV;
++	}
+ 
+ 	/* port 0 now uses the modified endpoint Address */
+ 	port = serial->port[0];
diff --git a/debian/patches/series b/debian/patches/series
index f22c3f2..6fd80f7 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -670,3 +670,6 @@ bugfix/x86/KVM-x86-Reload-pit-counters-for-all-channels-when-re.patch
 bugfix/all/revert-net-add-length-argument-to-skb_copy_and_csum_datagram_iovec.patch
 bugfix/all/udp-properly-support-msg_peek-with-truncated-buffers.patch
 bugfix/all/revert-xhci-don-t-finish-a-td-if-we-get-a-short-transfer.patch
+bugfix/all/usb-serial-visor-fix-crash-on-detecting-device-without-write_urbs.patch
+bugfix/all/sctp-prevent-soft-lockup-when-sctp_accept-is-called-.patch
+bugfix/all/tty-fix-unsafe-ldisc-reference-via-ioctl-tiocgetd.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