Skip to content

Commit ff940af

Browse files
TropicaoKernel Patches Daemon
authored andcommitted
bpf/powerpc64: prevent trampoline attachment when args location on stack is uncertain
When the target function receives more arguments than available registers, the additional arguments are passed on stack, and so the generated trampoline needs to read those to prepare the bpf context, but also to prepare the target function stack when it is in charge of calling it. This works well for scalar types, but if the value is a struct, we can not know for sure the exact struct location, as it may have been packed or manually aligned to a greater value. Prevent wrong readings by refusing trampoline attachment if the target function receives a struct on stack. While at it, move the max bpf args check in the new function. Fixes: d243b62 ("powerpc64/bpf: Add support for bpf trampolines") Signed-off-by: Alexis Lothoré (eBPF Foundation) <[email protected]>
1 parent 012b78e commit ff940af

File tree

1 file changed

+25
-3
lines changed

1 file changed

+25
-3
lines changed

arch/powerpc/net/bpf_jit_comp.c

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,24 @@ static void bpf_trampoline_restore_args_stack(u32 *image, struct codegen_context
648648
bpf_trampoline_restore_args_regs(image, ctx, nr_regs, regs_off);
649649
}
650650

651+
static int validate_args(const struct btf_func_model *m)
652+
{
653+
int nr_regs = m->nr_args, i;
654+
655+
for (i = 0; i < m->nr_args; i++) {
656+
if (m->arg_size[i] > SZL)
657+
nr_regs += round_up(m->arg_size[i], SZL) / SZL - 1;
658+
if (i > MAX_REGS_FOR_ARGS &&
659+
m->arg_flags[i] & BTF_FMODEL_STRUCT_ARG)
660+
return -ENOTSUPP;
661+
}
662+
663+
if (nr_regs > MAX_BPF_FUNC_ARGS)
664+
return -ENOTSUPP;
665+
666+
return 0;
667+
}
668+
651669
static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_image,
652670
void *rw_image_end, void *ro_image,
653671
const struct btf_func_model *m, u32 flags,
@@ -668,15 +686,19 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im
668686
if (IS_ENABLED(CONFIG_PPC32))
669687
return -EOPNOTSUPP;
670688

689+
/* make sure that any argument can be located and processed by the
690+
* trampoline
691+
*/
692+
ret = validate_args(m);
693+
if (ret)
694+
return ret;
695+
671696
nr_regs = m->nr_args;
672697
/* Extra registers for struct arguments */
673698
for (i = 0; i < m->nr_args; i++)
674699
if (m->arg_size[i] > SZL)
675700
nr_regs += round_up(m->arg_size[i], SZL) / SZL - 1;
676701

677-
if (nr_regs > MAX_BPF_FUNC_ARGS)
678-
return -EOPNOTSUPP;
679-
680702
ctx = &codegen_ctx;
681703
memset(ctx, 0, sizeof(*ctx));
682704

0 commit comments

Comments
 (0)