summaryrefslogtreecommitdiffstats
path: root/kernel/bpf
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-05-25 22:54:42 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-05-25 22:54:42 -0400
commit03250e1028057173b212341015d5fbf53327042c (patch)
tree1d43ff6bc664227f8ac42ba0a7e897dc51986095 /kernel/bpf
parent62d18ecfa64137349fac9c5817784fbd48b54f48 (diff)
parenteb110410b9f6477726026669f3f0c0567e8241e6 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Pull networking fixes from David Miller: "Let's begin the holiday weekend with some networking fixes: 1) Whoops need to restrict cfg80211 wiphy names even more to 64 bytes. From Eric Biggers. 2) Fix flags being ignored when using kernel_connect() with SCTP, from Xin Long. 3) Use after free in DCCP, from Alexey Kodanev. 4) Need to check rhltable_init() return value in ipmr code, from Eric Dumazet. 5) XDP handling fixes in virtio_net from Jason Wang. 6) Missing RTA_TABLE in rtm_ipv4_policy[], from Roopa Prabhu. 7) Need to use IRQ disabling spinlocks in mlx4_qp_lookup(), from Jack Morgenstein. 8) Prevent out-of-bounds speculation using indexes in BPF, from Daniel Borkmann. 9) Fix regression added by AF_PACKET link layer cure, from Willem de Bruijn. 10) Correct ENIC dma mask, from Govindarajulu Varadarajan. 11) Missing config options for PMTU tests, from Stefano Brivio" * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (48 commits) ibmvnic: Fix partial success login retries selftests/net: Add missing config options for PMTU tests mlx4_core: allocate ICM memory in page size chunks enic: set DMA mask to 47 bit ppp: remove the PPPIOCDETACH ioctl ipv4: remove warning in ip_recv_error net : sched: cls_api: deal with egdev path only if needed vhost: synchronize IOTLB message with dev cleanup packet: fix reserve calculation net/mlx5: IPSec, Fix a race between concurrent sandbox QP commands net/mlx5e: When RXFCS is set, add FCS data into checksum calculation bpf: properly enforce index mask to prevent out-of-bounds speculation net/mlx4: Fix irq-unsafe spinlock usage net: phy: broadcom: Fix bcm_write_exp() net: phy: broadcom: Fix auxiliary control register reads net: ipv4: add missing RTA_TABLE to rtm_ipv4_policy net/mlx4: fix spelling mistake: "Inrerface" -> "Interface" and rephrase message ibmvnic: Only do H_EOI for mobility events tuntap: correctly set SOCKWQ_ASYNC_NOSPACE virtio-net: fix leaking page for gso packet during mergeable XDP ...
Diffstat (limited to 'kernel/bpf')
-rw-r--r--kernel/bpf/verifier.c86
1 files changed, 64 insertions, 22 deletions
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 2ce967a63ede..1904e814f282 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -156,7 +156,29 @@ struct bpf_verifier_stack_elem {
156#define BPF_COMPLEXITY_LIMIT_INSNS 131072 156#define BPF_COMPLEXITY_LIMIT_INSNS 131072
157#define BPF_COMPLEXITY_LIMIT_STACK 1024 157#define BPF_COMPLEXITY_LIMIT_STACK 1024
158 158
159#define BPF_MAP_PTR_POISON ((void *)0xeB9F + POISON_POINTER_DELTA) 159#define BPF_MAP_PTR_UNPRIV 1UL
160#define BPF_MAP_PTR_POISON ((void *)((0xeB9FUL << 1) + \
161 POISON_POINTER_DELTA))
162#define BPF_MAP_PTR(X) ((struct bpf_map *)((X) & ~BPF_MAP_PTR_UNPRIV))
163
164static bool bpf_map_ptr_poisoned(const struct bpf_insn_aux_data *aux)
165{
166 return BPF_MAP_PTR(aux->map_state) == BPF_MAP_PTR_POISON;
167}
168
169static bool bpf_map_ptr_unpriv(const struct bpf_insn_aux_data *aux)
170{
171 return aux->map_state & BPF_MAP_PTR_UNPRIV;
172}
173
174static void bpf_map_ptr_store(struct bpf_insn_aux_data *aux,
175 const struct bpf_map *map, bool unpriv)
176{
177 BUILD_BUG_ON((unsigned long)BPF_MAP_PTR_POISON & BPF_MAP_PTR_UNPRIV);
178 unpriv |= bpf_map_ptr_unpriv(aux);
179 aux->map_state = (unsigned long)map |
180 (unpriv ? BPF_MAP_PTR_UNPRIV : 0UL);
181}
160 182
161struct bpf_call_arg_meta { 183struct bpf_call_arg_meta {
162 struct bpf_map *map_ptr; 184 struct bpf_map *map_ptr;
@@ -2358,6 +2380,29 @@ static int prepare_func_exit(struct bpf_verifier_env *env, int *insn_idx)
2358 return 0; 2380 return 0;
2359} 2381}
2360 2382
2383static int
2384record_func_map(struct bpf_verifier_env *env, struct bpf_call_arg_meta *meta,
2385 int func_id, int insn_idx)
2386{
2387 struct bpf_insn_aux_data *aux = &env->insn_aux_data[insn_idx];
2388
2389 if (func_id != BPF_FUNC_tail_call &&
2390 func_id != BPF_FUNC_map_lookup_elem)
2391 return 0;
2392 if (meta->map_ptr == NULL) {
2393 verbose(env, "kernel subsystem misconfigured verifier\n");
2394 return -EINVAL;
2395 }
2396
2397 if (!BPF_MAP_PTR(aux->map_state))
2398 bpf_map_ptr_store(aux, meta->map_ptr,
2399 meta->map_ptr->unpriv_array);
2400 else if (BPF_MAP_PTR(aux->map_state) != meta->map_ptr)
2401 bpf_map_ptr_store(aux, BPF_MAP_PTR_POISON,
2402 meta->map_ptr->unpriv_array);
2403 return 0;
2404}
2405
2361static int check_helper_call(struct bpf_verifier_env *env, int func_id, int insn_idx) 2406static int check_helper_call(struct bpf_verifier_env *env, int func_id, int insn_idx)
2362{ 2407{
2363 const struct bpf_func_proto *fn = NULL; 2408 const struct bpf_func_proto *fn = NULL;
@@ -2412,13 +2457,6 @@ static int check_helper_call(struct bpf_verifier_env *env, int func_id, int insn
2412 err = check_func_arg(env, BPF_REG_2, fn->arg2_type, &meta); 2457 err = check_func_arg(env, BPF_REG_2, fn->arg2_type, &meta);
2413 if (err) 2458 if (err)
2414 return err; 2459 return err;
2415 if (func_id == BPF_FUNC_tail_call) {
2416 if (meta.map_ptr == NULL) {
2417 verbose(env, "verifier bug\n");
2418 return -EINVAL;
2419 }
2420 env->insn_aux_data[insn_idx].map_ptr = meta.map_ptr;
2421 }
2422 err = check_func_arg(env, BPF_REG_3, fn->arg3_type, &meta); 2460 err = check_func_arg(env, BPF_REG_3, fn->arg3_type, &meta);
2423 if (err) 2461 if (err)
2424 return err; 2462 return err;
@@ -2429,6 +2467,10 @@ static int check_helper_call(struct bpf_verifier_env *env, int func_id, int insn
2429 if (err) 2467 if (err)
2430 return err; 2468 return err;
2431 2469
2470 err = record_func_map(env, &meta, func_id, insn_idx);
2471 if (err)
2472 return err;
2473
2432 /* Mark slots with STACK_MISC in case of raw mode, stack offset 2474 /* Mark slots with STACK_MISC in case of raw mode, stack offset
2433 * is inferred from register state. 2475 * is inferred from register state.
2434 */ 2476 */
@@ -2453,8 +2495,6 @@ static int check_helper_call(struct bpf_verifier_env *env, int func_id, int insn
2453 } else if (fn->ret_type == RET_VOID) { 2495 } else if (fn->ret_type == RET_VOID) {
2454 regs[BPF_REG_0].type = NOT_INIT; 2496 regs[BPF_REG_0].type = NOT_INIT;
2455 } else if (fn->ret_type == RET_PTR_TO_MAP_VALUE_OR_NULL) { 2497 } else if (fn->ret_type == RET_PTR_TO_MAP_VALUE_OR_NULL) {
2456 struct bpf_insn_aux_data *insn_aux;
2457
2458 regs[BPF_REG_0].type = PTR_TO_MAP_VALUE_OR_NULL; 2498 regs[BPF_REG_0].type = PTR_TO_MAP_VALUE_OR_NULL;
2459 /* There is no offset yet applied, variable or fixed */ 2499 /* There is no offset yet applied, variable or fixed */
2460 mark_reg_known_zero(env, regs, BPF_REG_0); 2500 mark_reg_known_zero(env, regs, BPF_REG_0);
@@ -2470,11 +2510,6 @@ static int check_helper_call(struct bpf_verifier_env *env, int func_id, int insn
2470 } 2510 }
2471 regs[BPF_REG_0].map_ptr = meta.map_ptr; 2511 regs[BPF_REG_0].map_ptr = meta.map_ptr;
2472 regs[BPF_REG_0].id = ++env->id_gen; 2512 regs[BPF_REG_0].id = ++env->id_gen;
2473 insn_aux = &env->insn_aux_data[insn_idx];
2474 if (!insn_aux->map_ptr)
2475 insn_aux->map_ptr = meta.map_ptr;
2476 else if (insn_aux->map_ptr != meta.map_ptr)
2477 insn_aux->map_ptr = BPF_MAP_PTR_POISON;
2478 } else { 2513 } else {
2479 verbose(env, "unknown return type %d of func %s#%d\n", 2514 verbose(env, "unknown return type %d of func %s#%d\n",
2480 fn->ret_type, func_id_name(func_id), func_id); 2515 fn->ret_type, func_id_name(func_id), func_id);
@@ -5470,6 +5505,7 @@ static int fixup_bpf_calls(struct bpf_verifier_env *env)
5470 struct bpf_insn *insn = prog->insnsi; 5505 struct bpf_insn *insn = prog->insnsi;
5471 const struct bpf_func_proto *fn; 5506 const struct bpf_func_proto *fn;
5472 const int insn_cnt = prog->len; 5507 const int insn_cnt = prog->len;
5508 struct bpf_insn_aux_data *aux;
5473 struct bpf_insn insn_buf[16]; 5509 struct bpf_insn insn_buf[16];
5474 struct bpf_prog *new_prog; 5510 struct bpf_prog *new_prog;
5475 struct bpf_map *map_ptr; 5511 struct bpf_map *map_ptr;
@@ -5544,19 +5580,22 @@ static int fixup_bpf_calls(struct bpf_verifier_env *env)
5544 insn->imm = 0; 5580 insn->imm = 0;
5545 insn->code = BPF_JMP | BPF_TAIL_CALL; 5581 insn->code = BPF_JMP | BPF_TAIL_CALL;
5546 5582
5583 aux = &env->insn_aux_data[i + delta];
5584 if (!bpf_map_ptr_unpriv(aux))
5585 continue;
5586
5547 /* instead of changing every JIT dealing with tail_call 5587 /* instead of changing every JIT dealing with tail_call
5548 * emit two extra insns: 5588 * emit two extra insns:
5549 * if (index >= max_entries) goto out; 5589 * if (index >= max_entries) goto out;
5550 * index &= array->index_mask; 5590 * index &= array->index_mask;
5551 * to avoid out-of-bounds cpu speculation 5591 * to avoid out-of-bounds cpu speculation
5552 */ 5592 */
5553 map_ptr = env->insn_aux_data[i + delta].map_ptr; 5593 if (bpf_map_ptr_poisoned(aux)) {
5554 if (map_ptr == BPF_MAP_PTR_POISON) {
5555 verbose(env, "tail_call abusing map_ptr\n"); 5594 verbose(env, "tail_call abusing map_ptr\n");
5556 return -EINVAL; 5595 return -EINVAL;
5557 } 5596 }
5558 if (!map_ptr->unpriv_array) 5597
5559 continue; 5598 map_ptr = BPF_MAP_PTR(aux->map_state);
5560 insn_buf[0] = BPF_JMP_IMM(BPF_JGE, BPF_REG_3, 5599 insn_buf[0] = BPF_JMP_IMM(BPF_JGE, BPF_REG_3,
5561 map_ptr->max_entries, 2); 5600 map_ptr->max_entries, 2);
5562 insn_buf[1] = BPF_ALU32_IMM(BPF_AND, BPF_REG_3, 5601 insn_buf[1] = BPF_ALU32_IMM(BPF_AND, BPF_REG_3,
@@ -5580,9 +5619,12 @@ static int fixup_bpf_calls(struct bpf_verifier_env *env)
5580 */ 5619 */
5581 if (prog->jit_requested && BITS_PER_LONG == 64 && 5620 if (prog->jit_requested && BITS_PER_LONG == 64 &&
5582 insn->imm == BPF_FUNC_map_lookup_elem) { 5621 insn->imm == BPF_FUNC_map_lookup_elem) {
5583 map_ptr = env->insn_aux_data[i + delta].map_ptr; 5622 aux = &env->insn_aux_data[i + delta];
5584 if (map_ptr == BPF_MAP_PTR_POISON || 5623 if (bpf_map_ptr_poisoned(aux))
5585 !map_ptr->ops->map_gen_lookup) 5624 goto patch_call_imm;
5625
5626 map_ptr = BPF_MAP_PTR(aux->map_state);
5627 if (!map_ptr->ops->map_gen_lookup)
5586 goto patch_call_imm; 5628 goto patch_call_imm;
5587 5629
5588 cnt = map_ptr->ops->map_gen_lookup(map_ptr, insn_buf); 5630 cnt = map_ptr->ops->map_gen_lookup(map_ptr, insn_buf);