x86/cfi,bpf: Fix bpf_struct_ops CFI
BPF struct_ops uses __arch_prepare_bpf_trampoline() to write trampolines for indirect function calls. These tramplines much have matching CFI. In order to obtain the correct CFI hash for the various methods, add a matching structure that contains stub functions, the compiler will generate correct CFI which we can pilfer for the trampolines. Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://lore.kernel.org/r/20231215092707.566977112@infradead.org Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
committed by
Alexei Starovoitov
parent
e72d88d18d
commit
2cd3e3772e
@@ -352,17 +352,16 @@ const struct bpf_link_ops bpf_struct_ops_link_lops = {
|
||||
int bpf_struct_ops_prepare_trampoline(struct bpf_tramp_links *tlinks,
|
||||
struct bpf_tramp_link *link,
|
||||
const struct btf_func_model *model,
|
||||
void *image, void *image_end)
|
||||
void *stub_func, void *image, void *image_end)
|
||||
{
|
||||
u32 flags;
|
||||
u32 flags = BPF_TRAMP_F_INDIRECT;
|
||||
int size;
|
||||
|
||||
tlinks[BPF_TRAMP_FENTRY].links[0] = link;
|
||||
tlinks[BPF_TRAMP_FENTRY].nr_links = 1;
|
||||
/* BPF_TRAMP_F_RET_FENTRY_RET is only used by bpf_struct_ops,
|
||||
* and it must be used alone.
|
||||
*/
|
||||
flags = model->ret_size > 0 ? BPF_TRAMP_F_RET_FENTRY_RET : 0;
|
||||
|
||||
if (model->ret_size > 0)
|
||||
flags |= BPF_TRAMP_F_RET_FENTRY_RET;
|
||||
|
||||
size = arch_bpf_trampoline_size(model, flags, tlinks, NULL);
|
||||
if (size < 0)
|
||||
@@ -370,7 +369,7 @@ int bpf_struct_ops_prepare_trampoline(struct bpf_tramp_links *tlinks,
|
||||
if (size > (unsigned long)image_end - (unsigned long)image)
|
||||
return -E2BIG;
|
||||
return arch_prepare_bpf_trampoline(NULL, image, image_end,
|
||||
model, flags, tlinks, NULL);
|
||||
model, flags, tlinks, stub_func);
|
||||
}
|
||||
|
||||
static long bpf_struct_ops_map_update_elem(struct bpf_map *map, void *key,
|
||||
@@ -504,11 +503,12 @@ static long bpf_struct_ops_map_update_elem(struct bpf_map *map, void *key,
|
||||
|
||||
err = bpf_struct_ops_prepare_trampoline(tlinks, link,
|
||||
&st_ops->func_models[i],
|
||||
*(void **)(st_ops->cfi_stubs + moff),
|
||||
image, image_end);
|
||||
if (err < 0)
|
||||
goto reset_unlock;
|
||||
|
||||
*(void **)(kdata + moff) = image;
|
||||
*(void **)(kdata + moff) = image + cfi_get_offset();
|
||||
image += err;
|
||||
|
||||
/* put prog_id to udata */
|
||||
|
||||
Reference in New Issue
Block a user