[linux] 07/09: firewire: net: guard against rx buffer overflows (CVE-2016-8633)

debian-kernel at lists.debian.org debian-kernel at lists.debian.org
Thu Dec 1 00:23:47 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 4fae4ce99a9edb38ea85fae557a01c53c8ece850
Author: Ben Hutchings <ben at decadent.org.uk>
Date:   Wed Nov 30 20:45:14 2016 +0000

    firewire: net: guard against rx buffer overflows (CVE-2016-8633)
---
 debian/changelog                                   |   1 +
 ...ire-net-guard-against-rx-buffer-overflows.patch | 126 +++++++++++++++++++++
 debian/patches/series                              |   1 +
 3 files changed, 128 insertions(+)

diff --git a/debian/changelog b/debian/changelog
index 699ac26..fe28ed0 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -12,6 +12,7 @@ linux (3.16.36-1+deb8u3) UNRELEASED; urgency=medium
   * posix_acl: Clear SGID bit when setting file permissions (CVE-2016-7097)
   * block: fix use-after-free in seq file (CVE-2016-7910)
   * block: fix use-after-free in sys_ioprio_get() (CVE-2016-7911)
+  * firewire: net: guard against rx buffer overflows (CVE-2016-8633)
 
  -- Ben Hutchings <ben at decadent.org.uk>  Wed, 30 Nov 2016 04:06:41 +0000
 
diff --git a/debian/patches/bugfix/all/firewire-net-guard-against-rx-buffer-overflows.patch b/debian/patches/bugfix/all/firewire-net-guard-against-rx-buffer-overflows.patch
new file mode 100644
index 0000000..250b981
--- /dev/null
+++ b/debian/patches/bugfix/all/firewire-net-guard-against-rx-buffer-overflows.patch
@@ -0,0 +1,126 @@
+From: Stefan Richter <stefanr at s5r6.in-berlin.de>
+Date: Sat, 29 Oct 2016 21:28:18 +0200
+Subject: firewire: net: guard against rx buffer overflows
+Origin: https://git.kernel.org/linus/667121ace9dbafb368618dbabcf07901c962ddac
+
+The IP-over-1394 driver firewire-net lacked input validation when
+handling incoming fragmented datagrams.  A maliciously formed fragment
+with a respectively large datagram_offset would cause a memcpy past the
+datagram buffer.
+
+So, drop any packets carrying a fragment with offset + length larger
+than datagram_size.
+
+In addition, ensure that
+  - GASP header, unfragmented encapsulation header, or fragment
+    encapsulation header actually exists before we access it,
+  - the encapsulated datagram or fragment is of nonzero size.
+
+Reported-by: Eyal Itkin <eyal.itkin at gmail.com>
+Reviewed-by: Eyal Itkin <eyal.itkin at gmail.com>
+Fixes: CVE 2016-8633
+Signed-off-by: Stefan Richter <stefanr at s5r6.in-berlin.de>
+Signed-off-by: Ben Hutchings <ben at decadent.org.uk>
+---
+ drivers/firewire/net.c | 51 ++++++++++++++++++++++++++++++++++----------------
+ 1 file changed, 35 insertions(+), 16 deletions(-)
+
+--- a/drivers/firewire/net.c
++++ b/drivers/firewire/net.c
+@@ -591,6 +591,9 @@ static int fwnet_incoming_packet(struct
+ 	int retval;
+ 	u16 ether_type;
+ 
++	if (len <= RFC2374_UNFRAG_HDR_SIZE)
++		return 0;
++
+ 	hdr.w0 = be32_to_cpu(buf[0]);
+ 	lf = fwnet_get_hdr_lf(&hdr);
+ 	if (lf == RFC2374_HDR_UNFRAG) {
+@@ -615,7 +618,12 @@ static int fwnet_incoming_packet(struct
+ 		return fwnet_finish_incoming_packet(net, skb, source_node_id,
+ 						    is_broadcast, ether_type);
+ 	}
++
+ 	/* A datagram fragment has been received, now the fun begins. */
++
++	if (len <= RFC2374_FRAG_HDR_SIZE)
++		return 0;
++
+ 	hdr.w1 = ntohl(buf[1]);
+ 	buf += 2;
+ 	len -= RFC2374_FRAG_HDR_SIZE;
+@@ -629,6 +637,9 @@ static int fwnet_incoming_packet(struct
+ 	datagram_label = fwnet_get_hdr_dgl(&hdr);
+ 	dg_size = fwnet_get_hdr_dg_size(&hdr); /* ??? + 1 */
+ 
++	if (fg_off + len > dg_size)
++		return 0;
++
+ 	spin_lock_irqsave(&dev->lock, flags);
+ 
+ 	peer = fwnet_peer_find_by_node_id(dev, source_node_id, generation);
+@@ -735,6 +746,22 @@ static void fwnet_receive_packet(struct
+ 	fw_send_response(card, r, rcode);
+ }
+ 
++static int gasp_source_id(__be32 *p)
++{
++	return be32_to_cpu(p[0]) >> 16;
++}
++
++static u32 gasp_specifier_id(__be32 *p)
++{
++	return (be32_to_cpu(p[0]) & 0xffff) << 8 |
++	       (be32_to_cpu(p[1]) & 0xff000000) >> 24;
++}
++
++static u32 gasp_version(__be32 *p)
++{
++	return be32_to_cpu(p[1]) & 0xffffff;
++}
++
+ static void fwnet_receive_broadcast(struct fw_iso_context *context,
+ 		u32 cycle, size_t header_length, void *header, void *data)
+ {
+@@ -744,9 +771,6 @@ static void fwnet_receive_broadcast(stru
+ 	__be32 *buf_ptr;
+ 	int retval;
+ 	u32 length;
+-	u16 source_node_id;
+-	u32 specifier_id;
+-	u32 ver;
+ 	unsigned long offset;
+ 	unsigned long flags;
+ 
+@@ -763,22 +787,17 @@ static void fwnet_receive_broadcast(stru
+ 
+ 	spin_unlock_irqrestore(&dev->lock, flags);
+ 
+-	specifier_id =    (be32_to_cpu(buf_ptr[0]) & 0xffff) << 8
+-			| (be32_to_cpu(buf_ptr[1]) & 0xff000000) >> 24;
+-	ver = be32_to_cpu(buf_ptr[1]) & 0xffffff;
+-	source_node_id = be32_to_cpu(buf_ptr[0]) >> 16;
+-
+-	if (specifier_id == IANA_SPECIFIER_ID &&
+-	    (ver == RFC2734_SW_VERSION
++	if (length > IEEE1394_GASP_HDR_SIZE &&
++	    gasp_specifier_id(buf_ptr) == IANA_SPECIFIER_ID &&
++	    (gasp_version(buf_ptr) == RFC2734_SW_VERSION
+ #if IS_ENABLED(CONFIG_IPV6)
+-	     || ver == RFC3146_SW_VERSION
++	     || gasp_version(buf_ptr) == RFC3146_SW_VERSION
+ #endif
+-	    )) {
+-		buf_ptr += 2;
+-		length -= IEEE1394_GASP_HDR_SIZE;
+-		fwnet_incoming_packet(dev, buf_ptr, length, source_node_id,
++	    ))
++		fwnet_incoming_packet(dev, buf_ptr + 2,
++				      length - IEEE1394_GASP_HDR_SIZE,
++				      gasp_source_id(buf_ptr),
+ 				      context->card->generation, true);
+-	}
+ 
+ 	packet.payload_length = dev->rcv_buffer_size;
+ 	packet.interrupt = 1;
diff --git a/debian/patches/series b/debian/patches/series
index c432675..346b7f0 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -692,6 +692,7 @@ bugfix/powerpc/kvm-ppc-book3s-hv-save-restore-tm-state-in-h_cede.patch
 bugfix/all//posix_acl-clear-sgid-bit-when-setting-file-permissions.patch
 bugfix/all/block-fix-use-after-free-in-seq-file.patch
 bugfix/all/block-fix-use-after-free-in-sys_ioprio_get.patch
+bugfix/all/firewire-net-guard-against-rx-buffer-overflows.patch
 
 # Fix ABI changes
 debian/of-fix-abi-changes.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