1d5810139SFrederick Lawler // SPDX-License-Identifier: GPL-2.0
2d5810139SFrederick Lawler #include <linux/bpf.h>
3d5810139SFrederick Lawler #include <bpf/bpf_helpers.h>
4d5810139SFrederick Lawler #include <bpf/bpf_tracing.h>
5d5810139SFrederick Lawler #include <errno.h>
6d5810139SFrederick Lawler #include <linux/capability.h>
7d5810139SFrederick Lawler 
8*e8c8361cSAlexei Starovoitov typedef struct { unsigned long long val; } kernel_cap_t;
9d5810139SFrederick Lawler 
10d5810139SFrederick Lawler struct cred {
11*e8c8361cSAlexei Starovoitov 	kernel_cap_t cap_effective;
12d5810139SFrederick Lawler } __attribute__((preserve_access_index));
13d5810139SFrederick Lawler 
14d5810139SFrederick Lawler char _license[] SEC("license") = "GPL";
15d5810139SFrederick Lawler 
16d5810139SFrederick Lawler SEC("lsm.s/userns_create")
BPF_PROG(test_userns_create,const struct cred * cred,int ret)17d5810139SFrederick Lawler int BPF_PROG(test_userns_create, const struct cred *cred, int ret)
18d5810139SFrederick Lawler {
19*e8c8361cSAlexei Starovoitov 	kernel_cap_t caps = cred->cap_effective;
20*e8c8361cSAlexei Starovoitov 	__u64 cap_mask = 1ULL << CAP_SYS_ADMIN;
21d5810139SFrederick Lawler 
22d5810139SFrederick Lawler 	if (ret)
23d5810139SFrederick Lawler 		return 0;
24d5810139SFrederick Lawler 
25d5810139SFrederick Lawler 	ret = -EPERM;
26f122a08bSLinus Torvalds 	if (caps.val & cap_mask)
27d5810139SFrederick Lawler 		return 0;
28d5810139SFrederick Lawler 
29d5810139SFrederick Lawler 	return -EPERM;
30d5810139SFrederick Lawler }
31