diff options
author | David S. Miller <davem@davemloft.net> | 2018-11-25 23:04:58 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-11-25 23:04:58 -0500 |
commit | 69500127424cd90ff2cf8191256b2ac3b0a4af56 (patch) | |
tree | 0c28501d1b0ba294b0f63803eb72b4af1594d870 /kernel | |
parent | aba36930a35e7f1fe1319b203f25c05d6c119936 (diff) | |
parent | 1efb6ee3edea57f57f9fb05dba8dcb3f7333f61f (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.c | 3 | ||||
-rw-r--r-- | kernel/bpf/queue_stack_maps.c | 16 | ||||
-rw-r--r-- | kernel/bpf/verifier.c | 2 | ||||
-rw-r--r-- | kernel/trace/bpf_trace.c | 8 |
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 */ |
46 | static int queue_stack_map_alloc_check(union bpf_attr *attr) | 47 | static 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; |