mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-22 02:17:36 -04:00
bpf: Move sleepable verification code to btf_id_allow_sleepable
Move sleepable verification code to btf_id_allow_sleepable function. It will be used in following changes. Adding code to retrieve type's name instead of passing it from bpf_check_attach_target function, because this function will be called from another place in following changes and it's easier to retrieve the name directly in here. Signed-off-by: Jiri Olsa <jolsa@kernel.org> Link: https://lore.kernel.org/r/20260606123955.345967-12-jolsa@kernel.org Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
committed by
Alexei Starovoitov
parent
d14e6b4346
commit
bd06659d3b
@@ -18779,6 +18779,55 @@ static bool is_tracing_multi_id(const struct bpf_prog *prog, u32 btf_id)
|
||||
return is_tracing_multi(prog->expected_attach_type) && bpf_multi_func_btf_id[0] == btf_id;
|
||||
}
|
||||
|
||||
static int btf_id_allow_sleepable(u32 btf_id, unsigned long addr, const struct bpf_prog *prog,
|
||||
const struct btf *btf)
|
||||
{
|
||||
const struct btf_type *t;
|
||||
const char *tname;
|
||||
|
||||
switch (prog->type) {
|
||||
case BPF_PROG_TYPE_TRACING:
|
||||
t = btf_type_by_id(btf, btf_id);
|
||||
if (!t)
|
||||
return -EINVAL;
|
||||
tname = btf_name_by_offset(btf, t->name_off);
|
||||
if (!tname)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* *.multi sleepable programs will pass initial sleepable check,
|
||||
* the actual attached btf ids are checked later during the link
|
||||
* attachment.
|
||||
*/
|
||||
if (is_tracing_multi_id(prog, btf_id))
|
||||
return 0;
|
||||
if (!check_attach_sleepable(btf_id, addr, tname))
|
||||
return 0;
|
||||
/*
|
||||
* fentry/fexit/fmod_ret progs can also be sleepable if they are
|
||||
* in the fmodret id set with the KF_SLEEPABLE flag.
|
||||
*/
|
||||
else {
|
||||
u32 *flags = btf_kfunc_is_modify_return(btf, btf_id, prog);
|
||||
|
||||
if (flags && (*flags & KF_SLEEPABLE))
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case BPF_PROG_TYPE_LSM:
|
||||
/*
|
||||
* LSM progs check that they are attached to bpf_lsm_*() funcs.
|
||||
* Only some of them are sleepable.
|
||||
*/
|
||||
if (bpf_lsm_is_sleepable_hook(btf_id))
|
||||
return 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int bpf_check_attach_target(struct bpf_verifier_log *log,
|
||||
const struct bpf_prog *prog,
|
||||
const struct bpf_prog *tgt_prog,
|
||||
@@ -19076,38 +19125,7 @@ int bpf_check_attach_target(struct bpf_verifier_log *log,
|
||||
}
|
||||
|
||||
if (prog->sleepable) {
|
||||
ret = -EINVAL;
|
||||
switch (prog->type) {
|
||||
case BPF_PROG_TYPE_TRACING:
|
||||
/* *.multi sleepable programs will pass initial sleepable check,
|
||||
* the actual attached btf ids are checked later during the link
|
||||
* attachment.
|
||||
*/
|
||||
if (is_tracing_multi_id(prog, btf_id))
|
||||
ret = 0;
|
||||
if (!check_attach_sleepable(btf_id, addr, tname))
|
||||
ret = 0;
|
||||
/* fentry/fexit/fmod_ret progs can also be sleepable if they are
|
||||
* in the fmodret id set with the KF_SLEEPABLE flag.
|
||||
*/
|
||||
else {
|
||||
u32 *flags = btf_kfunc_is_modify_return(btf, btf_id,
|
||||
prog);
|
||||
|
||||
if (flags && (*flags & KF_SLEEPABLE))
|
||||
ret = 0;
|
||||
}
|
||||
break;
|
||||
case BPF_PROG_TYPE_LSM:
|
||||
/* LSM progs check that they are attached to bpf_lsm_*() funcs.
|
||||
* Only some of them are sleepable.
|
||||
*/
|
||||
if (bpf_lsm_is_sleepable_hook(btf_id))
|
||||
ret = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ret = btf_id_allow_sleepable(btf_id, addr, prog, btf);
|
||||
if (ret) {
|
||||
module_put(mod);
|
||||
bpf_log(log, "%s is not sleepable\n", tname);
|
||||
|
||||
Reference in New Issue
Block a user