bpf: Use memmove for bpf_dynptr_{read,write}
authorKumar Kartikeya Dwivedi <memxor@gmail.com>
Wed, 7 Dec 2022 20:41:40 +0000 (02:11 +0530)
committerAlexei Starovoitov <ast@kernel.org>
Fri, 9 Dec 2022 02:39:28 +0000 (18:39 -0800)
It may happen that destination buffer memory overlaps with memory dynptr
points to. Hence, we must use memmove to correctly copy from dynptr to
destination buffer, or source buffer to dynptr.

This actually isn't a problem right now, as memcpy implementation falls
back to memmove on detecting overlap and warns about it, but we
shouldn't be relying on that.

Acked-by: Joanne Koong <joannelkoong@gmail.com>
Acked-by: David Vernet <void@manifault.com>
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/r/20221207204141.308952-7-memxor@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
kernel/bpf/helpers.c

index fa1093d4ad6b7469bcf457e30e036ba7973182d4..af30c6cbd65db1401b00103493bce4882ca4afc2 100644 (file)
@@ -1495,7 +1495,11 @@ BPF_CALL_5(bpf_dynptr_read, void *, dst, u32, len, const struct bpf_dynptr_kern
        if (err)
                return err;
 
-       memcpy(dst, src->data + src->offset + offset, len);
+       /* Source and destination may possibly overlap, hence use memmove to
+        * copy the data. E.g. bpf_dynptr_from_mem may create two dynptr
+        * pointing to overlapping PTR_TO_MAP_VALUE regions.
+        */
+       memmove(dst, src->data + src->offset + offset, len);
 
        return 0;
 }
@@ -1523,7 +1527,11 @@ BPF_CALL_5(bpf_dynptr_write, const struct bpf_dynptr_kern *, dst, u32, offset, v
        if (err)
                return err;
 
-       memcpy(dst->data + dst->offset + offset, src, len);
+       /* Source and destination may possibly overlap, hence use memmove to
+        * copy the data. E.g. bpf_dynptr_from_mem may create two dynptr
+        * pointing to overlapping PTR_TO_MAP_VALUE regions.
+        */
+       memmove(dst->data + dst->offset + offset, src, len);
 
        return 0;
 }