1 | // SPDX-License-Identifier: GPL-2.0 |
2 | |
3 | #include "vmlinux.h" |
4 | #include <bpf/bpf_helpers.h> |
5 | #include "bpf_misc.h" |
6 | |
7 | char _license[] SEC("license" ) = "GPL" ; |
8 | |
9 | struct { |
10 | __uint(type, BPF_MAP_TYPE_HASH); |
11 | __uint(max_entries, 1); |
12 | __type(key, u64); |
13 | __type(value, u64); |
14 | } m_hash SEC(".maps" ); |
15 | |
16 | SEC("?raw_tp" ) |
17 | __failure __msg("R8 invalid mem access 'map_value_or_null" ) |
18 | int jeq_infer_not_null_ptr_to_btfid(void *ctx) |
19 | { |
20 | struct bpf_map *map = (struct bpf_map *)&m_hash; |
21 | struct bpf_map *inner_map = map->inner_map_meta; |
22 | u64 key = 0, ret = 0, *val; |
23 | |
24 | val = bpf_map_lookup_elem(map, &key); |
25 | /* Do not mark ptr as non-null if one of them is |
26 | * PTR_TO_BTF_ID (R9), reject because of invalid |
27 | * access to map value (R8). |
28 | * |
29 | * Here, we need to inline those insns to access |
30 | * R8 directly, since compiler may use other reg |
31 | * once it figures out val==inner_map. |
32 | */ |
33 | asm volatile("r8 = %[val];\n" |
34 | "r9 = %[inner_map];\n" |
35 | "if r8 != r9 goto +1;\n" |
36 | "%[ret] = *(u64 *)(r8 +0);\n" |
37 | : [ret] "+r" (ret) |
38 | : [inner_map] "r" (inner_map), [val] "r" (val) |
39 | : "r8" , "r9" ); |
40 | |
41 | return ret; |
42 | } |
43 | |