Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

bpf: potential double-free of env->insn_aux_data

Function bpf_patch_insn_data() has the following structure:

static struct bpf_prog *bpf_patch_insn_data(... env ...)
{
struct bpf_prog *new_prog;
struct bpf_insn_aux_data *new_data = NULL;

if (len > 1) {
new_data = vrealloc(...); // <--------- (1)
if (!new_data)
return NULL;

env->insn_aux_data = new_data; // <---- (2)
}

new_prog = bpf_patch_insn_single(env->prog, off, patch, len);
if (IS_ERR(new_prog)) {
...
vfree(new_data); // <----------------- (3)
return NULL;
}
... happy path ...
}

In case if bpf_patch_insn_single() returns an error the `new_data`
allocated at (1) will be freed at (3). However, at (2) this pointer
is stored in `env->insn_aux_data`. Which is freed unconditionally
by verifier.c:bpf_check() on both happy and error paths.
Thus, leading to double-free.

Fix this by removing vfree() call at (3), ownership over `new_data` is
already passed to `env->insn_aux_data` at this point.

Fixes: 77620d126739 ("bpf: use realloc in bpf_patch_insn_data")
Reported-by: Chris Mason <clm@meta.com>
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/r/20250912-patch-insn-data-double-free-v1-1-af05bd85a21a@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Eduard Zingerman and committed by
Alexei Starovoitov
b13448dd 3ae4c527

-1
-1
kernel/bpf/verifier.c
··· 20800 20800 verbose(env, 20801 20801 "insn %d cannot be patched due to 16-bit range\n", 20802 20802 env->insn_aux_data[off].orig_idx); 20803 - vfree(new_data); 20804 20803 return NULL; 20805 20804 } 20806 20805 adjust_insn_aux_data(env, new_prog, off, len);