1 // SPDX-License-Identifier: GPL-2.0 2 #include <test_progs.h> 3 #include <bpf/btf.h> 4 5 /* 6 * A hash map with a key-less BTF (btf_key_type_id == 0) used to be accepted 7 * and then NULL-deref in btf_type_show() when dumped through bpffs. A fixed 8 * kernel rejects it at creation; verify that rejection, with a keyed positive 9 * control so the -EINVAL is about the missing key type and not some unrelated 10 * failure. 11 */ 12 static void check_keyless(int map_type, __u32 map_flags, int btf_fd, int val_id) 13 { 14 LIBBPF_OPTS(bpf_map_create_opts, opts); 15 int map_fd; 16 17 opts.map_flags = map_flags; 18 opts.btf_fd = btf_fd; 19 opts.btf_value_type_id = val_id; 20 21 /* Positive control: the same map with a real key type is accepted. */ 22 opts.btf_key_type_id = val_id; 23 map_fd = bpf_map_create(map_type, "keyed_map", 4, 4, 8, &opts); 24 if (!ASSERT_GE(map_fd, 0, "keyed create is accepted")) 25 return; 26 close(map_fd); 27 28 /* A key-less BTF must be rejected. */ 29 opts.btf_key_type_id = 0; 30 map_fd = bpf_map_create(map_type, "keyless_map", 4, 4, 8, &opts); 31 ASSERT_EQ(map_fd, -EINVAL, "key-less create is rejected"); 32 if (map_fd >= 0) 33 close(map_fd); 34 } 35 36 void test_btf_map_keyless(void) 37 { 38 int btf_fd, val_id; 39 struct btf *btf; 40 41 btf = btf__new_empty(); 42 if (!ASSERT_OK_PTR(btf, "btf__new_empty")) 43 return; 44 45 val_id = btf__add_int(btf, "int", 4, BTF_INT_SIGNED); 46 if (!ASSERT_GT(val_id, 0, "btf__add_int")) 47 goto out; 48 49 if (!ASSERT_OK(btf__load_into_kernel(btf), "btf__load_into_kernel")) 50 goto out; 51 btf_fd = btf__fd(btf); 52 53 if (test__start_subtest("hash")) 54 check_keyless(BPF_MAP_TYPE_HASH, 0, btf_fd, val_id); 55 if (test__start_subtest("rhash")) 56 check_keyless(BPF_MAP_TYPE_RHASH, BPF_F_NO_PREALLOC, btf_fd, val_id); 57 out: 58 btf__free(btf); 59 } 60