Skip to content

Commit 1a86ae5

Browse files
mrpregregkh
authored andcommitted
bpf: Fix array bounds error with may_goto
[ Upstream commit 6ebc503 ] may_goto uses an additional 8 bytes on the stack, which causes the interpreters[] array to go out of bounds when calculating index by stack_size. 1. If a BPF program is rewritten, re-evaluate the stack size. For non-JIT cases, reject loading directly. 2. For non-JIT cases, calculating interpreters[idx] may still cause out-of-bounds array access, and just warn about it. 3. For jit_requested cases, the execution of bpf_func also needs to be warned. So move the definition of function __bpf_prog_ret0_warn out of the macro definition CONFIG_BPF_JIT_ALWAYS_ON. Reported-by: [email protected] Closes: https://lore.kernel.org/bpf/[email protected]/ Fixes: 011832b ("bpf: Introduce may_goto instruction") Signed-off-by: Jiayuan Chen <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent 409160e commit 1a86ae5

File tree

2 files changed

+22
-4
lines changed

2 files changed

+22
-4
lines changed

kernel/bpf/core.c

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2290,17 +2290,18 @@ void bpf_patch_call_args(struct bpf_insn *insn, u32 stack_depth)
22902290
insn->code = BPF_JMP | BPF_CALL_ARGS;
22912291
}
22922292
#endif
2293-
#else
2293+
#endif
2294+
22942295
static unsigned int __bpf_prog_ret0_warn(const void *ctx,
22952296
const struct bpf_insn *insn)
22962297
{
22972298
/* If this handler ever gets executed, then BPF_JIT_ALWAYS_ON
2298-
* is not working properly, so warn about it!
2299+
* is not working properly, or interpreter is being used when
2300+
* prog->jit_requested is not 0, so warn about it!
22992301
*/
23002302
WARN_ON_ONCE(1);
23012303
return 0;
23022304
}
2303-
#endif
23042305

23052306
bool bpf_prog_map_compatible(struct bpf_map *map,
23062307
const struct bpf_prog *fp)
@@ -2380,8 +2381,18 @@ static void bpf_prog_select_func(struct bpf_prog *fp)
23802381
{
23812382
#ifndef CONFIG_BPF_JIT_ALWAYS_ON
23822383
u32 stack_depth = max_t(u32, fp->aux->stack_depth, 1);
2384+
u32 idx = (round_up(stack_depth, 32) / 32) - 1;
23832385

2384-
fp->bpf_func = interpreters[(round_up(stack_depth, 32) / 32) - 1];
2386+
/* may_goto may cause stack size > 512, leading to idx out-of-bounds.
2387+
* But for non-JITed programs, we don't need bpf_func, so no bounds
2388+
* check needed.
2389+
*/
2390+
if (!fp->jit_requested &&
2391+
!WARN_ON_ONCE(idx >= ARRAY_SIZE(interpreters))) {
2392+
fp->bpf_func = interpreters[idx];
2393+
} else {
2394+
fp->bpf_func = __bpf_prog_ret0_warn;
2395+
}
23852396
#else
23862397
fp->bpf_func = __bpf_prog_ret0_warn;
23872398
#endif

kernel/bpf/verifier.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21897,6 +21897,13 @@ static int do_misc_fixups(struct bpf_verifier_env *env)
2189721897
if (subprogs[cur_subprog + 1].start == i + delta + 1) {
2189821898
subprogs[cur_subprog].stack_depth += stack_depth_extra;
2189921899
subprogs[cur_subprog].stack_extra = stack_depth_extra;
21900+
21901+
stack_depth = subprogs[cur_subprog].stack_depth;
21902+
if (stack_depth > MAX_BPF_STACK && !prog->jit_requested) {
21903+
verbose(env, "stack size %d(extra %d) is too large\n",
21904+
stack_depth, stack_depth_extra);
21905+
return -EINVAL;
21906+
}
2190021907
cur_subprog++;
2190121908
stack_depth = subprogs[cur_subprog].stack_depth;
2190221909
stack_depth_extra = 0;

0 commit comments

Comments
 (0)