xref: /linux/security/landlock/audit.c (revision 69050f8d6d075dc01af7a5f2f550a8067510366f)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Landlock - Audit helpers
4  *
5  * Copyright © 2023-2025 Microsoft Corporation
6  */
7 
8 #include <kunit/test.h>
9 #include <linux/audit.h>
10 #include <linux/bitops.h>
11 #include <linux/lsm_audit.h>
12 #include <linux/pid.h>
13 #include <uapi/linux/landlock.h>
14 
15 #include "access.h"
16 #include "audit.h"
17 #include "common.h"
18 #include "cred.h"
19 #include "domain.h"
20 #include "limits.h"
21 #include "ruleset.h"
22 
23 static const char *const fs_access_strings[] = {
24 	[BIT_INDEX(LANDLOCK_ACCESS_FS_EXECUTE)] = "fs.execute",
25 	[BIT_INDEX(LANDLOCK_ACCESS_FS_WRITE_FILE)] = "fs.write_file",
26 	[BIT_INDEX(LANDLOCK_ACCESS_FS_READ_FILE)] = "fs.read_file",
27 	[BIT_INDEX(LANDLOCK_ACCESS_FS_READ_DIR)] = "fs.read_dir",
28 	[BIT_INDEX(LANDLOCK_ACCESS_FS_REMOVE_DIR)] = "fs.remove_dir",
29 	[BIT_INDEX(LANDLOCK_ACCESS_FS_REMOVE_FILE)] = "fs.remove_file",
30 	[BIT_INDEX(LANDLOCK_ACCESS_FS_MAKE_CHAR)] = "fs.make_char",
31 	[BIT_INDEX(LANDLOCK_ACCESS_FS_MAKE_DIR)] = "fs.make_dir",
32 	[BIT_INDEX(LANDLOCK_ACCESS_FS_MAKE_REG)] = "fs.make_reg",
33 	[BIT_INDEX(LANDLOCK_ACCESS_FS_MAKE_SOCK)] = "fs.make_sock",
34 	[BIT_INDEX(LANDLOCK_ACCESS_FS_MAKE_FIFO)] = "fs.make_fifo",
35 	[BIT_INDEX(LANDLOCK_ACCESS_FS_MAKE_BLOCK)] = "fs.make_block",
36 	[BIT_INDEX(LANDLOCK_ACCESS_FS_MAKE_SYM)] = "fs.make_sym",
37 	[BIT_INDEX(LANDLOCK_ACCESS_FS_REFER)] = "fs.refer",
38 	[BIT_INDEX(LANDLOCK_ACCESS_FS_TRUNCATE)] = "fs.truncate",
39 	[BIT_INDEX(LANDLOCK_ACCESS_FS_IOCTL_DEV)] = "fs.ioctl_dev",
40 };
41 
42 static_assert(ARRAY_SIZE(fs_access_strings) == LANDLOCK_NUM_ACCESS_FS);
43 
44 static const char *const net_access_strings[] = {
45 	[BIT_INDEX(LANDLOCK_ACCESS_NET_BIND_TCP)] = "net.bind_tcp",
46 	[BIT_INDEX(LANDLOCK_ACCESS_NET_CONNECT_TCP)] = "net.connect_tcp",
47 };
48 
49 static_assert(ARRAY_SIZE(net_access_strings) == LANDLOCK_NUM_ACCESS_NET);
50 
51 static __attribute_const__ const char *
52 get_blocker(const enum landlock_request_type type,
53 	    const unsigned long access_bit)
54 {
55 	switch (type) {
56 	case LANDLOCK_REQUEST_PTRACE:
57 		WARN_ON_ONCE(access_bit != -1);
58 		return "ptrace";
59 
60 	case LANDLOCK_REQUEST_FS_CHANGE_TOPOLOGY:
61 		WARN_ON_ONCE(access_bit != -1);
62 		return "fs.change_topology";
63 
64 	case LANDLOCK_REQUEST_FS_ACCESS:
65 		if (WARN_ON_ONCE(access_bit >= ARRAY_SIZE(fs_access_strings)))
66 			return "unknown";
67 		return fs_access_strings[access_bit];
68 
69 	case LANDLOCK_REQUEST_NET_ACCESS:
70 		if (WARN_ON_ONCE(access_bit >= ARRAY_SIZE(net_access_strings)))
71 			return "unknown";
72 		return net_access_strings[access_bit];
73 
74 	case LANDLOCK_REQUEST_SCOPE_ABSTRACT_UNIX_SOCKET:
75 		WARN_ON_ONCE(access_bit != -1);
76 		return "scope.abstract_unix_socket";
77 
78 	case LANDLOCK_REQUEST_SCOPE_SIGNAL:
79 		WARN_ON_ONCE(access_bit != -1);
80 		return "scope.signal";
81 	}
82 
83 	WARN_ON_ONCE(1);
84 	return "unknown";
85 }
86 
87 static void log_blockers(struct audit_buffer *const ab,
88 			 const enum landlock_request_type type,
89 			 const access_mask_t access)
90 {
91 	const unsigned long access_mask = access;
92 	unsigned long access_bit;
93 	bool is_first = true;
94 
95 	for_each_set_bit(access_bit, &access_mask, BITS_PER_TYPE(access)) {
96 		audit_log_format(ab, "%s%s", is_first ? "" : ",",
97 				 get_blocker(type, access_bit));
98 		is_first = false;
99 	}
100 	if (is_first)
101 		audit_log_format(ab, "%s", get_blocker(type, -1));
102 }
103 
104 static void log_domain(struct landlock_hierarchy *const hierarchy)
105 {
106 	struct audit_buffer *ab;
107 
108 	/* Ignores already logged domains.  */
109 	if (READ_ONCE(hierarchy->log_status) == LANDLOCK_LOG_RECORDED)
110 		return;
111 
112 	/* Uses consistent allocation flags wrt common_lsm_audit(). */
113 	ab = audit_log_start(audit_context(), GFP_ATOMIC | __GFP_NOWARN,
114 			     AUDIT_LANDLOCK_DOMAIN);
115 	if (!ab)
116 		return;
117 
118 	WARN_ON_ONCE(hierarchy->id == 0);
119 	audit_log_format(
120 		ab,
121 		"domain=%llx status=allocated mode=enforcing pid=%d uid=%u exe=",
122 		hierarchy->id, pid_nr(hierarchy->details->pid),
123 		hierarchy->details->uid);
124 	audit_log_untrustedstring(ab, hierarchy->details->exe_path);
125 	audit_log_format(ab, " comm=");
126 	audit_log_untrustedstring(ab, hierarchy->details->comm);
127 	audit_log_end(ab);
128 
129 	/*
130 	 * There may be race condition leading to logging of the same domain
131 	 * several times but that is OK.
132 	 */
133 	WRITE_ONCE(hierarchy->log_status, LANDLOCK_LOG_RECORDED);
134 }
135 
136 static struct landlock_hierarchy *
137 get_hierarchy(const struct landlock_ruleset *const domain, const size_t layer)
138 {
139 	struct landlock_hierarchy *hierarchy = domain->hierarchy;
140 	ssize_t i;
141 
142 	if (WARN_ON_ONCE(layer >= domain->num_layers))
143 		return hierarchy;
144 
145 	for (i = domain->num_layers - 1; i > layer; i--) {
146 		if (WARN_ON_ONCE(!hierarchy->parent))
147 			break;
148 
149 		hierarchy = hierarchy->parent;
150 	}
151 
152 	return hierarchy;
153 }
154 
155 #ifdef CONFIG_SECURITY_LANDLOCK_KUNIT_TEST
156 
157 static void test_get_hierarchy(struct kunit *const test)
158 {
159 	struct landlock_hierarchy dom0_hierarchy = {
160 		.id = 10,
161 	};
162 	struct landlock_hierarchy dom1_hierarchy = {
163 		.parent = &dom0_hierarchy,
164 		.id = 20,
165 	};
166 	struct landlock_hierarchy dom2_hierarchy = {
167 		.parent = &dom1_hierarchy,
168 		.id = 30,
169 	};
170 	struct landlock_ruleset dom2 = {
171 		.hierarchy = &dom2_hierarchy,
172 		.num_layers = 3,
173 	};
174 
175 	KUNIT_EXPECT_EQ(test, 10, get_hierarchy(&dom2, 0)->id);
176 	KUNIT_EXPECT_EQ(test, 20, get_hierarchy(&dom2, 1)->id);
177 	KUNIT_EXPECT_EQ(test, 30, get_hierarchy(&dom2, 2)->id);
178 	/* KUNIT_EXPECT_EQ(test, 30, get_hierarchy(&dom2, -1)->id); */
179 }
180 
181 #endif /* CONFIG_SECURITY_LANDLOCK_KUNIT_TEST */
182 
183 /* Get the youngest layer that denied the access_request. */
184 static size_t get_denied_layer(const struct landlock_ruleset *const domain,
185 			       access_mask_t *const access_request,
186 			       const struct layer_access_masks *masks)
187 {
188 	for (ssize_t i = ARRAY_SIZE(masks->access) - 1; i >= 0; i--) {
189 		if (masks->access[i] & *access_request) {
190 			*access_request &= masks->access[i];
191 			return i;
192 		}
193 	}
194 
195 	/* Not found - fall back to default values */
196 	*access_request = 0;
197 	return domain->num_layers - 1;
198 }
199 
200 #ifdef CONFIG_SECURITY_LANDLOCK_KUNIT_TEST
201 
202 static void test_get_denied_layer(struct kunit *const test)
203 {
204 	const struct landlock_ruleset dom = {
205 		.num_layers = 5,
206 	};
207 	const struct layer_access_masks masks = {
208 		.access[0] = LANDLOCK_ACCESS_FS_EXECUTE |
209 			     LANDLOCK_ACCESS_FS_READ_DIR,
210 		.access[1] = LANDLOCK_ACCESS_FS_READ_FILE |
211 			     LANDLOCK_ACCESS_FS_READ_DIR,
212 		.access[2] = LANDLOCK_ACCESS_FS_REMOVE_DIR,
213 	};
214 	access_mask_t access;
215 
216 	access = LANDLOCK_ACCESS_FS_EXECUTE;
217 	KUNIT_EXPECT_EQ(test, 0, get_denied_layer(&dom, &access, &masks));
218 	KUNIT_EXPECT_EQ(test, access, LANDLOCK_ACCESS_FS_EXECUTE);
219 
220 	access = LANDLOCK_ACCESS_FS_READ_FILE;
221 	KUNIT_EXPECT_EQ(test, 1, get_denied_layer(&dom, &access, &masks));
222 	KUNIT_EXPECT_EQ(test, access, LANDLOCK_ACCESS_FS_READ_FILE);
223 
224 	access = LANDLOCK_ACCESS_FS_READ_DIR;
225 	KUNIT_EXPECT_EQ(test, 1, get_denied_layer(&dom, &access, &masks));
226 	KUNIT_EXPECT_EQ(test, access, LANDLOCK_ACCESS_FS_READ_DIR);
227 
228 	access = LANDLOCK_ACCESS_FS_READ_FILE | LANDLOCK_ACCESS_FS_READ_DIR;
229 	KUNIT_EXPECT_EQ(test, 1, get_denied_layer(&dom, &access, &masks));
230 	KUNIT_EXPECT_EQ(test, access,
231 			LANDLOCK_ACCESS_FS_READ_FILE |
232 				LANDLOCK_ACCESS_FS_READ_DIR);
233 
234 	access = LANDLOCK_ACCESS_FS_EXECUTE | LANDLOCK_ACCESS_FS_READ_DIR;
235 	KUNIT_EXPECT_EQ(test, 1, get_denied_layer(&dom, &access, &masks));
236 	KUNIT_EXPECT_EQ(test, access, LANDLOCK_ACCESS_FS_READ_DIR);
237 
238 	access = LANDLOCK_ACCESS_FS_WRITE_FILE;
239 	KUNIT_EXPECT_EQ(test, 4, get_denied_layer(&dom, &access, &masks));
240 	KUNIT_EXPECT_EQ(test, access, 0);
241 }
242 
243 #endif /* CONFIG_SECURITY_LANDLOCK_KUNIT_TEST */
244 
245 static size_t
246 get_layer_from_deny_masks(access_mask_t *const access_request,
247 			  const access_mask_t all_existing_optional_access,
248 			  const deny_masks_t deny_masks)
249 {
250 	const unsigned long access_opt = all_existing_optional_access;
251 	const unsigned long access_req = *access_request;
252 	access_mask_t missing = 0;
253 	size_t youngest_layer = 0;
254 	size_t access_index = 0;
255 	unsigned long access_bit;
256 
257 	/* This will require change with new object types. */
258 	WARN_ON_ONCE(access_opt != _LANDLOCK_ACCESS_FS_OPTIONAL);
259 
260 	for_each_set_bit(access_bit, &access_opt,
261 			 BITS_PER_TYPE(access_mask_t)) {
262 		if (access_req & BIT(access_bit)) {
263 			const size_t layer =
264 				(deny_masks >> (access_index * 4)) &
265 				(LANDLOCK_MAX_NUM_LAYERS - 1);
266 
267 			if (layer > youngest_layer) {
268 				youngest_layer = layer;
269 				missing = BIT(access_bit);
270 			} else if (layer == youngest_layer) {
271 				missing |= BIT(access_bit);
272 			}
273 		}
274 		access_index++;
275 	}
276 
277 	*access_request = missing;
278 	return youngest_layer;
279 }
280 
281 #ifdef CONFIG_SECURITY_LANDLOCK_KUNIT_TEST
282 
283 static void test_get_layer_from_deny_masks(struct kunit *const test)
284 {
285 	deny_masks_t deny_mask;
286 	access_mask_t access;
287 
288 	/* truncate:0 ioctl_dev:2 */
289 	deny_mask = 0x20;
290 
291 	access = LANDLOCK_ACCESS_FS_TRUNCATE;
292 	KUNIT_EXPECT_EQ(test, 0,
293 			get_layer_from_deny_masks(&access,
294 						  _LANDLOCK_ACCESS_FS_OPTIONAL,
295 						  deny_mask));
296 	KUNIT_EXPECT_EQ(test, access, LANDLOCK_ACCESS_FS_TRUNCATE);
297 
298 	access = LANDLOCK_ACCESS_FS_TRUNCATE | LANDLOCK_ACCESS_FS_IOCTL_DEV;
299 	KUNIT_EXPECT_EQ(test, 2,
300 			get_layer_from_deny_masks(&access,
301 						  _LANDLOCK_ACCESS_FS_OPTIONAL,
302 						  deny_mask));
303 	KUNIT_EXPECT_EQ(test, access, LANDLOCK_ACCESS_FS_IOCTL_DEV);
304 
305 	/* truncate:15 ioctl_dev:15 */
306 	deny_mask = 0xff;
307 
308 	access = LANDLOCK_ACCESS_FS_TRUNCATE;
309 	KUNIT_EXPECT_EQ(test, 15,
310 			get_layer_from_deny_masks(&access,
311 						  _LANDLOCK_ACCESS_FS_OPTIONAL,
312 						  deny_mask));
313 	KUNIT_EXPECT_EQ(test, access, LANDLOCK_ACCESS_FS_TRUNCATE);
314 
315 	access = LANDLOCK_ACCESS_FS_TRUNCATE | LANDLOCK_ACCESS_FS_IOCTL_DEV;
316 	KUNIT_EXPECT_EQ(test, 15,
317 			get_layer_from_deny_masks(&access,
318 						  _LANDLOCK_ACCESS_FS_OPTIONAL,
319 						  deny_mask));
320 	KUNIT_EXPECT_EQ(test, access,
321 			LANDLOCK_ACCESS_FS_TRUNCATE |
322 				LANDLOCK_ACCESS_FS_IOCTL_DEV);
323 }
324 
325 #endif /* CONFIG_SECURITY_LANDLOCK_KUNIT_TEST */
326 
327 static bool is_valid_request(const struct landlock_request *const request)
328 {
329 	if (WARN_ON_ONCE(request->layer_plus_one > LANDLOCK_MAX_NUM_LAYERS))
330 		return false;
331 
332 	if (WARN_ON_ONCE(!(!!request->layer_plus_one ^ !!request->access)))
333 		return false;
334 
335 	if (request->access) {
336 		if (WARN_ON_ONCE(!(!!request->layer_masks ^
337 				   !!request->all_existing_optional_access)))
338 			return false;
339 	} else {
340 		if (WARN_ON_ONCE(request->layer_masks ||
341 				 request->all_existing_optional_access))
342 			return false;
343 	}
344 
345 	if (request->deny_masks) {
346 		if (WARN_ON_ONCE(!request->all_existing_optional_access))
347 			return false;
348 	}
349 
350 	return true;
351 }
352 
353 /**
354  * landlock_log_denial - Create audit records related to a denial
355  *
356  * @subject: The Landlock subject's credential denying an action.
357  * @request: Detail of the user space request.
358  */
359 void landlock_log_denial(const struct landlock_cred_security *const subject,
360 			 const struct landlock_request *const request)
361 {
362 	struct audit_buffer *ab;
363 	struct landlock_hierarchy *youngest_denied;
364 	size_t youngest_layer;
365 	access_mask_t missing;
366 
367 	if (WARN_ON_ONCE(!subject || !subject->domain ||
368 			 !subject->domain->hierarchy || !request))
369 		return;
370 
371 	if (!is_valid_request(request))
372 		return;
373 
374 	missing = request->access;
375 	if (missing) {
376 		/* Gets the nearest domain that denies the request. */
377 		if (request->layer_masks) {
378 			youngest_layer = get_denied_layer(subject->domain,
379 							  &missing,
380 							  request->layer_masks);
381 		} else {
382 			youngest_layer = get_layer_from_deny_masks(
383 				&missing, _LANDLOCK_ACCESS_FS_OPTIONAL,
384 				request->deny_masks);
385 		}
386 		youngest_denied =
387 			get_hierarchy(subject->domain, youngest_layer);
388 	} else {
389 		youngest_layer = request->layer_plus_one - 1;
390 		youngest_denied =
391 			get_hierarchy(subject->domain, youngest_layer);
392 	}
393 
394 	if (READ_ONCE(youngest_denied->log_status) == LANDLOCK_LOG_DISABLED)
395 		return;
396 
397 	/*
398 	 * Consistently keeps track of the number of denied access requests
399 	 * even if audit is currently disabled, or if audit rules currently
400 	 * exclude this record type, or if landlock_restrict_self(2)'s flags
401 	 * quiet logs.
402 	 */
403 	atomic64_inc(&youngest_denied->num_denials);
404 
405 	if (!audit_enabled)
406 		return;
407 
408 	/* Checks if the current exec was restricting itself. */
409 	if (subject->domain_exec & BIT(youngest_layer)) {
410 		/* Ignores denials for the same execution. */
411 		if (!youngest_denied->log_same_exec)
412 			return;
413 	} else {
414 		/* Ignores denials after a new execution. */
415 		if (!youngest_denied->log_new_exec)
416 			return;
417 	}
418 
419 	/* Uses consistent allocation flags wrt common_lsm_audit(). */
420 	ab = audit_log_start(audit_context(), GFP_ATOMIC | __GFP_NOWARN,
421 			     AUDIT_LANDLOCK_ACCESS);
422 	if (!ab)
423 		return;
424 
425 	audit_log_format(ab, "domain=%llx blockers=", youngest_denied->id);
426 	log_blockers(ab, request->type, missing);
427 	audit_log_lsm_data(ab, &request->audit);
428 	audit_log_end(ab);
429 
430 	/* Logs this domain the first time it shows in log. */
431 	log_domain(youngest_denied);
432 }
433 
434 /**
435  * landlock_log_drop_domain - Create an audit record on domain deallocation
436  *
437  * @hierarchy: The domain's hierarchy being deallocated.
438  *
439  * Only domains which previously appeared in the audit logs are logged again.
440  * This is useful to know when a domain will never show again in the audit log.
441  *
442  * Called in a work queue scheduled by landlock_put_ruleset_deferred() called
443  * by hook_cred_free().
444  */
445 void landlock_log_drop_domain(const struct landlock_hierarchy *const hierarchy)
446 {
447 	struct audit_buffer *ab;
448 
449 	if (WARN_ON_ONCE(!hierarchy))
450 		return;
451 
452 	if (!audit_enabled)
453 		return;
454 
455 	/* Ignores domains that were not logged.  */
456 	if (READ_ONCE(hierarchy->log_status) != LANDLOCK_LOG_RECORDED)
457 		return;
458 
459 	/*
460 	 * If logging of domain allocation succeeded, warns about failure to log
461 	 * domain deallocation to highlight unbalanced domain lifetime logs.
462 	 */
463 	ab = audit_log_start(audit_context(), GFP_KERNEL,
464 			     AUDIT_LANDLOCK_DOMAIN);
465 	if (!ab)
466 		return;
467 
468 	audit_log_format(ab, "domain=%llx status=deallocated denials=%llu",
469 			 hierarchy->id, atomic64_read(&hierarchy->num_denials));
470 	audit_log_end(ab);
471 }
472 
473 #ifdef CONFIG_SECURITY_LANDLOCK_KUNIT_TEST
474 
475 static struct kunit_case test_cases[] = {
476 	/* clang-format off */
477 	KUNIT_CASE(test_get_hierarchy),
478 	KUNIT_CASE(test_get_denied_layer),
479 	KUNIT_CASE(test_get_layer_from_deny_masks),
480 	{}
481 	/* clang-format on */
482 };
483 
484 static struct kunit_suite test_suite = {
485 	.name = "landlock_audit",
486 	.test_cases = test_cases,
487 };
488 
489 kunit_test_suite(test_suite);
490 
491 #endif /* CONFIG_SECURITY_LANDLOCK_KUNIT_TEST */
492