-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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>
- Loading branch information
Roberto Sassu
authored and
Alexei Starovoitov
committed
Sep 22, 2022
1 parent
7c036ed
commit ecce368
Showing
3 changed files
with
159 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
|
||
/* | ||
* Copyright (C) 2022 Huawei Technologies Duesseldorf GmbH | ||
* | ||
* Author: Roberto Sassu <roberto.sassu@huawei.com> | ||
*/ | ||
|
||
#include <linux/keyctl.h> | ||
#include <test_progs.h> | ||
|
||
#include "test_lookup_key.skel.h" | ||
|
||
#define KEY_LOOKUP_CREATE 0x01 | ||
#define KEY_LOOKUP_PARTIAL 0x02 | ||
|
||
static bool kfunc_not_supported; | ||
|
||
static int libbpf_print_cb(enum libbpf_print_level level, const char *fmt, | ||
va_list args) | ||
{ | ||
char *func; | ||
|
||
if (strcmp(fmt, "libbpf: extern (func ksym) '%s': not found in kernel or module BTFs\n")) | ||
return 0; | ||
|
||
func = va_arg(args, char *); | ||
|
||
if (strcmp(func, "bpf_lookup_user_key") && strcmp(func, "bpf_key_put") && | ||
strcmp(func, "bpf_lookup_system_key")) | ||
return 0; | ||
|
||
kfunc_not_supported = true; | ||
return 0; | ||
} | ||
|
||
void test_lookup_key(void) | ||
{ | ||
libbpf_print_fn_t old_print_cb; | ||
struct test_lookup_key *skel; | ||
__u32 next_id; | ||
int ret; | ||
|
||
skel = test_lookup_key__open(); | ||
if (!ASSERT_OK_PTR(skel, "test_lookup_key__open")) | ||
return; | ||
|
||
old_print_cb = libbpf_set_print(libbpf_print_cb); | ||
ret = test_lookup_key__load(skel); | ||
libbpf_set_print(old_print_cb); | ||
|
||
if (ret < 0 && kfunc_not_supported) { | ||
printf("%s:SKIP:bpf_lookup_*_key(), bpf_key_put() kfuncs not supported\n", | ||
__func__); | ||
test__skip(); | ||
goto close_prog; | ||
} | ||
|
||
if (!ASSERT_OK(ret, "test_lookup_key__load")) | ||
goto close_prog; | ||
|
||
ret = test_lookup_key__attach(skel); | ||
if (!ASSERT_OK(ret, "test_lookup_key__attach")) | ||
goto close_prog; | ||
|
||
skel->bss->monitored_pid = getpid(); | ||
skel->bss->key_serial = KEY_SPEC_THREAD_KEYRING; | ||
|
||
/* The thread-specific keyring does not exist, this test fails. */ | ||
skel->bss->flags = 0; | ||
|
||
ret = bpf_prog_get_next_id(0, &next_id); | ||
if (!ASSERT_LT(ret, 0, "bpf_prog_get_next_id")) | ||
goto close_prog; | ||
|
||
/* Force creation of the thread-specific keyring, this test succeeds. */ | ||
skel->bss->flags = KEY_LOOKUP_CREATE; | ||
|
||
ret = bpf_prog_get_next_id(0, &next_id); | ||
if (!ASSERT_OK(ret, "bpf_prog_get_next_id")) | ||
goto close_prog; | ||
|
||
/* Pass both lookup flags for parameter validation. */ | ||
skel->bss->flags = KEY_LOOKUP_CREATE | KEY_LOOKUP_PARTIAL; | ||
|
||
ret = bpf_prog_get_next_id(0, &next_id); | ||
if (!ASSERT_OK(ret, "bpf_prog_get_next_id")) | ||
goto close_prog; | ||
|
||
/* Pass invalid flags. */ | ||
skel->bss->flags = UINT64_MAX; | ||
|
||
ret = bpf_prog_get_next_id(0, &next_id); | ||
if (!ASSERT_LT(ret, 0, "bpf_prog_get_next_id")) | ||
goto close_prog; | ||
|
||
skel->bss->key_serial = 0; | ||
skel->bss->key_id = 1; | ||
|
||
ret = bpf_prog_get_next_id(0, &next_id); | ||
if (!ASSERT_OK(ret, "bpf_prog_get_next_id")) | ||
goto close_prog; | ||
|
||
skel->bss->key_id = UINT32_MAX; | ||
|
||
ret = bpf_prog_get_next_id(0, &next_id); | ||
ASSERT_LT(ret, 0, "bpf_prog_get_next_id"); | ||
|
||
close_prog: | ||
skel->bss->monitored_pid = 0; | ||
test_lookup_key__destroy(skel); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
|
||
/* | ||
* Copyright (C) 2022 Huawei Technologies Duesseldorf GmbH | ||
* | ||
* Author: Roberto Sassu <roberto.sassu@huawei.com> | ||
*/ | ||
|
||
#include "vmlinux.h" | ||
#include <errno.h> | ||
#include <bpf/bpf_helpers.h> | ||
#include <bpf/bpf_tracing.h> | ||
|
||
char _license[] SEC("license") = "GPL"; | ||
|
||
__u32 monitored_pid; | ||
__u32 key_serial; | ||
__u32 key_id; | ||
__u64 flags; | ||
|
||
extern struct bpf_key *bpf_lookup_user_key(__u32 serial, __u64 flags) __ksym; | ||
extern struct bpf_key *bpf_lookup_system_key(__u64 id) __ksym; | ||
extern void bpf_key_put(struct bpf_key *key) __ksym; | ||
|
||
SEC("lsm.s/bpf") | ||
int BPF_PROG(bpf, int cmd, union bpf_attr *attr, unsigned int size) | ||
{ | ||
struct bpf_key *bkey; | ||
__u32 pid; | ||
|
||
pid = bpf_get_current_pid_tgid() >> 32; | ||
if (pid != monitored_pid) | ||
return 0; | ||
|
||
if (key_serial) | ||
bkey = bpf_lookup_user_key(key_serial, flags); | ||
else | ||
bkey = bpf_lookup_system_key(key_id); | ||
|
||
if (!bkey) | ||
return -ENOENT; | ||
|
||
bpf_key_put(bkey); | ||
|
||
return 0; | ||
} |