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