Skip to content

Commit 45435d8

Browse files
keesAlexei Starovoitov
authored andcommitted
bpf: Always use maximal size for copy_array()
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]>
1 parent f90dd66 commit 45435d8

File tree

1 file changed

+7
-5
lines changed

1 file changed

+7
-5
lines changed

kernel/bpf/verifier.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1054,6 +1054,8 @@ static void print_insn_state(struct bpf_verifier_env *env,
10541054
*/
10551055
static void *copy_array(void *dst, const void *src, size_t n, size_t size, gfp_t flags)
10561056
{
1057+
size_t alloc_bytes;
1058+
void *orig = dst;
10571059
size_t bytes;
10581060

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

1065-
if (ksize(dst) < ksize(src)) {
1066-
kfree(dst);
1067-
dst = kmalloc_track_caller(kmalloc_size_roundup(bytes), flags);
1068-
if (!dst)
1069-
return NULL;
1067+
alloc_bytes = max(ksize(orig), kmalloc_size_roundup(bytes));
1068+
dst = krealloc(orig, alloc_bytes, flags);
1069+
if (!dst) {
1070+
kfree(orig);
1071+
return NULL;
10701072
}
10711073

10721074
memcpy(dst, src, bytes);

0 commit comments

Comments
 (0)