mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-01 06:33:07 +00:00
3f00c52393
Kfuncs currently support specifying the KF_TRUSTED_ARGS flag to signal to the verifier that it should enforce that a BPF program passes it a "safe", trusted pointer. Currently, "safe" means that the pointer is either PTR_TO_CTX, or is refcounted. There may be cases, however, where the kernel passes a BPF program a safe / trusted pointer to an object that the BPF program wishes to use as a kptr, but because the object does not yet have a ref_obj_id from the perspective of the verifier, the program would be unable to pass it to a KF_ACQUIRE | KF_TRUSTED_ARGS kfunc. The solution is to expand the set of pointers that are considered trusted according to KF_TRUSTED_ARGS, so that programs can invoke kfuncs with these pointers without getting rejected by the verifier. There is already a PTR_UNTRUSTED flag that is set in some scenarios, such as when a BPF program reads a kptr directly from a map without performing a bpf_kptr_xchg() call. These pointers of course can and should be rejected by the verifier. Unfortunately, however, PTR_UNTRUSTED does not cover all the cases for safety that need to be addressed to adequately protect kfuncs. Specifically, pointers obtained by a BPF program "walking" a struct are _not_ considered PTR_UNTRUSTED according to BPF. For example, say that we were to add a kfunc called bpf_task_acquire(), with KF_ACQUIRE | KF_TRUSTED_ARGS, to acquire a struct task_struct *. If we only used PTR_UNTRUSTED to signal that a task was unsafe to pass to a kfunc, the verifier would mistakenly allow the following unsafe BPF program to be loaded: SEC("tp_btf/task_newtask") int BPF_PROG(unsafe_acquire_task, struct task_struct *task, u64 clone_flags) { struct task_struct *acquired, *nested; nested = task->last_wakee; /* Would not be rejected by the verifier. */ acquired = bpf_task_acquire(nested); if (!acquired) return 0; bpf_task_release(acquired); return 0; } To address this, this patch defines a new type flag called PTR_TRUSTED which tracks whether a PTR_TO_BTF_ID pointer is safe to pass to a KF_TRUSTED_ARGS kfunc or a BPF helper function. PTR_TRUSTED pointers are passed directly from the kernel as a tracepoint or struct_ops callback argument. Any nested pointer that is obtained from walking a PTR_TRUSTED pointer is no longer PTR_TRUSTED. From the example above, the struct task_struct *task argument is PTR_TRUSTED, but the 'nested' pointer obtained from 'task->last_wakee' is not PTR_TRUSTED. A subsequent patch will add kfuncs for storing a task kfunc as a kptr, and then another patch will add selftests to validate. Signed-off-by: David Vernet <void@manifault.com> Link: https://lore.kernel.org/r/20221120051004.3605026-3-void@manifault.com Signed-off-by: Alexei Starovoitov <ast@kernel.org> |
||
---|---|---|
.. | ||
libbpf | ||
bpf_design_QA.rst | ||
bpf_devel_QA.rst | ||
bpf_licensing.rst | ||
bpf_prog_run.rst | ||
btf.rst | ||
clang-notes.rst | ||
classic_vs_extended.rst | ||
drgn.rst | ||
faq.rst | ||
helpers.rst | ||
index.rst | ||
instruction-set.rst | ||
kfuncs.rst | ||
linux-notes.rst | ||
llvm_reloc.rst | ||
map_array.rst | ||
map_cgroup_storage.rst | ||
map_cgrp_storage.rst | ||
map_cpumap.rst | ||
map_devmap.rst | ||
map_hash.rst | ||
map_lpm_trie.rst | ||
map_of_maps.rst | ||
map_queue_stack.rst | ||
maps.rst | ||
other.rst | ||
prog_cgroup_sockopt.rst | ||
prog_cgroup_sysctl.rst | ||
prog_flow_dissector.rst | ||
prog_lsm.rst | ||
prog_sk_lookup.rst | ||
programs.rst | ||
redirect.rst | ||
ringbuf.rst | ||
s390.rst | ||
syscall_api.rst | ||
test_debug.rst | ||
verifier.rst |