xref: /linux/security/ipe/policy_tests.c (revision c532de5a67a70f8533d495f8f2aaa9a0491c3ad0)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2020-2024 Microsoft Corporation. All rights reserved.
4  */
5 
6 #include <linux/slab.h>
7 #include <linux/types.h>
8 #include <linux/list.h>
9 #include <kunit/test.h>
10 #include "policy.h"
11 struct policy_case {
12 	const char *const policy;
13 	int errno;
14 	const char *const desc;
15 };
16 
17 static const struct policy_case policy_cases[] = {
18 	{
19 		"policy_name=allowall policy_version=0.0.0\n"
20 		"DEFAULT action=ALLOW",
21 		0,
22 		"basic",
23 	},
24 	{
25 		"policy_name=trailing_comment policy_version=152.0.0 #This is comment\n"
26 		"DEFAULT action=ALLOW",
27 		0,
28 		"trailing comment",
29 	},
30 	{
31 		"policy_name=allowallnewline policy_version=0.2.0\n"
32 		"DEFAULT action=ALLOW\n"
33 		"\n",
34 		0,
35 		"trailing newline",
36 	},
37 	{
38 		"policy_name=carriagereturnlinefeed policy_version=0.0.1\n"
39 		"DEFAULT action=ALLOW\n"
40 		"\r\n",
41 		0,
42 		"clrf newline",
43 	},
44 	{
45 		"policy_name=whitespace policy_version=0.0.0\n"
46 		"DEFAULT\taction=ALLOW\n"
47 		"     \t     DEFAULT \t    op=EXECUTE      action=DENY\n"
48 		"op=EXECUTE boot_verified=TRUE action=ALLOW\n"
49 		"# this is a\tcomment\t\t\t\t\n"
50 		"DEFAULT \t op=KMODULE\t\t\t  action=DENY\r\n"
51 		"op=KMODULE boot_verified=TRUE action=ALLOW\n",
52 		0,
53 		"various whitespaces and nested default",
54 	},
55 	{
56 		"policy_name=boot_verified policy_version=-1236.0.0\n"
57 		"DEFAULT\taction=ALLOW\n",
58 		-EINVAL,
59 		"negative version",
60 	},
61 	{
62 		"policy_name=$@!*&^%%\\:;{}() policy_version=0.0.0\n"
63 		"DEFAULT action=ALLOW",
64 		0,
65 		"special characters",
66 	},
67 	{
68 		"policy_name=test policy_version=999999.0.0\n"
69 		"DEFAULT action=ALLOW",
70 		-ERANGE,
71 		"overflow version",
72 	},
73 	{
74 		"policy_name=test policy_version=255.0\n"
75 		"DEFAULT action=ALLOW",
76 		-EBADMSG,
77 		"incomplete version",
78 	},
79 	{
80 		"policy_name=test policy_version=111.0.0.0\n"
81 		"DEFAULT action=ALLOW",
82 		-EBADMSG,
83 		"extra version",
84 	},
85 	{
86 		"",
87 		-EBADMSG,
88 		"0-length policy",
89 	},
90 	{
91 		"policy_name=test\0policy_version=0.0.0\n"
92 		"DEFAULT action=ALLOW",
93 		-EBADMSG,
94 		"random null in header",
95 	},
96 	{
97 		"policy_name=test policy_version=0.0.0\n"
98 		"\0DEFAULT action=ALLOW",
99 		-EBADMSG,
100 		"incomplete policy from NULL",
101 	},
102 	{
103 		"policy_name=test policy_version=0.0.0\n"
104 		"DEFAULT action=DENY\n\0"
105 		"op=EXECUTE dmverity_signature=TRUE action=ALLOW\n",
106 		0,
107 		"NULL truncates policy",
108 	},
109 	{
110 		"policy_name=test policy_version=0.0.0\n"
111 		"DEFAULT action=ALLOW\n"
112 		"op=EXECUTE dmverity_signature=abc action=ALLOW",
113 		-EBADMSG,
114 		"invalid property type",
115 	},
116 	{
117 		"DEFAULT action=ALLOW",
118 		-EBADMSG,
119 		"missing policy header",
120 	},
121 	{
122 		"policy_name=test policy_version=0.0.0\n",
123 		-EBADMSG,
124 		"missing default definition",
125 	},
126 	{
127 		"policy_name=test policy_version=0.0.0\n"
128 		"DEFAULT action=ALLOW\n"
129 		"dmverity_signature=TRUE op=EXECUTE action=ALLOW",
130 		-EBADMSG,
131 		"invalid rule ordering"
132 	},
133 	{
134 		"policy_name=test policy_version=0.0.0\n"
135 		"DEFAULT action=ALLOW\n"
136 		"action=ALLOW op=EXECUTE dmverity_signature=TRUE",
137 		-EBADMSG,
138 		"invalid rule ordering (2)",
139 	},
140 	{
141 		"policy_name=test policy_version=0.0\n"
142 		"DEFAULT action=ALLOW\n"
143 		"op=EXECUTE dmverity_signature=TRUE action=ALLOW",
144 		-EBADMSG,
145 		"invalid version",
146 	},
147 	{
148 		"policy_name=test policy_version=0.0.0\n"
149 		"DEFAULT action=ALLOW\n"
150 		"op=UNKNOWN dmverity_signature=TRUE action=ALLOW",
151 		-EBADMSG,
152 		"unknown operation",
153 	},
154 	{
155 		"policy_name=asdvpolicy_version=0.0.0\n"
156 		"DEFAULT action=ALLOW\n",
157 		-EBADMSG,
158 		"missing space after policy name",
159 	},
160 	{
161 		"policy_name=test\xFF\xEF policy_version=0.0.0\n"
162 		"DEFAULT action=ALLOW\n"
163 		"op=EXECUTE dmverity_signature=TRUE action=ALLOW",
164 		0,
165 		"expanded ascii",
166 	},
167 	{
168 		"policy_name=test\xFF\xEF policy_version=0.0.0\n"
169 		"DEFAULT action=ALLOW\n"
170 		"op=EXECUTE dmverity_roothash=GOOD_DOG action=ALLOW",
171 		-EBADMSG,
172 		"invalid property value (2)",
173 	},
174 	{
175 		"policy_name=test policy_version=0.0.0\n"
176 		"policy_name=test policy_version=0.1.0\n"
177 		"DEFAULT action=ALLOW",
178 		-EBADMSG,
179 		"double header"
180 	},
181 	{
182 		"policy_name=test policy_version=0.0.0\n"
183 		"DEFAULT action=ALLOW\n"
184 		"DEFAULT action=ALLOW\n",
185 		-EBADMSG,
186 		"double default"
187 	},
188 	{
189 		"policy_name=test policy_version=0.0.0\n"
190 		"DEFAULT action=ALLOW\n"
191 		"DEFAULT op=EXECUTE action=DENY\n"
192 		"DEFAULT op=EXECUTE action=ALLOW\n",
193 		-EBADMSG,
194 		"double operation default"
195 	},
196 	{
197 		"policy_name=test policy_version=0.0.0\n"
198 		"DEFAULT action=ALLOW\n"
199 		"DEFAULT op=EXECUTE action=DEN\n",
200 		-EBADMSG,
201 		"invalid action value"
202 	},
203 	{
204 		"policy_name=test policy_version=0.0.0\n"
205 		"DEFAULT action=ALLOW\n"
206 		"DEFAULT op=EXECUTE action\n",
207 		-EBADMSG,
208 		"invalid action value (2)"
209 	},
210 	{
211 		"policy_name=test policy_version=0.0.0\n"
212 		"DEFAULT action=ALLOW\n"
213 		"UNKNOWN value=true\n",
214 		-EBADMSG,
215 		"unrecognized statement"
216 	},
217 	{
218 		"policy_name=test policy_version=0.0.0\n"
219 		"DEFAULT action=ALLOW\n"
220 		"op=EXECUTE dmverity_roothash=1c0d7ee1f8343b7fbe418378e8eb22c061d7dec7 action=DENY\n",
221 		-EBADMSG,
222 		"old-style digest"
223 	},
224 	{
225 		"policy_name=test policy_version=0.0.0\n"
226 		"DEFAULT action=ALLOW\n"
227 		"op=EXECUTE fsverity_digest=1c0d7ee1f8343b7fbe418378e8eb22c061d7dec7 action=DENY\n",
228 		-EBADMSG,
229 		"old-style digest"
230 	}
231 };
232 
233 static void pol_to_desc(const struct policy_case *c, char *desc)
234 {
235 	strscpy(desc, c->desc, KUNIT_PARAM_DESC_SIZE);
236 }
237 
238 KUNIT_ARRAY_PARAM(ipe_policies, policy_cases, pol_to_desc);
239 
240 /**
241  * ipe_parser_unsigned_test - Test the parser by passing unsigned policies.
242  * @test: Supplies a pointer to a kunit structure.
243  *
244  * This is called by the kunit harness. This test does not check the correctness
245  * of the policy, but ensures that errors are handled correctly.
246  */
247 static void ipe_parser_unsigned_test(struct kunit *test)
248 {
249 	const struct policy_case *p = test->param_value;
250 	struct ipe_policy *pol;
251 
252 	pol = ipe_new_policy(p->policy, strlen(p->policy), NULL, 0);
253 
254 	if (p->errno) {
255 		KUNIT_EXPECT_EQ(test, PTR_ERR(pol), p->errno);
256 		return;
257 	}
258 
259 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pol);
260 	KUNIT_EXPECT_NOT_ERR_OR_NULL(test, pol->parsed);
261 	KUNIT_EXPECT_STREQ(test, pol->text, p->policy);
262 	KUNIT_EXPECT_PTR_EQ(test, NULL, pol->pkcs7);
263 	KUNIT_EXPECT_EQ(test, 0, pol->pkcs7len);
264 
265 	ipe_free_policy(pol);
266 }
267 
268 /**
269  * ipe_parser_widestring_test - Ensure parser fail on a wide string policy.
270  * @test: Supplies a pointer to a kunit structure.
271  *
272  * This is called by the kunit harness.
273  */
274 static void ipe_parser_widestring_test(struct kunit *test)
275 {
276 	const unsigned short policy[] = L"policy_name=Test policy_version=0.0.0\n"
277 					L"DEFAULT action=ALLOW";
278 	struct ipe_policy *pol = NULL;
279 
280 	pol = ipe_new_policy((const char *)policy, (ARRAY_SIZE(policy) - 1) * 2, NULL, 0);
281 	KUNIT_EXPECT_TRUE(test, IS_ERR_OR_NULL(pol));
282 
283 	ipe_free_policy(pol);
284 }
285 
286 static struct kunit_case ipe_parser_test_cases[] = {
287 	KUNIT_CASE_PARAM(ipe_parser_unsigned_test, ipe_policies_gen_params),
288 	KUNIT_CASE(ipe_parser_widestring_test),
289 	{ }
290 };
291 
292 static struct kunit_suite ipe_parser_test_suite = {
293 	.name = "ipe-parser",
294 	.test_cases = ipe_parser_test_cases,
295 };
296 
297 kunit_test_suite(ipe_parser_test_suite);
298