mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-29 13:53:33 +00:00
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 <v4bel@theori.io>
Link: https://lore.kernel.org/bpf/20221223094551.GA1439509@ubuntu
Fixes: ceb35b666d
("bpf/verifier: Use kmalloc_size_roundup() to match ksize() usage")
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: John Fastabend <john.fastabend@gmail.com>
Cc: Andrii Nakryiko <andrii@kernel.org>
Cc: Martin KaFai Lau <martin.lau@linux.dev>
Cc: Song Liu <song@kernel.org>
Cc: Yonghong Song <yhs@fb.com>
Cc: KP Singh <kpsingh@kernel.org>
Cc: Stanislav Fomichev <sdf@google.com>
Cc: Hao Luo <haoluo@google.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: bpf@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
Link: https://lore.kernel.org/r/20221223182836.never.866-kees@kernel.org
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
parent
f90dd663c4
commit
45435d8da7
1 changed files with 7 additions and 5 deletions
|
@ -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)
|
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;
|
size_t bytes;
|
||||||
|
|
||||||
if (ZERO_OR_NULL_PTR(src))
|
if (ZERO_OR_NULL_PTR(src))
|
||||||
|
@ -1062,10 +1064,10 @@ 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)))
|
if (unlikely(check_mul_overflow(n, size, &bytes)))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (ksize(dst) < ksize(src)) {
|
alloc_bytes = max(ksize(orig), kmalloc_size_roundup(bytes));
|
||||||
kfree(dst);
|
dst = krealloc(orig, alloc_bytes, flags);
|
||||||
dst = kmalloc_track_caller(kmalloc_size_roundup(bytes), flags);
|
if (!dst) {
|
||||||
if (!dst)
|
kfree(orig);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue