Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1401978

[PATCH 4.5 021/101] bpf: fix refcnt overflow

From Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Newsgroups linux.kernel
Subject [PATCH 4.5 021/101] bpf: fix refcnt overflow
Date 2016-05-17 03:50 +0200
Message-ID <rzCj2-6q8-67@gated-at.bofh.it> (permalink)
References <rzBZD-6iF-3@gated-at.bofh.it>
Organization linux.* mail to news gateway

Show all headers | View raw


4.5-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Alexei Starovoitov <ast@fb.com>

[ Upstream commit 92117d8443bc5afacc8d5ba82e541946310f106e ]

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@google.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 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(-)

--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -165,12 +165,13 @@ void bpf_register_prog_type(struct bpf_p
 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);
 
--- a/kernel/bpf/inode.c
+++ b/kernel/bpf/inode.c
@@ -31,10 +31,10 @@ static void *bpf_any_get(void *raw, enum
 {
 	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);
@@ -297,7 +297,8 @@ static void *bpf_obj_do_get(const struct
 		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;
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -201,11 +201,18 @@ struct bpf_map *__bpf_map_get(struct fd
 	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)
@@ -217,7 +224,7 @@ struct bpf_map *bpf_map_get_with_uref(u3
 	if (IS_ERR(map))
 		return map;
 
-	bpf_map_inc(map, true);
+	map = bpf_map_inc(map, true);
 	fdput(f);
 
 	return map;
@@ -600,6 +607,15 @@ static struct bpf_prog *__bpf_prog_get(s
 	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()
  */
@@ -612,7 +628,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;
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -2023,15 +2023,18 @@ static int replace_map_fd_with_map_ptr(s
 				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++;

Back to linux.kernel | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread


Thread

[PATCH 4.5 000/101] 4.5.5-stable review Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-17 03:50 +0200
  [PATCH 4.5 051/101] crypto: testmgr - Use kmalloc memory for RSA input Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-17 03:50 +0200
  [PATCH 4.5 005/101] net: sched: do not requeue a NULL skb Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-17 03:50 +0200
  [PATCH 4.5 047/101] mm: thp: calculate the mapcount correctly for THP pages during WP faults Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-17 03:50 +0200
  [PATCH 4.5 060/101] pinctrl: at91-pio4: fix pull-up/down logic Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-17 03:50 +0200
  [PATCH 4.5 002/101] decnet: Do not build routes to devices without decnet private data. Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-17 03:50 +0200
  [PATCH 4.5 019/101] net/mlx4_en: fix spurious timestamping callbacks Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-17 03:50 +0200
  [PATCH 4.5 009/101] net: use skb_postpush_rcsum instead of own implementations Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-17 03:50 +0200
  [PATCH 4.5 053/101] ALSA: usb-audio: Yet another Phoneix Audio device quirk Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-17 03:50 +0200
  [PATCH 4.5 057/101] spi: pxa2xx: Do not detect number of enabled chip selects on Intel SPT Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-17 03:50 +0200
  [PATCH 4.5 048/101] crypto: qat - fix invalid pf2vf_resp_wq logic Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-17 03:50 +0200
  [PATCH 4.5 055/101] ALSA: hda - Fix white noise on Asus UX501VW headset Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-17 03:50 +0200
  [PATCH 4.5 045/101] ocfs2: fix posix_acl_create deadlock Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-17 03:50 +0200
  [PATCH 4.5 064/101] vfs: add vfs_select_inode() helper Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-17 03:50 +0200
  [PATCH 4.5 062/101] perf diff: Fix duplicated output column Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-17 03:50 +0200
  [PATCH 4.5 046/101] zsmalloc: fix zs_can_compact() integer overflow Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-17 03:50 +0200
  [PATCH 4.5 052/101] ALSA: usb-audio: Quirk for yet another Phoenix Audio devices (v2) Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-17 03:50 +0200
  [PATCH 4.5 023/101] samples/bpf: fix trace_output example Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-17 03:50 +0200
  [PATCH 4.5 041/101] net: thunderx: avoid exposing kernel stack Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-17 03:50 +0200
  [PATCH 4.5 016/101] net/mlx5e: Fix minimum MTU Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-17 03:50 +0200
  [PATCH 4.5 050/101] crypto: hash - Fix page length clamping in hash walk Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-17 03:50 +0200
  [PATCH 4.5 043/101] net/route: enforce hoplimit max value Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-17 03:50 +0200
  [PATCH 4.5 024/101] net: Implement net_dbg_ratelimited() for CONFIG_DYNAMIC_DEBUG case Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-17 03:50 +0200
  [PATCH 4.5 061/101] regmap: spmi: Fix regmap_spmi_ext_read in multi-byte case Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-17 03:50 +0200
  [PATCH 4.5 029/101] sch_dsmark: update backlog as well Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-17 03:50 +0200
  [PATCH 4.5 021/101] bpf: fix refcnt overflow Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-17 03:50 +0200
  [PATCH 4.5 049/101] crypto: qat - fix adf_ctl_drv.c:undefined reference to adf_init_pf_wq Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-05-17 03:50 +0200
  Re: [PATCH 4.5 000/101] 4.5.5-stable review Guenter Roeck <linux@roeck-us.net> - 2016-05-17 19:30 +0200
  Re: [PATCH 4.5 000/101] 4.5.5-stable review Shuah Khan <shuahkh@osg.samsung.com> - 2016-05-17 19:30 +0200

csiph-web