[pve-devel] [PATCH kernel] Fix CVE-2016-4485, CVE-2016-4486, CVE-2016-4558

Fabian Grünbichler f.gruenbichler at proxmox.com
Wed May 11 12:36:51 CEST 2016


cherry-picked from Ubuntu Xenial master-next
---
 CVE-2016-4485-net-fix-infoleak-in-llc.patch       |  39 +++++
 CVE-2016-4486-net-fix-infoleak-in-rtnetlink.patch |  57 ++++++++
 CVE-2016-4558-bpf-fix-refcnt-overflow.patch       | 166 ++++++++++++++++++++++
 Makefile                                          |   3 +
 4 files changed, 265 insertions(+)
 create mode 100644 CVE-2016-4485-net-fix-infoleak-in-llc.patch
 create mode 100644 CVE-2016-4486-net-fix-infoleak-in-rtnetlink.patch
 create mode 100644 CVE-2016-4558-bpf-fix-refcnt-overflow.patch

diff --git a/CVE-2016-4485-net-fix-infoleak-in-llc.patch b/CVE-2016-4485-net-fix-infoleak-in-llc.patch
new file mode 100644
index 0000000..ff6bb13
--- /dev/null
+++ b/CVE-2016-4485-net-fix-infoleak-in-llc.patch
@@ -0,0 +1,39 @@
+From f1006a1bc4504ad7996ff9a33982b419e15945bc Mon Sep 17 00:00:00 2001
+From: Kangjie Lu <kangjielu at gmail.com>
+Date: Tue, 10 May 2016 15:12:22 +0100
+Subject: [PATCH] net: fix infoleak in llc
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The stack object “info” has a total size of 12 bytes. Its last byte
+is padding which is not initialized and leaked via “put_cmsg”.
+
+Signed-off-by: Kangjie Lu <kjlu at gatech.edu>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+(cherry picked from commit b8670c09f37bdf2847cc44f36511a53afc6161fd)
+CVE-2016-4485
+BugLink: https://bugs.launchpad.net/bugs/1578496
+Signed-off-by: Luis Henriques <luis.henriques at canonical.com>
+Acked-by: Tim Gardner <tim.gardner at canonical.com>
+Acked-by: Brad Figg <brad.figg at canonical.com>
+Signed-off-by: Kamal Mostafa <kamal at canonical.com>
+---
+ net/llc/af_llc.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c
+index 8dab4e5..bb8edb9 100644
+--- a/net/llc/af_llc.c
++++ b/net/llc/af_llc.c
+@@ -626,6 +626,7 @@ static void llc_cmsg_rcv(struct msghdr *msg, struct sk_buff *skb)
+ 	if (llc->cmsg_flags & LLC_CMSG_PKTINFO) {
+ 		struct llc_pktinfo info;
+ 
++		memset(&info, 0, sizeof(info));
+ 		info.lpi_ifindex = llc_sk(skb->sk)->dev->ifindex;
+ 		llc_pdu_decode_dsap(skb, &info.lpi_sap);
+ 		llc_pdu_decode_da(skb, info.lpi_mac);
+-- 
+2.1.4
+
diff --git a/CVE-2016-4486-net-fix-infoleak-in-rtnetlink.patch b/CVE-2016-4486-net-fix-infoleak-in-rtnetlink.patch
new file mode 100644
index 0000000..91560ce
--- /dev/null
+++ b/CVE-2016-4486-net-fix-infoleak-in-rtnetlink.patch
@@ -0,0 +1,57 @@
+From e60b65e11250a7ff7d3030b3d516fa5eb89e7b74 Mon Sep 17 00:00:00 2001
+From: Kangjie Lu <kangjielu at gmail.com>
+Date: Tue, 10 May 2016 15:12:40 +0100
+Subject: [PATCH] net: fix infoleak in rtnetlink
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The stack object “map” has a total size of 32 bytes. Its last 4
+bytes are padding generated by compiler. These padding bytes are
+not initialized and sent out via “nla_put”.
+
+Signed-off-by: Kangjie Lu <kjlu at gatech.edu>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+(cherry picked from commit 5f8e44741f9f216e33736ea4ec65ca9ac03036e6)
+CVE-2016-4486
+BugLink: https://bugs.launchpad.net/bugs/1578497
+Signed-off-by: Luis Henriques <luis.henriques at canonical.com>
+Acked-by: Tim Gardner <tim.gardner at canonical.com>
+Acked-by: Christopher Arges <chris.j.arges at canonical.com>
+Signed-off-by: Kamal Mostafa <kamal at canonical.com>
+---
+ net/core/rtnetlink.c | 18 ++++++++++--------
+ 1 file changed, 10 insertions(+), 8 deletions(-)
+
+diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
+index ca966f7..87b91ff 100644
+--- a/net/core/rtnetlink.c
++++ b/net/core/rtnetlink.c
+@@ -1175,14 +1175,16 @@ static noinline_for_stack int rtnl_fill_vfinfo(struct sk_buff *skb,
+ 
+ static int rtnl_fill_link_ifmap(struct sk_buff *skb, struct net_device *dev)
+ {
+-	struct rtnl_link_ifmap map = {
+-		.mem_start   = dev->mem_start,
+-		.mem_end     = dev->mem_end,
+-		.base_addr   = dev->base_addr,
+-		.irq         = dev->irq,
+-		.dma         = dev->dma,
+-		.port        = dev->if_port,
+-	};
++	struct rtnl_link_ifmap map;
++
++	memset(&map, 0, sizeof(map));
++	map.mem_start   = dev->mem_start;
++	map.mem_end     = dev->mem_end;
++	map.base_addr   = dev->base_addr;
++	map.irq         = dev->irq;
++	map.dma         = dev->dma;
++	map.port        = dev->if_port;
++
+ 	if (nla_put(skb, IFLA_MAP, sizeof(map), &map))
+ 		return -EMSGSIZE;
+ 
+-- 
+2.1.4
+
diff --git a/CVE-2016-4558-bpf-fix-refcnt-overflow.patch b/CVE-2016-4558-bpf-fix-refcnt-overflow.patch
new file mode 100644
index 0000000..7b8cf2b
--- /dev/null
+++ b/CVE-2016-4558-bpf-fix-refcnt-overflow.patch
@@ -0,0 +1,166 @@
+From eed43f28e204a9133d7523ebe1194688d9bdc802 Mon Sep 17 00:00:00 2001
+From: Alexei Starovoitov <ast at fb.com>
+Date: Mon, 9 May 2016 17:22:16 +0100
+Subject: [PATCH] bpf: fix refcnt overflow
+
+On a system with >32Gbyte of phyiscal memory and infinite RLIMIT_MEMLOCK,
+the malicious application may overflow 32-bit bpf program refcnt.
+It's also possible to overflow map refcnt on 1Tb system.
+Impose 32k hard limit which means that the same bpf program or
+map cannot be shared by more than 32k processes.
+
+Fixes: 1be7f75d1668 ("bpf: enable non-root eBPF programs")
+Reported-by: Jann Horn <jannh at google.com>
+Signed-off-by: Alexei Starovoitov <ast at kernel.org>
+Acked-by: Daniel Borkmann <daniel at iogearbox.net>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+
+(cherry picked from commit 92117d8443bc5afacc8d5ba82e541946310f106e)
+CVE-2016-4558
+BugLink: https://bugs.launchpad.net/bugs/1579140
+Signed-off-by: Luis Henriques <luis.henriques at canonical.com>
+Acked-by: Stefan Bader <stefan.bader at canonical.com>
+Acked-by: Tim Gardner <tim.gardner at canonical.com>
+Signed-off-by: Kamal Mostafa <kamal at canonical.com>
+---
+ include/linux/bpf.h   |  3 ++-
+ kernel/bpf/inode.c    |  7 ++++---
+ kernel/bpf/syscall.c  | 24 ++++++++++++++++++++----
+ kernel/bpf/verifier.c | 11 +++++++----
+ 4 files changed, 33 insertions(+), 12 deletions(-)
+
+diff --git a/include/linux/bpf.h b/include/linux/bpf.h
+index 83d1926..67bc2da 100644
+--- a/include/linux/bpf.h
++++ b/include/linux/bpf.h
+@@ -165,12 +165,13 @@ void bpf_register_prog_type(struct bpf_prog_type_list *tl);
+ void bpf_register_map_type(struct bpf_map_type_list *tl);
+ 
+ struct bpf_prog *bpf_prog_get(u32 ufd);
++struct bpf_prog *bpf_prog_inc(struct bpf_prog *prog);
+ void bpf_prog_put(struct bpf_prog *prog);
+ void bpf_prog_put_rcu(struct bpf_prog *prog);
+ 
+ struct bpf_map *bpf_map_get_with_uref(u32 ufd);
+ struct bpf_map *__bpf_map_get(struct fd f);
+-void bpf_map_inc(struct bpf_map *map, bool uref);
++struct bpf_map *bpf_map_inc(struct bpf_map *map, bool uref);
+ void bpf_map_put_with_uref(struct bpf_map *map);
+ void bpf_map_put(struct bpf_map *map);
+ 
+diff --git a/kernel/bpf/inode.c b/kernel/bpf/inode.c
+index 5a8a797..d1a7646 100644
+--- a/kernel/bpf/inode.c
++++ b/kernel/bpf/inode.c
+@@ -31,10 +31,10 @@ static void *bpf_any_get(void *raw, enum bpf_type type)
+ {
+ 	switch (type) {
+ 	case BPF_TYPE_PROG:
+-		atomic_inc(&((struct bpf_prog *)raw)->aux->refcnt);
++		raw = bpf_prog_inc(raw);
+ 		break;
+ 	case BPF_TYPE_MAP:
+-		bpf_map_inc(raw, true);
++		raw = bpf_map_inc(raw, true);
+ 		break;
+ 	default:
+ 		WARN_ON_ONCE(1);
+@@ -277,7 +277,8 @@ static void *bpf_obj_do_get(const struct filename *pathname,
+ 		goto out;
+ 
+ 	raw = bpf_any_get(inode->i_private, *type);
+-	touch_atime(&path);
++	if (!IS_ERR(raw))
++		touch_atime(&path);
+ 
+ 	path_put(&path);
+ 	return raw;
+diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
+index 3b39550..4e32cc9 100644
+--- a/kernel/bpf/syscall.c
++++ b/kernel/bpf/syscall.c
+@@ -181,11 +181,18 @@ struct bpf_map *__bpf_map_get(struct fd f)
+ 	return f.file->private_data;
+ }
+ 
+-void bpf_map_inc(struct bpf_map *map, bool uref)
++/* prog's and map's refcnt limit */
++#define BPF_MAX_REFCNT 32768
++
++struct bpf_map *bpf_map_inc(struct bpf_map *map, bool uref)
+ {
+-	atomic_inc(&map->refcnt);
++	if (atomic_inc_return(&map->refcnt) > BPF_MAX_REFCNT) {
++		atomic_dec(&map->refcnt);
++		return ERR_PTR(-EBUSY);
++	}
+ 	if (uref)
+ 		atomic_inc(&map->usercnt);
++	return map;
+ }
+ 
+ struct bpf_map *bpf_map_get_with_uref(u32 ufd)
+@@ -197,7 +204,7 @@ struct bpf_map *bpf_map_get_with_uref(u32 ufd)
+ 	if (IS_ERR(map))
+ 		return map;
+ 
+-	bpf_map_inc(map, true);
++	map = bpf_map_inc(map, true);
+ 	fdput(f);
+ 
+ 	return map;
+@@ -580,6 +587,15 @@ static struct bpf_prog *__bpf_prog_get(struct fd f)
+ 	return f.file->private_data;
+ }
+ 
++struct bpf_prog *bpf_prog_inc(struct bpf_prog *prog)
++{
++	if (atomic_inc_return(&prog->aux->refcnt) > BPF_MAX_REFCNT) {
++		atomic_dec(&prog->aux->refcnt);
++		return ERR_PTR(-EBUSY);
++	}
++	return prog;
++}
++
+ /* called by sockets/tracing/seccomp before attaching program to an event
+  * pairs with bpf_prog_put()
+  */
+@@ -592,7 +608,7 @@ struct bpf_prog *bpf_prog_get(u32 ufd)
+ 	if (IS_ERR(prog))
+ 		return prog;
+ 
+-	atomic_inc(&prog->aux->refcnt);
++	prog = bpf_prog_inc(prog);
+ 	fdput(f);
+ 
+ 	return prog;
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index 7520d73..2a1ed8e 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -2022,15 +2022,18 @@ static int replace_map_fd_with_map_ptr(struct verifier_env *env)
+ 				return -E2BIG;
+ 			}
+ 
+-			/* remember this map */
+-			env->used_maps[env->used_map_cnt++] = map;
+-
+ 			/* hold the map. If the program is rejected by verifier,
+ 			 * the map will be released by release_maps() or it
+ 			 * will be used by the valid program until it's unloaded
+ 			 * and all maps are released in free_bpf_prog_info()
+ 			 */
+-			bpf_map_inc(map, false);
++			map = bpf_map_inc(map, false);
++			if (IS_ERR(map)) {
++				fdput(f);
++				return PTR_ERR(map);
++			}
++			env->used_maps[env->used_map_cnt++] = map;
++
+ 			fdput(f);
+ next_insn:
+ 			insn++;
+-- 
+2.1.4
+
diff --git a/Makefile b/Makefile
index 89b524b..639a9d2 100644
--- a/Makefile
+++ b/Makefile
@@ -239,6 +239,9 @@ ${KERNEL_SRC}/README ${KERNEL_CFG_ORG}: ${KERNELSRCTAR}
 	cd ${KERNEL_SRC}; patch -p1 <../bug-950-tcp-fix-tcp_mark_head_lost-to-check-skb-len-before-f.patch
 	cd ${KERNEL_SRC}; patch -p1 < ../981-1-PCI-Reverse-standard-ACS-vs-device-specific-ACS-enabling.patch
 	cd ${KERNEL_SRC}; patch -p1 < ../981-2-PCI-Quirk-PCH-root-port-ACS-for-Sunrise-Point.patch
+	cd ${KERNEL_SRC}; patch -p1 < ../CVE-2016-4485-net-fix-infoleak-in-llc.patch
+	cd ${KERNEL_SRC}; patch -p1 < ../CVE-2016-4486-net-fix-infoleak-in-rtnetlink.patch
+	cd ${KERNEL_SRC}; patch -p1 < ../CVE-2016-4558-bpf-fix-refcnt-overflow.patch
 	sed -i ${KERNEL_SRC}/Makefile -e 's/^EXTRAVERSION.*$$/EXTRAVERSION=${EXTRAVERSION}/'
 	touch $@
 
-- 
2.1.4





More information about the pve-devel mailing list