Skip to content

Commit 6447e69

Browse files
tohojogregkh
authored andcommitted
bpf, test_run: Subtract size of xdp_frame from allowed metadata size
[ Upstream commit e558cca ] The xdp_frame structure takes up part of the XDP frame headroom, limiting the size of the metadata. However, in bpf_test_run, we don't take this into account, which makes it possible for userspace to supply a metadata size that is too large (taking up the entire headroom). If userspace supplies such a large metadata size in live packet mode, the xdp_update_frame_from_buff() call in xdp_test_run_init_page() call will fail, after which packet transmission proceeds with an uninitialised frame structure, leading to the usual Bad Stuff. The commit in the Fixes tag fixed a related bug where the second check in xdp_update_frame_from_buff() could fail, but did not add any additional constraints on the metadata size. Complete the fix by adding an additional check on the metadata size. Reorder the checks slightly to make the logic clearer and add a comment. Link: https://lore.kernel.org/r/fa2be179-bad7-4ee3-8668-4903d1853461@hust.edu.cn Fixes: b6f1f78 ("bpf, test_run: Fix packet size check for live packet mode") Reported-by: Yinhao Hu <dddddd@hust.edu.cn> Reported-by: Kaiyan Mei <M202472210@hust.edu.cn> Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com> Reviewed-by: Amery Hung <ameryhung@gmail.com> Link: https://lore.kernel.org/r/20260105114747.1358750-1-toke@redhat.com Signed-off-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 6611a73 commit 6447e69

1 file changed

Lines changed: 13 additions & 5 deletions

File tree

net/bpf/test_run.c

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1230,8 +1230,6 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr,
12301230
batch_size = NAPI_POLL_WEIGHT;
12311231
else if (batch_size > TEST_XDP_MAX_BATCH)
12321232
return -E2BIG;
1233-
1234-
headroom += sizeof(struct xdp_page_head);
12351233
} else if (batch_size) {
12361234
return -EINVAL;
12371235
}
@@ -1244,16 +1242,26 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr,
12441242
/* There can't be user provided data before the meta data */
12451243
if (ctx->data_meta || ctx->data_end > kattr->test.data_size_in ||
12461244
ctx->data > ctx->data_end ||
1247-
unlikely(xdp_metalen_invalid(ctx->data)) ||
12481245
(do_live && (kattr->test.data_out || kattr->test.ctx_out)))
12491246
goto free_ctx;
1250-
/* Meta data is allocated from the headroom */
1251-
headroom -= ctx->data;
12521247

12531248
meta_sz = ctx->data;
1249+
if (xdp_metalen_invalid(meta_sz) || meta_sz > headroom - sizeof(struct xdp_frame))
1250+
goto free_ctx;
1251+
1252+
/* Meta data is allocated from the headroom */
1253+
headroom -= meta_sz;
12541254
linear_sz = ctx->data_end;
12551255
}
12561256

1257+
/* The xdp_page_head structure takes up space in each page, limiting the
1258+
* size of the packet data; add the extra size to headroom here to make
1259+
* sure it's accounted in the length checks below, but not in the
1260+
* metadata size check above.
1261+
*/
1262+
if (do_live)
1263+
headroom += sizeof(struct xdp_page_head);
1264+
12571265
max_linear_sz = PAGE_SIZE - headroom - tailroom;
12581266
linear_sz = min_t(u32, linear_sz, max_linear_sz);
12591267

0 commit comments

Comments
 (0)