From ab08863c58b1a96ff8378e373cb3d277cbe65b68 Mon Sep 17 00:00:00 2001 From: Alexei Starovoitov Date: Sat, 17 Oct 2026 23:09:49 +0000 Subject: [PATCH] bpf: Use memmove() to store bytes in an xdp_buff bpf_dynptr_write() to the dynptr of an xdp_buff ends in bpf_xdp_store_bytes(). The source can be a slice of the same xdp_buff which overlaps the destination, and the helper itself takes such a slice as well. memcpy() then reads bytes which it has overwritten already. On x86 with FSRM p = bpf_dynptr_slice_rdwr(&ptr, 0, NULL, 64); bpf_dynptr_write(&ptr, 8, p, 64, 0); repeats the first 8 bytes of the packet instead of moving 64. A write that crosses from the linear part into a fragment is copied piece by piece, where the first piece can overwrite what the second one has yet to read. That is not dealt with here. Fixes: 2012c867c800 ("bpf: verifier: Accept dynptr mem as mem in helpers") Signed-off-by: Alexei Starovoitov Link: https://patch.msgid.link/20261017230950.802052-16-alexei.starovoitov@gmail.com --- net/core/filter.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/core/filter.c b/net/core/filter.c index 7fbee7570d0c..b7ac145b68b1 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -4330,7 +4330,8 @@ BPF_CALL_4(bpf_xdp_store_bytes, struct xdp_buff *, xdp, u32, offset, if (!ptr) bpf_xdp_copy_buf(xdp, offset, buf, len, true); else - memcpy(ptr, buf, len); + /* through a dynptr the source may be an overlapping slice */ + memmove(ptr, buf, len); return 0; }