Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichal Kubecek <mkubecek@suse.cz>2016-12-01 12:55:38 +0100
committerMichal Kubecek <mkubecek@suse.cz>2016-12-01 12:55:38 +0100
commitb29a190a8a3dbc998daa5e8560b6c7b0670f892c (patch)
tree290904b0f4ecdda97e9b8f3c20e416794f9c5ff5
parent2f20d4ed504c65fbf472f0d707564c56896a0a8f (diff)
tipc: check minimum bearer MTU (CVE-2016-8632 bsc#1008831).rpm-4.4.21-84
-rw-r--r--patches.fixes/tipc-check-minimum-bearer-MTU.patch121
-rw-r--r--series.conf1
2 files changed, 122 insertions, 0 deletions
diff --git a/patches.fixes/tipc-check-minimum-bearer-MTU.patch b/patches.fixes/tipc-check-minimum-bearer-MTU.patch
new file mode 100644
index 0000000000..ea547b3b4c
--- /dev/null
+++ b/patches.fixes/tipc-check-minimum-bearer-MTU.patch
@@ -0,0 +1,121 @@
+From: Michal Kubecek <mkubecek@suse.cz>
+Date: Thu, 1 Dec 2016 11:26:33 +0100
+Subject: tipc: check minimum bearer MTU
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+Patch-mainline: Submitted - 20161201 (target 4.9)
+References: CVE-2016-8632 bsc#1008831
+
+Qian Zhang (张谦) reported a potential socket buffer overflow in
+tipc_msg_build() which is also known as CVE-2016-8632: due to
+insufficient checks, a buffer overflow can occur if MTU is too short for
+even tipc headers. As anyone can set device MTU in a user/net namespace,
+this issue can be abused by a regular user.
+
+As agreed in the discussion on Ben Hutchings' original patch, we should
+check the MTU at the moment a bearer is attached rather than for each
+processed packet. We also need to repeat the check when bearer MTU is
+adjusted to new device MTU. UDP case also needs a check to avoid
+overflow when calculating bearer MTU.
+
+Fixes: b97bf3fd8f6a ("[TIPC] Initial merge")
+Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
+Reported-by: Qian Zhang (张谦) <zhangqian-c@360.cn>
+
+---
+ net/tipc/bearer.c | 11 +++++++++--
+ net/tipc/bearer.h | 13 +++++++++++++
+ net/tipc/udp_media.c | 5 +++++
+ 3 files changed, 27 insertions(+), 2 deletions(-)
+
+diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
+index 648f2a67f314..4457c6e9ede8 100644
+--- a/net/tipc/bearer.c
++++ b/net/tipc/bearer.c
+@@ -381,6 +381,10 @@ int tipc_enable_l2_media(struct net *net, struct tipc_bearer *b,
+ dev = dev_get_by_name(net, driver_name);
+ if (!dev)
+ return -ENODEV;
++ if (tipc_check_mtu(dev, 0)) {
++ dev_put(dev);
++ return -EINVAL;
++ }
+
+ /* Associate TIPC bearer with L2 bearer */
+ rcu_assign_pointer(b->media_ptr, dev);
+@@ -570,14 +574,17 @@ static int tipc_l2_device_event(struct notifier_block *nb, unsigned long evt,
+ if (!b_ptr)
+ return NOTIFY_DONE;
+
+- b_ptr->mtu = dev->mtu;
+-
+ switch (evt) {
+ case NETDEV_CHANGE:
+ if (netif_carrier_ok(dev))
+ break;
+ case NETDEV_GOING_DOWN:
+ case NETDEV_CHANGEMTU:
++ if (tipc_check_mtu(dev, 0)) {
++ bearer_disable(net, b_ptr);
++ break;
++ }
++ b_ptr->mtu = dev->mtu;
+ tipc_reset_bearer(net, b_ptr);
+ break;
+ case NETDEV_CHANGEADDR:
+diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h
+index 552185bc4773..6306b6f8f615 100644
+--- a/net/tipc/bearer.h
++++ b/net/tipc/bearer.h
+@@ -39,6 +39,7 @@
+
+ #include "netlink.h"
+ #include "core.h"
++#include "msg.h"
+ #include <net/genetlink.h>
+
+ #define MAX_MEDIA 3
+@@ -61,6 +62,9 @@
+ #define TIPC_MEDIA_TYPE_IB 2
+ #define TIPC_MEDIA_TYPE_UDP 3
+
++/* minimum bearer MTU */
++#define TIPC_MIN_BEARER_MTU (MAX_H_SIZE + INT_H_SIZE)
++
+ /**
+ * struct tipc_node_map - set of node identifiers
+ * @count: # of nodes in set
+@@ -226,4 +230,13 @@ void tipc_bearer_xmit(struct net *net, u32 bearer_id,
+ void tipc_bearer_bc_xmit(struct net *net, u32 bearer_id,
+ struct sk_buff_head *xmitq);
+
++/* check if device MTU is sufficient for tipc headers */
++static inline bool tipc_check_mtu(struct net_device *dev, unsigned int reserve)
++{
++ if (dev->mtu >= TIPC_MIN_BEARER_MTU + reserve)
++ return false;
++ netdev_warn(dev, "MTU too low for tipc bearer\n");
++ return true;
++}
++
+ #endif /* _TIPC_BEARER_H */
+diff --git a/net/tipc/udp_media.c b/net/tipc/udp_media.c
+index 6af78c6276b4..34939fd6ced3 100644
+--- a/net/tipc/udp_media.c
++++ b/net/tipc/udp_media.c
+@@ -376,6 +376,11 @@ static int tipc_udp_enable(struct net *net, struct tipc_bearer *b,
+ udp_conf.local_ip.s_addr = htonl(INADDR_ANY);
+ udp_conf.use_udp_checksums = false;
+ ub->ifindex = dev->ifindex;
++ if (tipc_check_mtu(dev, sizeof(struct iphdr) +
++ sizeof(struct udphdr))) {
++ err = -EINVAL;
++ goto err;
++ }
+ b->mtu = dev->mtu - sizeof(struct iphdr)
+ - sizeof(struct udphdr);
+ #if IS_ENABLED(CONFIG_IPV6)
+--
+2.10.2
+
diff --git a/series.conf b/series.conf
index 317dff8fc4..f51197a988 100644
--- a/series.conf
+++ b/series.conf
@@ -1738,6 +1738,7 @@
patches.kabi/kabi-hide-new-member-recursion_counter-in-struct-sk_.patch
patches.fixes/sctp-validate-chunk-len-before-actually-using-it.patch
patches.fixes/packet-fix-race-condition-in-packet_set_ring.patch
+ patches.fixes/tipc-check-minimum-bearer-MTU.patch
########################################################
# Netfilter