linux/kernel/bpf
Kumar Kartikeya Dwivedi 838a10bd2e bpf: Augment raw_tp arguments with PTR_MAYBE_NULL
Arguments to a raw tracepoint are tagged as trusted, which carries the
semantics that the pointer will be non-NULL.  However, in certain cases,
a raw tracepoint argument may end up being NULL. More context about this
issue is available in [0].

Thus, there is a discrepancy between the reality, that raw_tp arguments can
actually be NULL, and the verifier's knowledge, that they are never NULL,
causing explicit NULL check branch to be dead code eliminated.

A previous attempt [1], i.e. the second fixed commit, was made to
simulate symbolic execution as if in most accesses, the argument is a
non-NULL raw_tp, except for conditional jumps.  This tried to suppress
branch prediction while preserving compatibility, but surfaced issues
with production programs that were difficult to solve without increasing
verifier complexity. A more complete discussion of issues and fixes is
available at [2].

Fix this by maintaining an explicit list of tracepoints where the
arguments are known to be NULL, and mark the positional arguments as
PTR_MAYBE_NULL. Additionally, capture the tracepoints where arguments
are known to be ERR_PTR, and mark these arguments as scalar values to
prevent potential dereference.

Each hex digit is used to encode NULL-ness (0x1) or ERR_PTR-ness (0x2),
shifted by the zero-indexed argument number x 4. This can be represented
as follows:
1st arg: 0x1
2nd arg: 0x10
3rd arg: 0x100
... and so on (likewise for ERR_PTR case).

In the future, an automated pass will be used to produce such a list, or
insert __nullable annotations automatically for tracepoints. Each
compilation unit will be analyzed and results will be collated to find
whether a tracepoint pointer is definitely not null, maybe null, or an
unknown state where verifier conservatively marks it PTR_MAYBE_NULL.
A proof of concept of this tool from Eduard is available at [3].

Note that in case we don't find a specification in the raw_tp_null_args
array and the tracepoint belongs to a kernel module, we will
conservatively mark the arguments as PTR_MAYBE_NULL. This is because
unlike for in-tree modules, out-of-tree module tracepoints may pass NULL
freely to the tracepoint. We don't protect against such tracepoints
passing ERR_PTR (which is uncommon anyway), lest we mark all such
arguments as SCALAR_VALUE.

While we are it, let's adjust the test raw_tp_null to not perform
dereference of the skb->mark, as that won't be allowed anymore, and make
it more robust by using inline assembly to test the dead code
elimination behavior, which should still stay the same.

  [0]: https://lore.kernel.org/bpf/ZrCZS6nisraEqehw@jlelli-thinkpadt14gen4.remote.csb
  [1]: https://lore.kernel.org/all/20241104171959.2938862-1-memxor@gmail.com
  [2]: https://lore.kernel.org/bpf/20241206161053.809580-1-memxor@gmail.com
  [3]: https://github.com/eddyz87/llvm-project/tree/nullness-for-tracepoint-params

Reported-by: Juri Lelli <juri.lelli@redhat.com> # original bug
Reported-by: Manu Bretelle <chantra@meta.com> # bugs in masking fix
Fixes: 3f00c52393 ("bpf: Allow trusted pointers to be passed to KF_TRUSTED_ARGS kfuncs")
Fixes: cb4158ce8e ("bpf: Mark raw_tp arguments with PTR_MAYBE_NULL")
Reviewed-by: Eduard Zingerman <eddyz87@gmail.com>
Co-developed-by: Jiri Olsa <jolsa@kernel.org>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/r/20241213221929.3495062-3-memxor@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2024-12-13 16:24:53 -08:00
..
preload bpf: make preloaded map iterators to display map elements count 2023-07-06 12:42:25 -07:00
arena.c bpf: Do not alloc arena on unsupported arches 2024-11-15 08:10:13 -08:00
arraymap.c bpf: Prevent tailcall infinite loop caused by freplace 2024-10-16 09:21:18 -07:00
bloom_filter.c bpf: Check bloom filter map value size 2024-03-27 09:56:17 -07:00
bpf_cgrp_storage.c bpf: Add "bool swap_uptrs" arg to bpf_local_storage_update() and bpf_selem_alloc() 2024-10-24 10:25:59 -07:00
bpf_inode_storage.c bpf-next-bpf-next-6.13 2024-11-21 08:11:04 -08:00
bpf_iter.c [tree-wide] finally take no_llseek out 2024-09-27 08:18:43 -07:00
bpf_local_storage.c bpf: Add uptr support in the map_value of the task local storage. 2024-10-24 10:25:59 -07:00
bpf_lru_list.c bpf: Address KCSAN report on bpf_lru_list 2023-05-12 12:01:03 -07:00
bpf_lru_list.h bpf: lru: Remove unused declaration bpf_lru_promote() 2023-08-08 17:21:42 -07:00
bpf_lsm.c bpf, lsm: Remove getlsmprop hooks BTF IDs 2024-11-25 14:14:17 -08:00
bpf_struct_ops.c bpf: Add kernel symbol for struct_ops trampoline 2024-11-12 17:13:46 -08:00
bpf_task_storage.c bpf-next-bpf-next-6.13 2024-11-21 08:11:04 -08:00
btf.c bpf: Augment raw_tp arguments with PTR_MAYBE_NULL 2024-12-13 16:24:53 -08:00
btf_iter.c bpf: Remove custom build rule 2024-08-30 08:55:26 -07:00
btf_relocate.c bpf: Remove custom build rule 2024-08-30 08:55:26 -07:00
cgroup.c Summary 2024-11-22 20:36:11 -08:00
cgroup_iter.c bpf: Let verifier consider {task,cgroup} is trusted in bpf_iter_reg 2023-11-07 15:24:25 -08:00
core.c bpf: fix potential error return 2024-12-10 11:17:53 -08:00
cpumap.c bpf, cpumap: Move xdp:xdp_cpumap_kthread tracepoint before rcv 2024-09-11 16:32:11 +02:00
cpumask.c bpf: Allow invoking kfuncs from BPF_PROG_TYPE_SYSCALL progs 2024-04-05 10:56:09 -07:00
crypto.c bpf: crypto: make state and IV dynptr nullable 2024-06-13 16:33:04 -07:00
devmap.c bpf: fix OOB devmap writes when deleting elements 2024-11-25 14:25:48 -08:00
disasm.c bpf: add special internal-only MOV instruction to resolve per-CPU addrs 2024-04-03 10:29:55 -07:00
disasm.h
dispatcher.c bpf: Add kernel symbol for struct_ops trampoline 2024-11-12 17:13:46 -08:00
hashtab.c bpf: Call free_htab_elem() after htab_unlock_bucket() 2024-11-11 08:18:30 -08:00
helpers.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf 2024-11-13 12:52:51 -08:00
inode.c bpf: Preserve param->string when parsing mount options 2024-10-22 12:56:38 -07:00
Kconfig bpf: remove CONFIG_BPF_JIT dependency on CONFIG_MODULES of 2024-05-14 00:36:29 -07:00
kmem_cache_iter.c bpf: Add open coded version of kmem_cache iterator 2024-11-01 11:08:32 -07:00
link_iter.c
local_storage.c bpf: Replace 8 seq_puts() calls by seq_putc() calls 2024-07-29 12:53:00 -07:00
log.c bpf: Fix print_reg_state's constant scalar dump 2024-10-17 11:06:34 -07:00
lpm_trie.c bpf: Use raw_spinlock_t for LPM trie 2024-12-06 09:14:26 -08:00
Makefile bpf: Introduce range_tree data structure and use it in bpf arena 2024-11-13 13:52:45 -08:00
map_in_map.c bpf: switch maps to CLASS(fd, ...) 2024-08-13 15:58:17 -07:00
map_in_map.h bpf: Add map and need_defer parameters to .map_fd_put_ptr() 2023-12-04 17:50:26 -08:00
map_iter.c bpf: treewide: Annotate BPF kfuncs in BTF 2024-01-31 20:40:56 -08:00
memalloc.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf 2024-11-13 12:52:51 -08:00
mmap_unlock_work.h
mprog.c bpf: Handle bpf_mprog_query with NULL entry 2023-10-06 17:11:20 -07:00
net_namespace.c
offload.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net 2023-09-21 21:49:45 +02:00
percpu_freelist.c
percpu_freelist.h
prog_iter.c
queue_stack_maps.c bpf: Avoid deadlock when using queue and stack maps from NMI 2023-09-11 19:04:49 -07:00
range_tree.c bpf: Add necessary migrate_disable to range_tree. 2024-11-15 08:11:53 -08:00
range_tree.h bpf: Introduce range_tree data structure and use it in bpf arena 2024-11-13 13:52:45 -08:00
relo_core.c bpf: Remove custom build rule 2024-08-30 08:55:26 -07:00
reuseport_array.c bpf: Use sockfd_put() helper 2024-08-30 08:57:47 -07:00
ringbuf.c bpf: Add MEM_WRITE attribute 2024-10-22 15:42:56 -07:00
stackmap.c bpf: wire up sleepable bpf_get_stack() and bpf_get_task_stack() helpers 2024-09-11 09:58:31 -07:00
syscall.c tracing updates for v6.13: 2024-11-22 13:27:01 -08:00
sysfs_btf.c btf: Avoid weak external references 2024-04-16 16:35:13 +02:00
task_iter.c vfs-6.13.file 2024-11-18 10:30:29 -08:00
tcx.c bpf, tcx: Get rid of tcx_link_const 2023-10-23 15:01:53 -07:00
tnum.c bpf: simplify tnum output if a fully known constant 2023-12-02 11:36:51 -08:00
token.c remove pointless includes of <linux/fdtable.h> 2024-10-07 13:34:41 -04:00
trampoline.c bpf: Add kernel symbol for struct_ops trampoline 2024-11-12 17:13:46 -08:00
verifier.c bpf: Revert "bpf: Mark raw_tp arguments with PTR_MAYBE_NULL" 2024-12-13 16:24:53 -08:00