Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'bpf-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf

Pull bpf fixes from Alexei Starovoitov:

- Fix incorrect usage of BPF_TRAMP_F_ORIG_STACK in riscv JIT (Menglong
Dong)

- Fix reference count leak in bpf_prog_test_run_xdp() (Tetsuo Handa)

- Fix metadata size check in bpf_test_run() (Toke Høiland-Jørgensen)

- Check that BPF insn array is not allowed as a map for const strings
(Deepanshu Kartikey)

* tag 'bpf-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf:
bpf: Fix reference count leak in bpf_prog_test_run_xdp()
bpf: Reject BPF_MAP_TYPE_INSN_ARRAY in check_reg_const_str()
selftests/bpf: Update xdp_context_test_run test to check maximum metadata size
bpf, test_run: Subtract size of xdp_frame from allowed metadata size
riscv, bpf: Fix incorrect usage of BPF_TRAMP_F_ORIG_STACK

+35 -15
+2 -4
arch/riscv/net/bpf_jit_comp64.c
··· 1133 1133 1134 1134 store_args(nr_arg_slots, args_off, ctx); 1135 1135 1136 - /* skip to actual body of traced function */ 1137 - if (flags & BPF_TRAMP_F_ORIG_STACK) 1138 - orig_call += RV_FENTRY_NINSNS * 4; 1139 - 1140 1136 if (flags & BPF_TRAMP_F_CALL_ORIG) { 1141 1137 emit_imm(RV_REG_A0, ctx->insns ? (const s64)im : RV_MAX_COUNT_IMM, ctx); 1142 1138 ret = emit_call((const u64)__bpf_tramp_enter, true, ctx); ··· 1167 1171 } 1168 1172 1169 1173 if (flags & BPF_TRAMP_F_CALL_ORIG) { 1174 + /* skip to actual body of traced function */ 1175 + orig_call += RV_FENTRY_NINSNS * 4; 1170 1176 restore_args(min_t(int, nr_arg_slots, RV_MAX_REG_ARGS), args_off, ctx); 1171 1177 restore_stack_args(nr_arg_slots - RV_MAX_REG_ARGS, args_off, stk_arg_off, ctx); 1172 1178 ret = emit_call((const u64)orig_call, true, ctx);
+5
kernel/bpf/verifier.c
··· 9609 9609 if (reg->type != PTR_TO_MAP_VALUE) 9610 9610 return -EINVAL; 9611 9611 9612 + if (map->map_type == BPF_MAP_TYPE_INSN_ARRAY) { 9613 + verbose(env, "R%d points to insn_array map which cannot be used as const string\n", regno); 9614 + return -EACCES; 9615 + } 9616 + 9612 9617 if (!bpf_map_is_rdonly(map)) { 9613 9618 verbose(env, "R%d does not point to a readonly map'\n", regno); 9614 9619 return -EACCES;
+17 -8
net/bpf/test_run.c
··· 1294 1294 batch_size = NAPI_POLL_WEIGHT; 1295 1295 else if (batch_size > TEST_XDP_MAX_BATCH) 1296 1296 return -E2BIG; 1297 - 1298 - headroom += sizeof(struct xdp_page_head); 1299 1297 } else if (batch_size) { 1300 1298 return -EINVAL; 1301 1299 } ··· 1306 1308 /* There can't be user provided data before the meta data */ 1307 1309 if (ctx->data_meta || ctx->data_end > kattr->test.data_size_in || 1308 1310 ctx->data > ctx->data_end || 1309 - unlikely(xdp_metalen_invalid(ctx->data)) || 1310 1311 (do_live && (kattr->test.data_out || kattr->test.ctx_out))) 1311 1312 goto free_ctx; 1312 - /* Meta data is allocated from the headroom */ 1313 - headroom -= ctx->data; 1314 1313 1315 1314 meta_sz = ctx->data; 1315 + if (xdp_metalen_invalid(meta_sz) || meta_sz > headroom - sizeof(struct xdp_frame)) 1316 + goto free_ctx; 1317 + 1318 + /* Meta data is allocated from the headroom */ 1319 + headroom -= meta_sz; 1316 1320 linear_sz = ctx->data_end; 1317 1321 } 1322 + 1323 + /* The xdp_page_head structure takes up space in each page, limiting the 1324 + * size of the packet data; add the extra size to headroom here to make 1325 + * sure it's accounted in the length checks below, but not in the 1326 + * metadata size check above. 1327 + */ 1328 + if (do_live) 1329 + headroom += sizeof(struct xdp_page_head); 1318 1330 1319 1331 max_linear_sz = PAGE_SIZE - headroom - tailroom; 1320 1332 linear_sz = min_t(u32, linear_sz, max_linear_sz); ··· 1363 1355 1364 1356 if (sinfo->nr_frags == MAX_SKB_FRAGS) { 1365 1357 ret = -ENOMEM; 1366 - goto out; 1358 + goto out_put_dev; 1367 1359 } 1368 1360 1369 1361 page = alloc_page(GFP_KERNEL); 1370 1362 if (!page) { 1371 1363 ret = -ENOMEM; 1372 - goto out; 1364 + goto out_put_dev; 1373 1365 } 1374 1366 1375 1367 frag = &sinfo->frags[sinfo->nr_frags++]; ··· 1381 1373 if (copy_from_user(page_address(page), data_in + size, 1382 1374 data_len)) { 1383 1375 ret = -EFAULT; 1384 - goto out; 1376 + goto out_put_dev; 1385 1377 } 1386 1378 sinfo->xdp_frags_size += data_len; 1387 1379 size += data_len; ··· 1396 1388 ret = bpf_test_run_xdp_live(prog, &xdp, repeat, batch_size, &duration); 1397 1389 else 1398 1390 ret = bpf_test_run(prog, &xdp, repeat, &retval, &duration, true); 1391 + out_put_dev: 1399 1392 /* We convert the xdp_buff back to an xdp_md before checking the return 1400 1393 * code so the reference count of any held netdevice will be decremented 1401 1394 * even if the test run failed.
+11 -3
tools/testing/selftests/bpf/prog_tests/xdp_context_test_run.c
··· 47 47 struct test_xdp_context_test_run *skel = NULL; 48 48 char data[sizeof(pkt_v4) + sizeof(__u32)]; 49 49 char bad_ctx[sizeof(struct xdp_md) + 1]; 50 + char large_data[256]; 50 51 struct xdp_md ctx_in, ctx_out; 51 52 DECLARE_LIBBPF_OPTS(bpf_test_run_opts, opts, 52 53 .data_in = &data, ··· 95 94 test_xdp_context_error(prog_fd, opts, 4, sizeof(__u32), sizeof(data), 96 95 0, 0, 0); 97 96 98 - /* Meta data must be 255 bytes or smaller */ 99 - test_xdp_context_error(prog_fd, opts, 0, 256, sizeof(data), 0, 0, 0); 100 - 101 97 /* Total size of data must be data_end - data_meta or larger */ 102 98 test_xdp_context_error(prog_fd, opts, 0, sizeof(__u32), 103 99 sizeof(data) + 1, 0, 0, 0); ··· 113 115 /* The egress cannot be specified */ 114 116 test_xdp_context_error(prog_fd, opts, 0, sizeof(__u32), sizeof(data), 115 117 0, 0, 1); 118 + 119 + /* Meta data must be 216 bytes or smaller (256 - sizeof(struct 120 + * xdp_frame)). Test both nearest invalid size and nearest invalid 121 + * 4-byte-aligned size, and make sure data_in is large enough that we 122 + * actually hit the check on metadata length 123 + */ 124 + opts.data_in = large_data; 125 + opts.data_size_in = sizeof(large_data); 126 + test_xdp_context_error(prog_fd, opts, 0, 217, sizeof(large_data), 0, 0, 0); 127 + test_xdp_context_error(prog_fd, opts, 0, 220, sizeof(large_data), 0, 0, 0); 116 128 117 129 test_xdp_context_test_run__destroy(skel); 118 130 }