bpf: Do not allow to load sleepable BPF_TRACE_RAW_TP program
authorJiri Olsa <jolsa@kernel.org>
Tue, 17 Jan 2023 22:37:04 +0000 (23:37 +0100)
committerAlexei Starovoitov <ast@kernel.org>
Wed, 18 Jan 2023 00:56:04 +0000 (16:56 -0800)
Currently we allow to load any tracing program as sleepable,
but BPF_TRACE_RAW_TP can't sleep. Making the check explicit
for tracing programs attach types, so sleepable BPF_TRACE_RAW_TP
will fail to load.

Updating the verifier error to mention iter programs as well.

Acked-by: Song Liu <song@kernel.org>
Acked-by: Yonghong Song <yhs@fb.com>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Link: https://lore.kernel.org/r/20230117223705.440975-1-jolsa@kernel.org
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
kernel/bpf/verifier.c

index fa4c911603e90a5558a9d15e2fb84044e36dba5c..ca7db2ce70b94d94ffdce521168b2f1f99b0be2a 100644 (file)
@@ -16743,6 +16743,23 @@ BTF_ID(func, rcu_read_unlock_strict)
 #endif
 BTF_SET_END(btf_id_deny)
 
+static bool can_be_sleepable(struct bpf_prog *prog)
+{
+       if (prog->type == BPF_PROG_TYPE_TRACING) {
+               switch (prog->expected_attach_type) {
+               case BPF_TRACE_FENTRY:
+               case BPF_TRACE_FEXIT:
+               case BPF_MODIFY_RETURN:
+               case BPF_TRACE_ITER:
+                       return true;
+               default:
+                       return false;
+               }
+       }
+       return prog->type == BPF_PROG_TYPE_LSM ||
+              prog->type == BPF_PROG_TYPE_KPROBE; /* only for uprobes */
+}
+
 static int check_attach_btf_id(struct bpf_verifier_env *env)
 {
        struct bpf_prog *prog = env->prog;
@@ -16761,9 +16778,8 @@ static int check_attach_btf_id(struct bpf_verifier_env *env)
                return -EINVAL;
        }
 
-       if (prog->aux->sleepable && prog->type != BPF_PROG_TYPE_TRACING &&
-           prog->type != BPF_PROG_TYPE_LSM && prog->type != BPF_PROG_TYPE_KPROBE) {
-               verbose(env, "Only fentry/fexit/fmod_ret, lsm, and kprobe/uprobe programs can be sleepable\n");
+       if (prog->aux->sleepable && !can_be_sleepable(prog)) {
+               verbose(env, "Only fentry/fexit/fmod_ret, lsm, iter and uprobe programs can be sleepable\n");
                return -EINVAL;
        }