* [PATCH bpf-next v2 0/2] Relax allowlist for open-coded css_task iter
@ 2023-10-24 2:42 Chuyi Zhou
2023-10-24 2:42 ` [PATCH bpf-next v2 1/2] bpf: Relax allowlist for " Chuyi Zhou
2023-10-24 2:42 ` [PATCH bpf-next v2 2/2] selftests/bpf: Add test for css_task iter combining with cgroup iter Chuyi Zhou
0 siblings, 2 replies; 9+ messages in thread
From: Chuyi Zhou @ 2023-10-24 2:42 UTC (permalink / raw)
To: bpf; +Cc: ast, daniel, andrii, martin.lau, Chuyi Zhou
Hi,
The patchset aims to relax the allowlist for open-coded css_task iter
suggested by Alexei[1].
Please see individual patches for more details. And comments are always
welcome.
Patch summary:
* Patch #1: Relax the allowlist and let css_task iter can be used in
bpf iters and any sleepable progs.
* Patch #2: Add a test in cgroup_iters.c which demonstrates how
css_task iters can be combined with cgroup iter.
link[1]:https://lore.kernel.org/lkml/CAADnVQKafk_junRyE=-FVAik4hjTRDtThymYGEL8hGTuYoOGpA@mail.gmail.com/
---
Changes in v2:
* Fix the incorrect logic in check_css_task_iter_allowlist. Use
expected_attach_type to check whether we are using bpf_iters.
* Link to v1:https://lore.kernel.org/bpf/20231022154527.229117-1-zhouchuyi@bytedance.com/T/#m946f9cde86b44a13265d9a44c5738a711eb578fd
---
Chuyi Zhou (2):
bpf: Relax allowlist for css_task iter
selftests/bpf: Add test for css_task iter combining with cgroup iter
kernel/bpf/verifier.c | 21 ++++++----
.../selftests/bpf/prog_tests/cgroup_iter.c | 33 +++++++++++++++
.../selftests/bpf/progs/iters_css_task.c | 41 +++++++++++++++++++
.../selftests/bpf/progs/iters_task_failure.c | 4 +-
4 files changed, 89 insertions(+), 10 deletions(-)
--
2.20.1
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH bpf-next v2 1/2] bpf: Relax allowlist for css_task iter
2023-10-24 2:42 [PATCH bpf-next v2 0/2] Relax allowlist for open-coded css_task iter Chuyi Zhou
@ 2023-10-24 2:42 ` Chuyi Zhou
2023-10-24 4:57 ` Alexei Starovoitov
2023-10-24 2:42 ` [PATCH bpf-next v2 2/2] selftests/bpf: Add test for css_task iter combining with cgroup iter Chuyi Zhou
1 sibling, 1 reply; 9+ messages in thread
From: Chuyi Zhou @ 2023-10-24 2:42 UTC (permalink / raw)
To: bpf; +Cc: ast, daniel, andrii, martin.lau, Chuyi Zhou
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: 9c66dc94b62ae ("bpf: Introduce css_task open-coded iterator kfuncs")
Signed-off-by: Chuyi Zhou <zhouchuyi@bytedance.com>
---
kernel/bpf/verifier.c | 21 ++++++++++++-------
.../selftests/bpf/progs/iters_task_failure.c | 4 ++--
2 files changed, 15 insertions(+), 10 deletions(-)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index e9bc5d4a25a1..9f209adc4ccb 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -11088,18 +11088,23 @@ static int process_kf_arg_ptr_to_rbtree_node(struct bpf_verifier_env *env,
&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)
{
enum bpf_prog_type prog_type = resolve_prog_type(env->prog);
- switch (prog_type) {
- case BPF_PROG_TYPE_LSM:
+ if (prog_type == BPF_PROG_TYPE_LSM)
return true;
- case BPF_TRACE_ITER:
- return env->prog->aux->sleepable;
- default:
- return false;
- }
+
+ if (env->prog->expected_attach_type == BPF_TRACE_ITER)
+ return true;
+
+ return env->prog->aux->sleepable;
}
static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_kfunc_call_arg_meta *meta,
@@ -11357,7 +11362,7 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_kfunc_call_
case KF_ARG_PTR_TO_ITER:
if (meta->func_id == special_kfunc_list[KF_bpf_iter_css_task_new]) {
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;
}
}
diff --git a/tools/testing/selftests/bpf/progs/iters_task_failure.c b/tools/testing/selftests/bpf/progs/iters_task_failure.c
index c3bf96a67dba..6b1588d70652 100644
--- a/tools/testing/selftests/bpf/progs/iters_task_failure.c
+++ b/tools/testing/selftests/bpf/progs/iters_task_failure.c
@@ -84,8 +84,8 @@ int BPF_PROG(iter_css_lock_and_unlock)
return 0;
}
-SEC("?fentry.s/" SYS_PREFIX "sys_getpgid")
-__failure __msg("css_task_iter is only allowed in bpf_lsm and bpf iter-s")
+SEC("?fentry/" SYS_PREFIX "sys_getpgid")
+__failure __msg("css_task_iter is only allowed in bpf_lsm, bpf_iter and sleepable progs")
int BPF_PROG(iter_css_task_for_each)
{
u64 cg_id = bpf_get_current_cgroup_id();
--
2.20.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH bpf-next v2 2/2] selftests/bpf: Add test for css_task iter combining with cgroup iter
2023-10-24 2:42 [PATCH bpf-next v2 0/2] Relax allowlist for open-coded css_task iter Chuyi Zhou
2023-10-24 2:42 ` [PATCH bpf-next v2 1/2] bpf: Relax allowlist for " Chuyi Zhou
@ 2023-10-24 2:42 ` Chuyi Zhou
1 sibling, 0 replies; 9+ messages in thread
From: Chuyi Zhou @ 2023-10-24 2:42 UTC (permalink / raw)
To: bpf; +Cc: ast, daniel, andrii, martin.lau, Chuyi Zhou
This patch adds a test which demonstrates how css_task iter can be combined
with cgroup iter and it won't cause deadlock, though cgroup iter is not
sleepable.
Signed-off-by: Chuyi Zhou <zhouchuyi@bytedance.com>
---
.../selftests/bpf/prog_tests/cgroup_iter.c | 33 +++++++++++++++
.../selftests/bpf/progs/iters_css_task.c | 41 +++++++++++++++++++
2 files changed, 74 insertions(+)
diff --git a/tools/testing/selftests/bpf/prog_tests/cgroup_iter.c b/tools/testing/selftests/bpf/prog_tests/cgroup_iter.c
index e02feb5fae97..3679687a6927 100644
--- a/tools/testing/selftests/bpf/prog_tests/cgroup_iter.c
+++ b/tools/testing/selftests/bpf/prog_tests/cgroup_iter.c
@@ -4,6 +4,7 @@
#include <test_progs.h>
#include <bpf/libbpf.h>
#include <bpf/btf.h>
+#include "iters_css_task.skel.h"
#include "cgroup_iter.skel.h"
#include "cgroup_helpers.h"
@@ -263,6 +264,35 @@ static void test_walk_dead_self_only(struct cgroup_iter *skel)
close(cgrp_fd);
}
+static void test_walk_self_only_css_task(void)
+{
+ struct iters_css_task *skel = NULL;
+ int err;
+
+ skel = iters_css_task__open();
+ if (!ASSERT_OK_PTR(skel, "skel_open"))
+ return;
+
+ bpf_program__set_autoload(skel->progs.cgroup_id_printer, true);
+
+ err = iters_css_task__load(skel);
+ if (!ASSERT_OK(err, "skel_load"))
+ goto cleanup;
+
+ err = join_cgroup(cg_path[CHILD2]);
+ if (!ASSERT_OK(err, "join_cgroup"))
+ goto cleanup;
+
+ skel->bss->target_pid = getpid();
+ snprintf(expected_output, sizeof(expected_output),
+ PROLOGUE "%8llu\n" EPILOGUE, cg_id[CHILD2]);
+ read_from_cgroup_iter(skel->progs.cgroup_id_printer, cg_fd[CHILD2],
+ BPF_CGROUP_ITER_SELF_ONLY, "test_walk_self_only_css_task");
+ ASSERT_EQ(skel->bss->css_task_cnt, 1, "css_task_cnt");
+cleanup:
+ iters_css_task__destroy(skel);
+}
+
void test_cgroup_iter(void)
{
struct cgroup_iter *skel = NULL;
@@ -293,6 +323,9 @@ void test_cgroup_iter(void)
test_walk_self_only(skel);
if (test__start_subtest("cgroup_iter__dead_self_only"))
test_walk_dead_self_only(skel);
+ if (test__start_subtest("cgroup_iter__self_only_css_task"))
+ test_walk_self_only_css_task();
+
out:
cgroup_iter__destroy(skel);
cleanup_cgroups();
diff --git a/tools/testing/selftests/bpf/progs/iters_css_task.c b/tools/testing/selftests/bpf/progs/iters_css_task.c
index 5089ce384a1c..0974e6f44328 100644
--- a/tools/testing/selftests/bpf/progs/iters_css_task.c
+++ b/tools/testing/selftests/bpf/progs/iters_css_task.c
@@ -10,6 +10,7 @@
char _license[] SEC("license") = "GPL";
+struct cgroup *bpf_cgroup_acquire(struct cgroup *p) __ksym;
struct cgroup *bpf_cgroup_from_id(u64 cgid) __ksym;
void bpf_cgroup_release(struct cgroup *p) __ksym;
@@ -45,3 +46,43 @@ int BPF_PROG(iter_css_task_for_each, struct vm_area_struct *vma,
return -EPERM;
}
+
+static inline u64 cgroup_id(struct cgroup *cgrp)
+{
+ return cgrp->kn->id;
+}
+
+SEC("?iter/cgroup")
+int cgroup_id_printer(struct bpf_iter__cgroup *ctx)
+{
+ struct seq_file *seq = ctx->meta->seq;
+ struct cgroup *cgrp, *acquired;
+ struct cgroup_subsys_state *css;
+ struct task_struct *task;
+
+ cgrp = ctx->cgroup;
+
+ /* epilogue */
+ if (cgrp == NULL) {
+ BPF_SEQ_PRINTF(seq, "epilogue\n");
+ return 0;
+ }
+
+ /* prologue */
+ if (ctx->meta->seq_num == 0)
+ BPF_SEQ_PRINTF(seq, "prologue\n");
+
+ BPF_SEQ_PRINTF(seq, "%8llu\n", cgroup_id(cgrp));
+
+ acquired = bpf_cgroup_from_id(cgroup_id(cgrp));
+ if (!acquired)
+ return 0;
+ css = &acquired->self;
+ css_task_cnt = 0;
+ bpf_for_each(css_task, task, css, CSS_TASK_ITER_PROCS) {
+ if (task->pid == target_pid)
+ css_task_cnt++;
+ }
+ bpf_cgroup_release(acquired);
+ return 0;
+}
--
2.20.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH bpf-next v2 1/2] bpf: Relax allowlist for css_task iter
2023-10-24 2:42 ` [PATCH bpf-next v2 1/2] bpf: Relax allowlist for " Chuyi Zhou
@ 2023-10-24 4:57 ` Alexei Starovoitov
2023-10-24 5:52 ` Chuyi Zhou
0 siblings, 1 reply; 9+ messages in thread
From: Alexei Starovoitov @ 2023-10-24 4:57 UTC (permalink / raw)
To: Chuyi Zhou
Cc: bpf, Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Martin KaFai Lau
On Mon, Oct 23, 2023 at 7:42 PM Chuyi Zhou <zhouchuyi@bytedance.com> wrote:
>
> 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: 9c66dc94b62ae ("bpf: Introduce css_task open-coded iterator kfuncs")
> Signed-off-by: Chuyi Zhou <zhouchuyi@bytedance.com>
> ---
> kernel/bpf/verifier.c | 21 ++++++++++++-------
> .../selftests/bpf/progs/iters_task_failure.c | 4 ++--
> 2 files changed, 15 insertions(+), 10 deletions(-)
>
> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> index e9bc5d4a25a1..9f209adc4ccb 100644
> --- a/kernel/bpf/verifier.c
> +++ b/kernel/bpf/verifier.c
> @@ -11088,18 +11088,23 @@ static int process_kf_arg_ptr_to_rbtree_node(struct bpf_verifier_env *env,
> &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)
> {
> enum bpf_prog_type prog_type = resolve_prog_type(env->prog);
>
> - switch (prog_type) {
> - case BPF_PROG_TYPE_LSM:
> + if (prog_type == BPF_PROG_TYPE_LSM)
> return true;
> - case BPF_TRACE_ITER:
> - return env->prog->aux->sleepable;
> - default:
> - return false;
> - }
> +
> + if (env->prog->expected_attach_type == BPF_TRACE_ITER)
> + return true;
I think the switch by prog_type has to stay.
Checking attach_type == BPF_TRACE_ITER without considering prog_type
is fragile. It likely works, but we don't do it anywhere else.
Let's stick to what is known to work.
> -SEC("?fentry.s/" SYS_PREFIX "sys_getpgid")
> -__failure __msg("css_task_iter is only allowed in bpf_lsm and bpf iter-s")
> +SEC("?fentry/" SYS_PREFIX "sys_getpgid")
> +__failure __msg("css_task_iter is only allowed in bpf_lsm, bpf_iter and sleepable progs")
Please add both. fentry that is rejected and fentry.s that is accepted.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH bpf-next v2 1/2] bpf: Relax allowlist for css_task iter
2023-10-24 4:57 ` Alexei Starovoitov
@ 2023-10-24 5:52 ` Chuyi Zhou
2023-10-24 6:08 ` Yonghong Song
0 siblings, 1 reply; 9+ messages in thread
From: Chuyi Zhou @ 2023-10-24 5:52 UTC (permalink / raw)
To: Alexei Starovoitov
Cc: bpf, Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Martin KaFai Lau
Hello,
在 2023/10/24 12:57, Alexei Starovoitov 写道:
> On Mon, Oct 23, 2023 at 7:42 PM Chuyi Zhou <zhouchuyi@bytedance.com> wrote:
>>
>> 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: 9c66dc94b62ae ("bpf: Introduce css_task open-coded iterator kfuncs")
>> Signed-off-by: Chuyi Zhou <zhouchuyi@bytedance.com>
>> ---
>> kernel/bpf/verifier.c | 21 ++++++++++++-------
>> .../selftests/bpf/progs/iters_task_failure.c | 4 ++--
>> 2 files changed, 15 insertions(+), 10 deletions(-)
>>
>> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
>> index e9bc5d4a25a1..9f209adc4ccb 100644
>> --- a/kernel/bpf/verifier.c
>> +++ b/kernel/bpf/verifier.c
>> @@ -11088,18 +11088,23 @@ static int process_kf_arg_ptr_to_rbtree_node(struct bpf_verifier_env *env,
>> &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)
>> {
>> enum bpf_prog_type prog_type = resolve_prog_type(env->prog);
>>
>> - switch (prog_type) {
>> - case BPF_PROG_TYPE_LSM:
>> + if (prog_type == BPF_PROG_TYPE_LSM)
>> return true;
>> - case BPF_TRACE_ITER:
>> - return env->prog->aux->sleepable;
>> - default:
>> - return false;
>> - }
>> +
>> + if (env->prog->expected_attach_type == BPF_TRACE_ITER)
>> + return true;
>
> I think the switch by prog_type has to stay.
> Checking attach_type == BPF_TRACE_ITER without considering prog_type
> is fragile. It likely works, but we don't do it anywhere else.
> Let's stick to what is known to work.
>
IIUC, do you mean:
static bool check_css_task_iter_allowlist(struct bpf_verifier_env *env)
{
enum bpf_prog_type prog_type = resolve_prog_type(env->prog);
switch (prog_type) {
case BPF_PROG_TYPE_LSM:
return true;
case BPF_PROG_TYPE_TRACING:
if (env->prog->expected_attach_type == BPF_TRACE_ITER)
return true;
return env->prog->aux->sleepable;
default:
return env->prog->aux->sleepable;
}
}
>> -SEC("?fentry.s/" SYS_PREFIX "sys_getpgid")
>> -__failure __msg("css_task_iter is only allowed in bpf_lsm and bpf iter-s")
>> +SEC("?fentry/" SYS_PREFIX "sys_getpgid")
>> +__failure __msg("css_task_iter is only allowed in bpf_lsm, bpf_iter and sleepable progs")
>
> Please add both. fentry that is rejected and fentry.s that is accepted.
Sure.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH bpf-next v2 1/2] bpf: Relax allowlist for css_task iter
2023-10-24 5:52 ` Chuyi Zhou
@ 2023-10-24 6:08 ` Yonghong Song
2023-10-24 6:23 ` Chuyi Zhou
0 siblings, 1 reply; 9+ messages in thread
From: Yonghong Song @ 2023-10-24 6:08 UTC (permalink / raw)
To: Chuyi Zhou, Alexei Starovoitov
Cc: bpf, Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Martin KaFai Lau
On 10/23/23 10:52 PM, Chuyi Zhou wrote:
> Hello,
>
> 在 2023/10/24 12:57, Alexei Starovoitov 写道:
>> On Mon, Oct 23, 2023 at 7:42 PM Chuyi Zhou <zhouchuyi@bytedance.com>
>> wrote:
>>>
>>> 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: 9c66dc94b62ae ("bpf: Introduce css_task open-coded iterator
>>> kfuncs")
>>> Signed-off-by: Chuyi Zhou <zhouchuyi@bytedance.com>
>>> ---
>>> kernel/bpf/verifier.c | 21
>>> ++++++++++++-------
>>> .../selftests/bpf/progs/iters_task_failure.c | 4 ++--
>>> 2 files changed, 15 insertions(+), 10 deletions(-)
>>>
>>> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
>>> index e9bc5d4a25a1..9f209adc4ccb 100644
>>> --- a/kernel/bpf/verifier.c
>>> +++ b/kernel/bpf/verifier.c
>>> @@ -11088,18 +11088,23 @@ static int
>>> process_kf_arg_ptr_to_rbtree_node(struct bpf_verifier_env *env,
>>> &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)
>>> {
>>> enum bpf_prog_type prog_type = resolve_prog_type(env->prog);
>>>
>>> - switch (prog_type) {
>>> - case BPF_PROG_TYPE_LSM:
>>> + if (prog_type == BPF_PROG_TYPE_LSM)
>>> return true;
>>> - case BPF_TRACE_ITER:
>>> - return env->prog->aux->sleepable;
>>> - default:
>>> - return false;
>>> - }
>>> +
>>> + if (env->prog->expected_attach_type == BPF_TRACE_ITER)
>>> + return true;
>>
>> I think the switch by prog_type has to stay.
>> Checking attach_type == BPF_TRACE_ITER without considering prog_type
>> is fragile. It likely works, but we don't do it anywhere else.
>> Let's stick to what is known to work.
>>
>
> IIUC, do you mean:
>
> static bool check_css_task_iter_allowlist(struct bpf_verifier_env *env)
> {
> enum bpf_prog_type prog_type = resolve_prog_type(env->prog);
>
> switch (prog_type) {
> case BPF_PROG_TYPE_LSM:
> return true;
> case BPF_PROG_TYPE_TRACING:
> if (env->prog->expected_attach_type == BPF_TRACE_ITER)
> return true;
> return env->prog->aux->sleepable;
The above can be a fullthrough instead.
> default:
> return env->prog->aux->sleepable;
> }
> }
>
>>> -SEC("?fentry.s/" SYS_PREFIX "sys_getpgid")
>>> -__failure __msg("css_task_iter is only allowed in bpf_lsm and bpf
>>> iter-s")
>>> +SEC("?fentry/" SYS_PREFIX "sys_getpgid")
>>> +__failure __msg("css_task_iter is only allowed in bpf_lsm, bpf_iter
>>> and sleepable progs")
>>
>> Please add both. fentry that is rejected and fentry.s that is accepted.
>
> Sure.
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH bpf-next v2 1/2] bpf: Relax allowlist for css_task iter
2023-10-24 6:08 ` Yonghong Song
@ 2023-10-24 6:23 ` Chuyi Zhou
2023-10-24 11:43 ` Chuyi Zhou
0 siblings, 1 reply; 9+ messages in thread
From: Chuyi Zhou @ 2023-10-24 6:23 UTC (permalink / raw)
To: Yonghong Song, Alexei Starovoitov
Cc: bpf, Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Martin KaFai Lau
Hello,
在 2023/10/24 14:08, Yonghong Song 写道:
>
> On 10/23/23 10:52 PM, Chuyi Zhou wrote:
>> Hello,
>>
>> 在 2023/10/24 12:57, Alexei Starovoitov 写道:
>>> On Mon, Oct 23, 2023 at 7:42 PM Chuyi Zhou <zhouchuyi@bytedance.com>
>>> wrote:
>>>>
>>>> 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: 9c66dc94b62ae ("bpf: Introduce css_task open-coded iterator
>>>> kfuncs")
>>>> Signed-off-by: Chuyi Zhou <zhouchuyi@bytedance.com>
>>>> ---
>>>> kernel/bpf/verifier.c | 21
>>>> ++++++++++++-------
>>>> .../selftests/bpf/progs/iters_task_failure.c | 4 ++--
>>>> 2 files changed, 15 insertions(+), 10 deletions(-)
>>>>
>>>> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
>>>> index e9bc5d4a25a1..9f209adc4ccb 100644
>>>> --- a/kernel/bpf/verifier.c
>>>> +++ b/kernel/bpf/verifier.c
>>>> @@ -11088,18 +11088,23 @@ static int
>>>> process_kf_arg_ptr_to_rbtree_node(struct bpf_verifier_env *env,
>>>> &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)
>>>> {
>>>> enum bpf_prog_type prog_type = resolve_prog_type(env->prog);
>>>>
>>>> - switch (prog_type) {
>>>> - case BPF_PROG_TYPE_LSM:
>>>> + if (prog_type == BPF_PROG_TYPE_LSM)
>>>> return true;
>>>> - case BPF_TRACE_ITER:
>>>> - return env->prog->aux->sleepable;
>>>> - default:
>>>> - return false;
>>>> - }
>>>> +
>>>> + if (env->prog->expected_attach_type == BPF_TRACE_ITER)
>>>> + return true;
>>>
>>> I think the switch by prog_type has to stay.
>>> Checking attach_type == BPF_TRACE_ITER without considering prog_type
>>> is fragile. It likely works, but we don't do it anywhere else.
>>> Let's stick to what is known to work.
>>>
>>
>> IIUC, do you mean:
>>
>> static bool check_css_task_iter_allowlist(struct bpf_verifier_env *env)
>> {
>> enum bpf_prog_type prog_type = resolve_prog_type(env->prog);
>>
>> switch (prog_type) {
>> case BPF_PROG_TYPE_LSM:
>> return true;
>> case BPF_PROG_TYPE_TRACING:
>> if (env->prog->expected_attach_type == BPF_TRACE_ITER)
>> return true;
>> return env->prog->aux->sleepable;
>
>
> The above can be a fullthrough instead.
>
Sorry, what do you mean 'a fullthrough' ?
Do you mean we can check env->prog->aux->sleepable first and then fall
back to check prog/attach type ?
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH bpf-next v2 1/2] bpf: Relax allowlist for css_task iter
2023-10-24 6:23 ` Chuyi Zhou
@ 2023-10-24 11:43 ` Chuyi Zhou
2023-10-24 15:28 ` Yonghong Song
0 siblings, 1 reply; 9+ messages in thread
From: Chuyi Zhou @ 2023-10-24 11:43 UTC (permalink / raw)
To: Yonghong Song, Alexei Starovoitov
Cc: bpf, Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Martin KaFai Lau
在 2023/10/24 14:23, Chuyi Zhou 写道:
> Hello,
>
> 在 2023/10/24 14:08, Yonghong Song 写道:
>>
>> On 10/23/23 10:52 PM, Chuyi Zhou wrote:
>>> Hello,
>>>
>>> 在 2023/10/24 12:57, Alexei Starovoitov 写道:
>>>> On Mon, Oct 23, 2023 at 7:42 PM Chuyi Zhou <zhouchuyi@bytedance.com>
>>>> wrote:
>>>>>
>>>>> 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: 9c66dc94b62ae ("bpf: Introduce css_task open-coded iterator
>>>>> kfuncs")
>>>>> Signed-off-by: Chuyi Zhou <zhouchuyi@bytedance.com>
>>>>> ---
>>>>> kernel/bpf/verifier.c | 21
>>>>> ++++++++++++-------
>>>>> .../selftests/bpf/progs/iters_task_failure.c | 4 ++--
>>>>> 2 files changed, 15 insertions(+), 10 deletions(-)
>>>>>
>>>>> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
>>>>> index e9bc5d4a25a1..9f209adc4ccb 100644
>>>>> --- a/kernel/bpf/verifier.c
>>>>> +++ b/kernel/bpf/verifier.c
>>>>> @@ -11088,18 +11088,23 @@ static int
>>>>> process_kf_arg_ptr_to_rbtree_node(struct bpf_verifier_env *env,
>>>>> &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)
>>>>> {
>>>>> enum bpf_prog_type prog_type = resolve_prog_type(env->prog);
>>>>>
>>>>> - switch (prog_type) {
>>>>> - case BPF_PROG_TYPE_LSM:
>>>>> + if (prog_type == BPF_PROG_TYPE_LSM)
>>>>> return true;
>>>>> - case BPF_TRACE_ITER:
>>>>> - return env->prog->aux->sleepable;
>>>>> - default:
>>>>> - return false;
>>>>> - }
>>>>> +
>>>>> + if (env->prog->expected_attach_type == BPF_TRACE_ITER)
>>>>> + return true;
>>>>
>>>> I think the switch by prog_type has to stay.
>>>> Checking attach_type == BPF_TRACE_ITER without considering prog_type
>>>> is fragile. It likely works, but we don't do it anywhere else.
>>>> Let's stick to what is known to work.
>>>>
>>>
>>> IIUC, do you mean:
>>>
>>> static bool check_css_task_iter_allowlist(struct bpf_verifier_env *env)
>>> {
>>> enum bpf_prog_type prog_type = resolve_prog_type(env->prog);
>>>
>>> switch (prog_type) {
>>> case BPF_PROG_TYPE_LSM:
>>> return true;
>>> case BPF_PROG_TYPE_TRACING:
>>> if (env->prog->expected_attach_type == BPF_TRACE_ITER)
>>> return true;
>>> return env->prog->aux->sleepable;
>>
>>
>> The above can be a fullthrough instead.
>>
>
> Sorry, what do you mean 'a fullthrough' ?
> Do you mean we can check env->prog->aux->sleepable first and then fall
> back to check prog/attach type ?
>
I see...
Sorry for the above noise. I noticed verifier.c uses 'fallthrough' to
avoid the build warning, so we can:
static bool check_css_task_iter_allowlist(struct bpf_verifier_env *env)
{
enum bpf_prog_type prog_type = resolve_prog_type(env->prog);
switch (prog_type) {
case BPF_PROG_TYPE_LSM:
return true;
case BPF_PROG_TYPE_TRACING:
if (env->prog->expected_attach_type == BPF_TRACE_ITER)
return true;
fallthrough;
default:
return env->prog->aux->sleepable;
}
}
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH bpf-next v2 1/2] bpf: Relax allowlist for css_task iter
2023-10-24 11:43 ` Chuyi Zhou
@ 2023-10-24 15:28 ` Yonghong Song
0 siblings, 0 replies; 9+ messages in thread
From: Yonghong Song @ 2023-10-24 15:28 UTC (permalink / raw)
To: Chuyi Zhou, Alexei Starovoitov
Cc: bpf, Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Martin KaFai Lau
On 10/24/23 4:43 AM, Chuyi Zhou wrote:
>
>
> 在 2023/10/24 14:23, Chuyi Zhou 写道:
>> Hello,
>>
>> 在 2023/10/24 14:08, Yonghong Song 写道:
>>>
>>> On 10/23/23 10:52 PM, Chuyi Zhou wrote:
>>>> Hello,
>>>>
>>>> 在 2023/10/24 12:57, Alexei Starovoitov 写道:
>>>>> On Mon, Oct 23, 2023 at 7:42 PM Chuyi Zhou
>>>>> <zhouchuyi@bytedance.com> wrote:
>>>>>>
>>>>>> 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: 9c66dc94b62ae ("bpf: Introduce css_task open-coded
>>>>>> iterator kfuncs")
>>>>>> Signed-off-by: Chuyi Zhou <zhouchuyi@bytedance.com>
>>>>>> ---
>>>>>> kernel/bpf/verifier.c | 21
>>>>>> ++++++++++++-------
>>>>>> .../selftests/bpf/progs/iters_task_failure.c | 4 ++--
>>>>>> 2 files changed, 15 insertions(+), 10 deletions(-)
>>>>>>
>>>>>> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
>>>>>> index e9bc5d4a25a1..9f209adc4ccb 100644
>>>>>> --- a/kernel/bpf/verifier.c
>>>>>> +++ b/kernel/bpf/verifier.c
>>>>>> @@ -11088,18 +11088,23 @@ static int
>>>>>> process_kf_arg_ptr_to_rbtree_node(struct bpf_verifier_env *env,
>>>>>> &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)
>>>>>> {
>>>>>> enum bpf_prog_type prog_type =
>>>>>> resolve_prog_type(env->prog);
>>>>>>
>>>>>> - switch (prog_type) {
>>>>>> - case BPF_PROG_TYPE_LSM:
>>>>>> + if (prog_type == BPF_PROG_TYPE_LSM)
>>>>>> return true;
>>>>>> - case BPF_TRACE_ITER:
>>>>>> - return env->prog->aux->sleepable;
>>>>>> - default:
>>>>>> - return false;
>>>>>> - }
>>>>>> +
>>>>>> + if (env->prog->expected_attach_type == BPF_TRACE_ITER)
>>>>>> + return true;
>>>>>
>>>>> I think the switch by prog_type has to stay.
>>>>> Checking attach_type == BPF_TRACE_ITER without considering prog_type
>>>>> is fragile. It likely works, but we don't do it anywhere else.
>>>>> Let's stick to what is known to work.
>>>>>
>>>>
>>>> IIUC, do you mean:
>>>>
>>>> static bool check_css_task_iter_allowlist(struct bpf_verifier_env
>>>> *env)
>>>> {
>>>> enum bpf_prog_type prog_type = resolve_prog_type(env->prog);
>>>>
>>>> switch (prog_type) {
>>>> case BPF_PROG_TYPE_LSM:
>>>> return true;
>>>> case BPF_PROG_TYPE_TRACING:
>>>> if (env->prog->expected_attach_type == BPF_TRACE_ITER)
>>>> return true;
>>>> return env->prog->aux->sleepable;
>>>
>>>
>>> The above can be a fullthrough instead.
>>>
>>
>> Sorry, what do you mean 'a fullthrough' ?
>> Do you mean we can check env->prog->aux->sleepable first and then
>> fall back to check prog/attach type ?
>>
>
> I see...
>
> Sorry for the above noise. I noticed verifier.c uses 'fallthrough' to
> avoid the build warning, so we can:
>
> static bool check_css_task_iter_allowlist(struct bpf_verifier_env *env)
> {
> enum bpf_prog_type prog_type = resolve_prog_type(env->prog);
>
> switch (prog_type) {
> case BPF_PROG_TYPE_LSM:
> return true;
> case BPF_PROG_TYPE_TRACING:
> if (env->prog->expected_attach_type == BPF_TRACE_ITER)
> return true;
> fallthrough;
> default:
> return env->prog->aux->sleepable;
> }
> }
The above LGTM.
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2023-10-24 15:28 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-10-24 2:42 [PATCH bpf-next v2 0/2] Relax allowlist for open-coded css_task iter Chuyi Zhou
2023-10-24 2:42 ` [PATCH bpf-next v2 1/2] bpf: Relax allowlist for " Chuyi Zhou
2023-10-24 4:57 ` Alexei Starovoitov
2023-10-24 5:52 ` Chuyi Zhou
2023-10-24 6:08 ` Yonghong Song
2023-10-24 6:23 ` Chuyi Zhou
2023-10-24 11:43 ` Chuyi Zhou
2023-10-24 15:28 ` Yonghong Song
2023-10-24 2:42 ` [PATCH bpf-next v2 2/2] selftests/bpf: Add test for css_task iter combining with cgroup iter Chuyi Zhou
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).