History

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

Linus Torvalds committed 10 months ago

Commit c537e122 parents b543459 ec69daa4 files · +35 −15Browse files

Unified · Split

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