Commit 3091b667 authored by Chuyi Zhou's avatar Chuyi Zhou Committed by Alexei Starovoitov

bpf: Relax allowlist for css_task iter

The newly added open-coded css_task iter would try to hold the global
css_set_lock in bpf_iter_css_task_new, so the bpf side has to be careful in
where it allows to use this iter. The mainly concern is dead locking on
css_set_lock. check_css_task_iter_allowlist() in verifier enforced css_task
can only be used in bpf_lsm hooks and sleepable bpf_iter.

This patch relax the allowlist for css_task iter. Any lsm and any iter
(even non-sleepable) and any sleepable are safe since they would not hold
the css_set_lock before entering BPF progs context.

This patch also fixes the misused BPF_TRACE_ITER in
check_css_task_iter_allowlist which compared bpf_prog_type with
bpf_attach_type.

Fixes: 9c66dc94 ("bpf: Introduce css_task open-coded iterator kfuncs")
Signed-off-by: default avatarChuyi Zhou <zhouchuyi@bytedance.com>
Acked-by: default avatarYonghong Song <yonghong.song@linux.dev>
Link: https://lore.kernel.org/r/20231031050438.93297-2-zhouchuyi@bytedance.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent 9af37759
...@@ -11402,6 +11402,12 @@ static int process_kf_arg_ptr_to_rbtree_node(struct bpf_verifier_env *env, ...@@ -11402,6 +11402,12 @@ static int process_kf_arg_ptr_to_rbtree_node(struct bpf_verifier_env *env,
&meta->arg_rbtree_root.field); &meta->arg_rbtree_root.field);
} }
/*
* css_task iter allowlist is needed to avoid dead locking on css_set_lock.
* LSM hooks and iters (both sleepable and non-sleepable) are safe.
* Any sleepable progs are also safe since bpf_check_attach_target() enforce
* them can only be attached to some specific hook points.
*/
static bool check_css_task_iter_allowlist(struct bpf_verifier_env *env) static bool check_css_task_iter_allowlist(struct bpf_verifier_env *env)
{ {
enum bpf_prog_type prog_type = resolve_prog_type(env->prog); enum bpf_prog_type prog_type = resolve_prog_type(env->prog);
...@@ -11409,10 +11415,12 @@ static bool check_css_task_iter_allowlist(struct bpf_verifier_env *env) ...@@ -11409,10 +11415,12 @@ static bool check_css_task_iter_allowlist(struct bpf_verifier_env *env)
switch (prog_type) { switch (prog_type) {
case BPF_PROG_TYPE_LSM: case BPF_PROG_TYPE_LSM:
return true; return true;
case BPF_TRACE_ITER: case BPF_PROG_TYPE_TRACING:
return env->prog->aux->sleepable; if (env->prog->expected_attach_type == BPF_TRACE_ITER)
return true;
fallthrough;
default: default:
return false; return env->prog->aux->sleepable;
} }
} }
...@@ -11671,7 +11679,7 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_kfunc_call_ ...@@ -11671,7 +11679,7 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_kfunc_call_
case KF_ARG_PTR_TO_ITER: case KF_ARG_PTR_TO_ITER:
if (meta->func_id == special_kfunc_list[KF_bpf_iter_css_task_new]) { if (meta->func_id == special_kfunc_list[KF_bpf_iter_css_task_new]) {
if (!check_css_task_iter_allowlist(env)) { if (!check_css_task_iter_allowlist(env)) {
verbose(env, "css_task_iter is only allowed in bpf_lsm and bpf iter-s\n"); verbose(env, "css_task_iter is only allowed in bpf_lsm, bpf_iter and sleepable progs\n");
return -EINVAL; return -EINVAL;
} }
} }
......
...@@ -84,8 +84,8 @@ int BPF_PROG(iter_css_lock_and_unlock) ...@@ -84,8 +84,8 @@ int BPF_PROG(iter_css_lock_and_unlock)
return 0; return 0;
} }
SEC("?fentry.s/" SYS_PREFIX "sys_getpgid") SEC("?fentry/" SYS_PREFIX "sys_getpgid")
__failure __msg("css_task_iter is only allowed in bpf_lsm and bpf iter-s") __failure __msg("css_task_iter is only allowed in bpf_lsm, bpf_iter and sleepable progs")
int BPF_PROG(iter_css_task_for_each) int BPF_PROG(iter_css_task_for_each)
{ {
u64 cg_id = bpf_get_current_cgroup_id(); u64 cg_id = bpf_get_current_cgroup_id();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment