Skip to content

Commit 17e64cf

Browse files
jetlimeKernel Patches Daemon
authored andcommitted
selftests/bpf: add tests to verify the enforcement of CONFIG_CGROUP_LSM_NUM
Add a selftest that verifies the kernel correctly enforces CONFIG_CGROUP_LSM_NUM as the maximum number of concurrently attachable per-cgroup LSM hook slots. The BPF program side (progs/cgroup_lsm_num.c) defines 12 lsm_cgroup programs, each attached to a distinct LSM hook. The test side (prog_tests/cgroup_lsm_num.c) attempts to attach all 12 programs one by one to a cgroup, and verifies that exactly 10 succeed and 2 are rejected, matching the value of CONFIG_CGROUP_LSM_NUM set to 10 in the selftest Kconfig fragment. Signed-off-by: Paul Houssel <paulhoussel2@gmail.com>
1 parent cd2566e commit 17e64cf

3 files changed

Lines changed: 153 additions & 0 deletions

File tree

tools/testing/selftests/bpf/config

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ CONFIG_BPF_STREAM_PARSER=y
1111
CONFIG_BPF_SYSCALL=y
1212
# CONFIG_BPF_UNPRIV_DEFAULT_OFF is not set
1313
CONFIG_CGROUP_BPF=y
14+
CONFIG_CGROUP_LSM_NUM=10
1415
CONFIG_CRYPTO_HMAC=y
1516
CONFIG_CRYPTO_SHA256=y
1617
CONFIG_CRYPTO_USER_API=y
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/* Copyright (c) 2026 Orange */
3+
4+
/*
5+
* Test that the kernel enforces CONFIG_CGROUP_LSM_NUM as the maximum
6+
* number of concurrently used per-cgroup LSM hook slots.
7+
*
8+
* - load a BPF object with 12 programs each on a distinct lsm_cgroup hook
9+
* - attach them one by one via bpf_program__attach_cgroup()
10+
* - at some point the slots are exhausted and attachment fails
11+
* - verify that 10 succeed attachment and 2 fail
12+
*/
13+
14+
#include <test_progs.h>
15+
#include <bpf/bpf.h>
16+
17+
#include "cgroup_lsm_num.skel.h"
18+
#include "cgroup_helpers.h"
19+
20+
void test_cgroup_lsm_num(void)
21+
{
22+
struct cgroup_lsm_num *skel = NULL;
23+
struct bpf_program *prog;
24+
int cgroup_fd = -1;
25+
int attached = 0;
26+
int failed = 0;
27+
28+
cgroup_fd = test__join_cgroup("/cgroup_lsm_num");
29+
if (!ASSERT_GE(cgroup_fd, 0, "join_cgroup"))
30+
return;
31+
32+
skel = cgroup_lsm_num__open_and_load();
33+
if (!ASSERT_OK_PTR(skel, "open_and_load"))
34+
goto out;
35+
36+
bpf_object__for_each_program(prog, skel->obj) {
37+
struct bpf_link *link;
38+
39+
link = bpf_program__attach_cgroup(prog, cgroup_fd);
40+
if (!link) {
41+
if (errno == EOPNOTSUPP) {
42+
test__skip();
43+
goto out;
44+
}
45+
failed++;
46+
} else {
47+
attached++;
48+
}
49+
}
50+
51+
// CONFIG_CGROUP_LSM_NUM set to 10
52+
// -> 10 programs shall be attached
53+
ASSERT_EQ(attached, 10, "at least one attached");
54+
// -> 2 programs shall be rejected
55+
ASSERT_EQ(failed, 2, "limit was enforced");
56+
57+
out:
58+
close(cgroup_fd);
59+
cgroup_lsm_num__destroy(skel);
60+
}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/* Copyright (c) 2026 Orange */
3+
4+
/*
5+
* 12 LSM programs with lsm_cgroup attachment type, each on a distinct LSM
6+
* hook. Used by prog_tests/cgroup_lsm_num.c to verify that the kernel
7+
* enforces the CONFIG_CGROUP_LSM_NUM limit on unique per-cgroup LSM hook
8+
* slots. With CONFIG_CGROUP_LSM_NUM set to 10, 10 shall be attached and 2
9+
* rejected.
10+
*/
11+
12+
#include "vmlinux.h"
13+
#include <bpf/bpf_helpers.h>
14+
#include <bpf/bpf_tracing.h>
15+
16+
char _license[] SEC("license") = "GPL";
17+
18+
SEC("lsm_cgroup/socket_create")
19+
int BPF_PROG(hook0, int family, int type, int protocol, int kern)
20+
{
21+
return 1;
22+
}
23+
24+
SEC("lsm_cgroup/socket_post_create")
25+
int BPF_PROG(hook1, struct socket *sock, int family, int type,
26+
int protocol, int kern)
27+
{
28+
return 1;
29+
}
30+
31+
SEC("lsm_cgroup/socket_socketpair")
32+
int BPF_PROG(hook2, struct socket *socka, struct socket *sockb)
33+
{
34+
return 1;
35+
}
36+
37+
SEC("lsm_cgroup/socket_bind")
38+
int BPF_PROG(hook3, struct socket *sock, struct sockaddr *address,
39+
int addrlen)
40+
{
41+
return 1;
42+
}
43+
44+
SEC("lsm_cgroup/socket_connect")
45+
int BPF_PROG(hook4, struct socket *sock, struct sockaddr *address,
46+
int addrlen)
47+
{
48+
return 1;
49+
}
50+
51+
SEC("lsm_cgroup/socket_listen")
52+
int BPF_PROG(hook5, struct socket *sock, int backlog)
53+
{
54+
return 1;
55+
}
56+
57+
SEC("lsm_cgroup/socket_accept")
58+
int BPF_PROG(hook6, struct socket *sock, struct socket *newsock)
59+
{
60+
return 1;
61+
}
62+
63+
SEC("lsm_cgroup/socket_sendmsg")
64+
int BPF_PROG(hook7, struct socket *sock, struct msghdr *msg, int size)
65+
{
66+
return 1;
67+
}
68+
69+
SEC("lsm_cgroup/socket_recvmsg")
70+
int BPF_PROG(hook8, struct socket *sock, struct msghdr *msg, int size,
71+
int flags)
72+
{
73+
return 1;
74+
}
75+
76+
SEC("lsm_cgroup/socket_getsockname")
77+
int BPF_PROG(hook9, struct socket *sock)
78+
{
79+
return 1;
80+
}
81+
82+
SEC("lsm_cgroup/socket_getpeername")
83+
int BPF_PROG(hook10, struct socket *sock)
84+
{
85+
return 1;
86+
}
87+
88+
SEC("lsm_cgroup/socket_shutdown")
89+
int BPF_PROG(hook11, struct socket *sock, int how)
90+
{
91+
return 1;
92+
}

0 commit comments

Comments
 (0)