summaryrefslogtreecommitdiffstats
path: root/kernel/bpf
diff options
context:
space:
mode:
authorAlexei Starovoitov <ast@kernel.org>2023-03-02 20:14:42 -0800
committerDaniel Borkmann <daniel@iogearbox.net>2023-03-03 17:42:20 +0100
commit8d093b4e95a2a16a2cfcd36869b348a17112fabe (patch)
tree76ee3f72594b752b3e289117a586312d1e50f051 /kernel/bpf
parent03b77e17aeb22a5935ea20d585ca6a1f2947e62b (diff)
downloadlinux-stable-8d093b4e95a2a16a2cfcd36869b348a17112fabe.tar.gz
linux-stable-8d093b4e95a2a16a2cfcd36869b348a17112fabe.tar.bz2
linux-stable-8d093b4e95a2a16a2cfcd36869b348a17112fabe.zip
bpf: Mark cgroups and dfl_cgrp fields as trusted.
bpf programs sometimes do: bpf_cgrp_storage_get(&map, task->cgroups->dfl_cgrp, ...); It is safe to do, because cgroups->dfl_cgrp pointer is set diring init and never changes. The task->cgroups is also never NULL. It is also set during init and will change when task switches cgroups. For any trusted task pointer dereference of cgroups and dfl_cgrp should yield trusted pointers. The verifier wasn't aware of this. Hence in gcc compiled kernels task->cgroups dereference was producing PTR_TO_BTF_ID without modifiers while in clang compiled kernels the verifier recognizes __rcu tag in cgroups field and produces PTR_TO_BTF_ID | MEM_RCU | MAYBE_NULL. Tag cgroups and dfl_cgrp as trusted to equalize clang and gcc behavior. When GCC supports btf_type_tag such tagging will done directly in the type. Signed-off-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Acked-by: David Vernet <void@manifault.com> Acked-by: Tejun Heo <tj@kernel.org> Link: https://lore.kernel.org/bpf/20230303041446.3630-3-alexei.starovoitov@gmail.com
Diffstat (limited to 'kernel/bpf')
-rw-r--r--kernel/bpf/verifier.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index bf580f246a01..b834f3d2d81a 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -5046,6 +5046,11 @@ static int bpf_map_direct_read(struct bpf_map *map, int off, int size, u64 *val)
BTF_TYPE_SAFE_NESTED(struct task_struct) {
const cpumask_t *cpus_ptr;
+ struct css_set __rcu *cgroups;
+};
+
+BTF_TYPE_SAFE_NESTED(struct css_set) {
+ struct cgroup *dfl_cgrp;
};
static bool nested_ptr_is_trusted(struct bpf_verifier_env *env,
@@ -5057,6 +5062,7 @@ static bool nested_ptr_is_trusted(struct bpf_verifier_env *env,
return false;
BTF_TYPE_EMIT(BTF_TYPE_SAFE_NESTED(struct task_struct));
+ BTF_TYPE_EMIT(BTF_TYPE_SAFE_NESTED(struct css_set));
return btf_nested_type_is_trusted(&env->log, reg, off);
}