Skip to content

Commit

Permalink
bpf: Always use maximal size for copy_array()
Browse files Browse the repository at this point in the history
Instead of counting on prior allocations to have sized allocations to
the next kmalloc bucket size, always perform a krealloc that is at least
ksize(dst) in size (which is a no-op), so the size can be correctly
tracked by all the various allocation size trackers (KASAN,
__alloc_size, etc).

Reported-by: Hyunwoo Kim <[email protected]>
Link: https://lore.kernel.org/bpf/20221223094551.GA1439509@ubuntu
Fixes: ceb35b6 ("bpf/verifier: Use kmalloc_size_roundup() to match ksize() usage")
Cc: Alexei Starovoitov <[email protected]>
Cc: Daniel Borkmann <[email protected]>
Cc: John Fastabend <[email protected]>
Cc: Andrii Nakryiko <[email protected]>
Cc: Martin KaFai Lau <[email protected]>
Cc: Song Liu <[email protected]>
Cc: Yonghong Song <[email protected]>
Cc: KP Singh <[email protected]>
Cc: Stanislav Fomichev <[email protected]>
Cc: Hao Luo <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: [email protected]
Signed-off-by: Kees Cook <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Alexei Starovoitov <[email protected]>
  • Loading branch information
kees authored and Alexei Starovoitov committed Dec 28, 2022
1 parent f90dd66 commit 45435d8
Showing 1 changed file with 7 additions and 5 deletions.
12 changes: 7 additions & 5 deletions kernel/bpf/verifier.c
Original file line number Diff line number Diff line change
Expand Up @@ -1054,6 +1054,8 @@ static void print_insn_state(struct bpf_verifier_env *env,
*/
static void *copy_array(void *dst, const void *src, size_t n, size_t size, gfp_t flags)
{
size_t alloc_bytes;
void *orig = dst;
size_t bytes;

if (ZERO_OR_NULL_PTR(src))
Expand All @@ -1062,11 +1064,11 @@ static void *copy_array(void *dst, const void *src, size_t n, size_t size, gfp_t
if (unlikely(check_mul_overflow(n, size, &bytes)))
return NULL;

if (ksize(dst) < ksize(src)) {
kfree(dst);
dst = kmalloc_track_caller(kmalloc_size_roundup(bytes), flags);
if (!dst)
return NULL;
alloc_bytes = max(ksize(orig), kmalloc_size_roundup(bytes));
dst = krealloc(orig, alloc_bytes, flags);
if (!dst) {
kfree(orig);
return NULL;
}

memcpy(dst, src, bytes);
Expand Down

0 comments on commit 45435d8

Please sign in to comment.