Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests/bpf: Add additional tests for bpf_lookup_*_key()

Add a test to ensure that bpf_lookup_user_key() creates a referenced
special keyring when the KEY_LOOKUP_CREATE flag is passed to this function.

Ensure that the kfunc rejects invalid flags.

Ensure that a keyring can be obtained from bpf_lookup_system_key() when one
of the pre-determined keyring IDs is provided.

The test is currently blacklisted for s390x (JIT does not support calling
kernel function).

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
Link: https://lore.kernel.org/r/20220920075951.929132-12-roberto.sassu@huaweicloud.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Roberto Sassu and committed by
Alexei Starovoitov
ecce368d 7c036ed9

+159
+1
tools/testing/selftests/bpf/DENYLIST.s390x
··· 72 72 htab_update # failed to attach: ERROR: strerror_r(-524)=22 (trampoline) 73 73 tracing_struct # failed to auto-attach: -524 (trampoline) 74 74 user_ringbuf # failed to find kernel BTF type ID of '__s390x_sys_prctl': -3 (?) 75 + lookup_key # JIT does not support calling kernel function (kfunc)
+112
tools/testing/selftests/bpf/prog_tests/lookup_key.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + /* 4 + * Copyright (C) 2022 Huawei Technologies Duesseldorf GmbH 5 + * 6 + * Author: Roberto Sassu <roberto.sassu@huawei.com> 7 + */ 8 + 9 + #include <linux/keyctl.h> 10 + #include <test_progs.h> 11 + 12 + #include "test_lookup_key.skel.h" 13 + 14 + #define KEY_LOOKUP_CREATE 0x01 15 + #define KEY_LOOKUP_PARTIAL 0x02 16 + 17 + static bool kfunc_not_supported; 18 + 19 + static int libbpf_print_cb(enum libbpf_print_level level, const char *fmt, 20 + va_list args) 21 + { 22 + char *func; 23 + 24 + if (strcmp(fmt, "libbpf: extern (func ksym) '%s': not found in kernel or module BTFs\n")) 25 + return 0; 26 + 27 + func = va_arg(args, char *); 28 + 29 + if (strcmp(func, "bpf_lookup_user_key") && strcmp(func, "bpf_key_put") && 30 + strcmp(func, "bpf_lookup_system_key")) 31 + return 0; 32 + 33 + kfunc_not_supported = true; 34 + return 0; 35 + } 36 + 37 + void test_lookup_key(void) 38 + { 39 + libbpf_print_fn_t old_print_cb; 40 + struct test_lookup_key *skel; 41 + __u32 next_id; 42 + int ret; 43 + 44 + skel = test_lookup_key__open(); 45 + if (!ASSERT_OK_PTR(skel, "test_lookup_key__open")) 46 + return; 47 + 48 + old_print_cb = libbpf_set_print(libbpf_print_cb); 49 + ret = test_lookup_key__load(skel); 50 + libbpf_set_print(old_print_cb); 51 + 52 + if (ret < 0 && kfunc_not_supported) { 53 + printf("%s:SKIP:bpf_lookup_*_key(), bpf_key_put() kfuncs not supported\n", 54 + __func__); 55 + test__skip(); 56 + goto close_prog; 57 + } 58 + 59 + if (!ASSERT_OK(ret, "test_lookup_key__load")) 60 + goto close_prog; 61 + 62 + ret = test_lookup_key__attach(skel); 63 + if (!ASSERT_OK(ret, "test_lookup_key__attach")) 64 + goto close_prog; 65 + 66 + skel->bss->monitored_pid = getpid(); 67 + skel->bss->key_serial = KEY_SPEC_THREAD_KEYRING; 68 + 69 + /* The thread-specific keyring does not exist, this test fails. */ 70 + skel->bss->flags = 0; 71 + 72 + ret = bpf_prog_get_next_id(0, &next_id); 73 + if (!ASSERT_LT(ret, 0, "bpf_prog_get_next_id")) 74 + goto close_prog; 75 + 76 + /* Force creation of the thread-specific keyring, this test succeeds. */ 77 + skel->bss->flags = KEY_LOOKUP_CREATE; 78 + 79 + ret = bpf_prog_get_next_id(0, &next_id); 80 + if (!ASSERT_OK(ret, "bpf_prog_get_next_id")) 81 + goto close_prog; 82 + 83 + /* Pass both lookup flags for parameter validation. */ 84 + skel->bss->flags = KEY_LOOKUP_CREATE | KEY_LOOKUP_PARTIAL; 85 + 86 + ret = bpf_prog_get_next_id(0, &next_id); 87 + if (!ASSERT_OK(ret, "bpf_prog_get_next_id")) 88 + goto close_prog; 89 + 90 + /* Pass invalid flags. */ 91 + skel->bss->flags = UINT64_MAX; 92 + 93 + ret = bpf_prog_get_next_id(0, &next_id); 94 + if (!ASSERT_LT(ret, 0, "bpf_prog_get_next_id")) 95 + goto close_prog; 96 + 97 + skel->bss->key_serial = 0; 98 + skel->bss->key_id = 1; 99 + 100 + ret = bpf_prog_get_next_id(0, &next_id); 101 + if (!ASSERT_OK(ret, "bpf_prog_get_next_id")) 102 + goto close_prog; 103 + 104 + skel->bss->key_id = UINT32_MAX; 105 + 106 + ret = bpf_prog_get_next_id(0, &next_id); 107 + ASSERT_LT(ret, 0, "bpf_prog_get_next_id"); 108 + 109 + close_prog: 110 + skel->bss->monitored_pid = 0; 111 + test_lookup_key__destroy(skel); 112 + }
+46
tools/testing/selftests/bpf/progs/test_lookup_key.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + /* 4 + * Copyright (C) 2022 Huawei Technologies Duesseldorf GmbH 5 + * 6 + * Author: Roberto Sassu <roberto.sassu@huawei.com> 7 + */ 8 + 9 + #include "vmlinux.h" 10 + #include <errno.h> 11 + #include <bpf/bpf_helpers.h> 12 + #include <bpf/bpf_tracing.h> 13 + 14 + char _license[] SEC("license") = "GPL"; 15 + 16 + __u32 monitored_pid; 17 + __u32 key_serial; 18 + __u32 key_id; 19 + __u64 flags; 20 + 21 + extern struct bpf_key *bpf_lookup_user_key(__u32 serial, __u64 flags) __ksym; 22 + extern struct bpf_key *bpf_lookup_system_key(__u64 id) __ksym; 23 + extern void bpf_key_put(struct bpf_key *key) __ksym; 24 + 25 + SEC("lsm.s/bpf") 26 + int BPF_PROG(bpf, int cmd, union bpf_attr *attr, unsigned int size) 27 + { 28 + struct bpf_key *bkey; 29 + __u32 pid; 30 + 31 + pid = bpf_get_current_pid_tgid() >> 32; 32 + if (pid != monitored_pid) 33 + return 0; 34 + 35 + if (key_serial) 36 + bkey = bpf_lookup_user_key(key_serial, flags); 37 + else 38 + bkey = bpf_lookup_system_key(key_id); 39 + 40 + if (!bkey) 41 + return -ENOENT; 42 + 43 + bpf_key_put(bkey); 44 + 45 + return 0; 46 + }