summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2018-11-25 23:04:58 -0500
committerDavid S. Miller <davem@davemloft.net>2018-11-25 23:04:58 -0500
commit69500127424cd90ff2cf8191256b2ac3b0a4af56 (patch)
tree0c28501d1b0ba294b0f63803eb72b4af1594d870 /kernel
parentaba36930a35e7f1fe1319b203f25c05d6c119936 (diff)
parent1efb6ee3edea57f57f9fb05dba8dcb3f7333f61f (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf
Daniel Borkmann says: ==================== pull-request: bpf 2018-11-25 The following pull-request contains BPF updates for your *net* tree. The main changes are: 1) Fix an off-by-one bug when adjusting subprog start offsets after patching, from Edward. 2) Fix several bugs such as overflow in size allocation in queue / stack map creation, from Alexei. 3) Fix wrong IPv6 destination port byte order in bpf_sk_lookup_udp helper, from Andrey. 4) Fix several bugs in bpftool such as preventing an infinite loop in get_fdinfo, error handling and man page references, from Quentin. 5) Fix a warning in bpf_trace_printk() that wasn't catching an invalid format string, from Martynas. 6) Fix a bug in BPF cgroup local storage where non-atomic allocation was used in atomic context, from Roman. 7) Fix a NULL pointer dereference bug in bpftool from reallocarray() error handling, from Jakub and Wen. 8) Add a copy of pkt_cls.h and tc_bpf.h uapi headers to the tools include infrastructure so that bpftool compiles on older RHEL7-like user space which does not ship these headers, from Yonghong. 9) Fix BPF kselftests for user space where to get ping test working with ping6 and ping -6, from Li. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/bpf/local_storage.c3
-rw-r--r--kernel/bpf/queue_stack_maps.c16
-rw-r--r--kernel/bpf/verifier.c2
-rw-r--r--kernel/trace/bpf_trace.c8
4 files changed, 16 insertions, 13 deletions
diff --git a/kernel/bpf/local_storage.c b/kernel/bpf/local_storage.c
index c97a8f968638..bed9d48a7ae9 100644
--- a/kernel/bpf/local_storage.c
+++ b/kernel/bpf/local_storage.c
@@ -139,7 +139,8 @@ static int cgroup_storage_update_elem(struct bpf_map *map, void *_key,
139 return -ENOENT; 139 return -ENOENT;
140 140
141 new = kmalloc_node(sizeof(struct bpf_storage_buffer) + 141 new = kmalloc_node(sizeof(struct bpf_storage_buffer) +
142 map->value_size, __GFP_ZERO | GFP_USER, 142 map->value_size,
143 __GFP_ZERO | GFP_ATOMIC | __GFP_NOWARN,
143 map->numa_node); 144 map->numa_node);
144 if (!new) 145 if (!new)
145 return -ENOMEM; 146 return -ENOMEM;
diff --git a/kernel/bpf/queue_stack_maps.c b/kernel/bpf/queue_stack_maps.c
index 8bbd72d3a121..b384ea9f3254 100644
--- a/kernel/bpf/queue_stack_maps.c
+++ b/kernel/bpf/queue_stack_maps.c
@@ -7,6 +7,7 @@
7#include <linux/bpf.h> 7#include <linux/bpf.h>
8#include <linux/list.h> 8#include <linux/list.h>
9#include <linux/slab.h> 9#include <linux/slab.h>
10#include <linux/capability.h>
10#include "percpu_freelist.h" 11#include "percpu_freelist.h"
11 12
12#define QUEUE_STACK_CREATE_FLAG_MASK \ 13#define QUEUE_STACK_CREATE_FLAG_MASK \
@@ -45,8 +46,12 @@ static bool queue_stack_map_is_full(struct bpf_queue_stack *qs)
45/* Called from syscall */ 46/* Called from syscall */
46static int queue_stack_map_alloc_check(union bpf_attr *attr) 47static int queue_stack_map_alloc_check(union bpf_attr *attr)
47{ 48{
49 if (!capable(CAP_SYS_ADMIN))
50 return -EPERM;
51
48 /* check sanity of attributes */ 52 /* check sanity of attributes */
49 if (attr->max_entries == 0 || attr->key_size != 0 || 53 if (attr->max_entries == 0 || attr->key_size != 0 ||
54 attr->value_size == 0 ||
50 attr->map_flags & ~QUEUE_STACK_CREATE_FLAG_MASK) 55 attr->map_flags & ~QUEUE_STACK_CREATE_FLAG_MASK)
51 return -EINVAL; 56 return -EINVAL;
52 57
@@ -63,15 +68,10 @@ static struct bpf_map *queue_stack_map_alloc(union bpf_attr *attr)
63{ 68{
64 int ret, numa_node = bpf_map_attr_numa_node(attr); 69 int ret, numa_node = bpf_map_attr_numa_node(attr);
65 struct bpf_queue_stack *qs; 70 struct bpf_queue_stack *qs;
66 u32 size, value_size; 71 u64 size, queue_size, cost;
67 u64 queue_size, cost;
68
69 size = attr->max_entries + 1;
70 value_size = attr->value_size;
71
72 queue_size = sizeof(*qs) + (u64) value_size * size;
73 72
74 cost = queue_size; 73 size = (u64) attr->max_entries + 1;
74 cost = queue_size = sizeof(*qs) + size * attr->value_size;
75 if (cost >= U32_MAX - PAGE_SIZE) 75 if (cost >= U32_MAX - PAGE_SIZE)
76 return ERR_PTR(-E2BIG); 76 return ERR_PTR(-E2BIG);
77 77
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 1971ca325fb4..6dd419550aba 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -5650,7 +5650,7 @@ static void adjust_subprog_starts(struct bpf_verifier_env *env, u32 off, u32 len
5650 return; 5650 return;
5651 /* NOTE: fake 'exit' subprog should be updated as well. */ 5651 /* NOTE: fake 'exit' subprog should be updated as well. */
5652 for (i = 0; i <= env->subprog_cnt; i++) { 5652 for (i = 0; i <= env->subprog_cnt; i++) {
5653 if (env->subprog_info[i].start < off) 5653 if (env->subprog_info[i].start <= off)
5654 continue; 5654 continue;
5655 env->subprog_info[i].start += len - 1; 5655 env->subprog_info[i].start += len - 1;
5656 } 5656 }
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
index 08fcfe440c63..9864a35c8bb5 100644
--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@ -196,11 +196,13 @@ BPF_CALL_5(bpf_trace_printk, char *, fmt, u32, fmt_size, u64, arg1,
196 i++; 196 i++;
197 } else if (fmt[i] == 'p' || fmt[i] == 's') { 197 } else if (fmt[i] == 'p' || fmt[i] == 's') {
198 mod[fmt_cnt]++; 198 mod[fmt_cnt]++;
199 i++; 199 /* disallow any further format extensions */
200 if (!isspace(fmt[i]) && !ispunct(fmt[i]) && fmt[i] != 0) 200 if (fmt[i + 1] != 0 &&
201 !isspace(fmt[i + 1]) &&
202 !ispunct(fmt[i + 1]))
201 return -EINVAL; 203 return -EINVAL;
202 fmt_cnt++; 204 fmt_cnt++;
203 if (fmt[i - 1] == 's') { 205 if (fmt[i] == 's') {
204 if (str_seen) 206 if (str_seen)
205 /* allow only one '%s' per fmt string */ 207 /* allow only one '%s' per fmt string */
206 return -EINVAL; 208 return -EINVAL;