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: 2012c867c8 ("bpf: verifier: Accept dynptr mem as mem in helpers")
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://patch.msgid.link/20261017230950.802052-16-alexei.starovoitov@gmail.com
This commit is contained in:
Alexei Starovoitov 2026-10-17 23:09:49 +00:00
parent 1db084f428
commit ab08863c58
No known key found for this signature in database

View File

@ -4330,7 +4330,8 @@ BPF_CALL_4(bpf_xdp_store_bytes, struct xdp_buff *, xdp, u32, offset,
if (!ptr) if (!ptr)
bpf_xdp_copy_buf(xdp, offset, buf, len, true); bpf_xdp_copy_buf(xdp, offset, buf, len, true);
else else
memcpy(ptr, buf, len); /* through a dynptr the source may be an overlapping slice */
memmove(ptr, buf, len);
return 0; return 0;
} }