1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Linux Security Module infrastructure tests
4 * Tests for the lsm_list_modules system call
5 *
6 * Copyright �� 2022 Casey Schaufler <casey@schaufler-ca.com>
7 */
8
9#define _GNU_SOURCE
10#include <linux/lsm.h>
11#include <string.h>
12#include <stdio.h>
13#include <unistd.h>
14#include <sys/types.h>
15#include "../kselftest_harness.h"
16#include "common.h"
17
18TEST(size_null_lsm_list_modules)
19{
20	const long page_size = sysconf(_SC_PAGESIZE);
21	__u64 *syscall_lsms = calloc(page_size, 1);
22
23	ASSERT_NE(NULL, syscall_lsms);
24	errno = 0;
25	ASSERT_EQ(-1, lsm_list_modules(syscall_lsms, NULL, 0));
26	ASSERT_EQ(EFAULT, errno);
27
28	free(syscall_lsms);
29}
30
31TEST(ids_null_lsm_list_modules)
32{
33	const long page_size = sysconf(_SC_PAGESIZE);
34	__u32 size = page_size;
35
36	errno = 0;
37	ASSERT_EQ(-1, lsm_list_modules(NULL, &size, 0));
38	ASSERT_EQ(EFAULT, errno);
39	ASSERT_NE(1, size);
40}
41
42TEST(size_too_small_lsm_list_modules)
43{
44	const long page_size = sysconf(_SC_PAGESIZE);
45	__u64 *syscall_lsms = calloc(page_size, 1);
46	__u32 size = 1;
47
48	ASSERT_NE(NULL, syscall_lsms);
49	errno = 0;
50	ASSERT_EQ(-1, lsm_list_modules(syscall_lsms, &size, 0));
51	ASSERT_EQ(E2BIG, errno);
52	ASSERT_NE(1, size);
53
54	free(syscall_lsms);
55}
56
57TEST(flags_set_lsm_list_modules)
58{
59	const long page_size = sysconf(_SC_PAGESIZE);
60	__u64 *syscall_lsms = calloc(page_size, 1);
61	__u32 size = page_size;
62
63	ASSERT_NE(NULL, syscall_lsms);
64	errno = 0;
65	ASSERT_EQ(-1, lsm_list_modules(syscall_lsms, &size, 7));
66	ASSERT_EQ(EINVAL, errno);
67	ASSERT_EQ(page_size, size);
68
69	free(syscall_lsms);
70}
71
72TEST(correct_lsm_list_modules)
73{
74	const long page_size = sysconf(_SC_PAGESIZE);
75	__u32 size = page_size;
76	__u64 *syscall_lsms = calloc(page_size, 1);
77	char *sysfs_lsms = calloc(page_size, 1);
78	char *name;
79	char *cp;
80	int count;
81	int i;
82
83	ASSERT_NE(NULL, sysfs_lsms);
84	ASSERT_NE(NULL, syscall_lsms);
85	ASSERT_EQ(0, read_sysfs_lsms(sysfs_lsms, page_size));
86
87	count = lsm_list_modules(syscall_lsms, &size, 0);
88	ASSERT_LE(1, count);
89	cp = sysfs_lsms;
90	for (i = 0; i < count; i++) {
91		switch (syscall_lsms[i]) {
92		case LSM_ID_CAPABILITY:
93			name = "capability";
94			break;
95		case LSM_ID_SELINUX:
96			name = "selinux";
97			break;
98		case LSM_ID_SMACK:
99			name = "smack";
100			break;
101		case LSM_ID_TOMOYO:
102			name = "tomoyo";
103			break;
104		case LSM_ID_APPARMOR:
105			name = "apparmor";
106			break;
107		case LSM_ID_YAMA:
108			name = "yama";
109			break;
110		case LSM_ID_LOADPIN:
111			name = "loadpin";
112			break;
113		case LSM_ID_SAFESETID:
114			name = "safesetid";
115			break;
116		case LSM_ID_LOCKDOWN:
117			name = "lockdown";
118			break;
119		case LSM_ID_BPF:
120			name = "bpf";
121			break;
122		case LSM_ID_LANDLOCK:
123			name = "landlock";
124			break;
125		case LSM_ID_IMA:
126			name = "ima";
127			break;
128		case LSM_ID_EVM:
129			name = "evm";
130			break;
131		default:
132			name = "INVALID";
133			break;
134		}
135		ASSERT_EQ(0, strncmp(cp, name, strlen(name)));
136		cp += strlen(name) + 1;
137	}
138
139	free(sysfs_lsms);
140	free(syscall_lsms);
141}
142
143TEST_HARNESS_MAIN
144