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 static size_t get_denied_layer(const struct landlock_ruleset *const domain, 184 access_mask_t *const access_request, 185 const layer_mask_t (*const layer_masks)[], 186 const size_t layer_masks_size) 187 { 188 const unsigned long access_req = *access_request; 189 unsigned long access_bit; 190 access_mask_t missing = 0; 191 long youngest_layer = -1; 192 193 for_each_set_bit(access_bit, &access_req, layer_masks_size) { 194 const access_mask_t mask = (*layer_masks)[access_bit]; 195 long layer; 196 197 if (!mask) 198 continue; 199 200 /* __fls(1) == 0 */ 201 layer = __fls(mask); 202 if (layer > youngest_layer) { 203 youngest_layer = layer; 204 missing = BIT(access_bit); 205 } else if (layer == youngest_layer) { 206 missing |= BIT(access_bit); 207 } 208 } 209 210 *access_request = missing; 211 if (youngest_layer == -1) 212 return domain->num_layers - 1; 213 214 return youngest_layer; 215 } 216 217 #ifdef CONFIG_SECURITY_LANDLOCK_KUNIT_TEST 218 219 static void test_get_denied_layer(struct kunit *const test) 220 { 221 const struct landlock_ruleset dom = { 222 .num_layers = 5, 223 }; 224 const layer_mask_t layer_masks[LANDLOCK_NUM_ACCESS_FS] = { 225 [BIT_INDEX(LANDLOCK_ACCESS_FS_EXECUTE)] = BIT(0), 226 [BIT_INDEX(LANDLOCK_ACCESS_FS_READ_FILE)] = BIT(1), 227 [BIT_INDEX(LANDLOCK_ACCESS_FS_READ_DIR)] = BIT(1) | BIT(0), 228 [BIT_INDEX(LANDLOCK_ACCESS_FS_REMOVE_DIR)] = BIT(2), 229 }; 230 access_mask_t access; 231 232 access = LANDLOCK_ACCESS_FS_EXECUTE; 233 KUNIT_EXPECT_EQ(test, 0, 234 get_denied_layer(&dom, &access, &layer_masks, 235 sizeof(layer_masks))); 236 KUNIT_EXPECT_EQ(test, access, LANDLOCK_ACCESS_FS_EXECUTE); 237 238 access = LANDLOCK_ACCESS_FS_READ_FILE; 239 KUNIT_EXPECT_EQ(test, 1, 240 get_denied_layer(&dom, &access, &layer_masks, 241 sizeof(layer_masks))); 242 KUNIT_EXPECT_EQ(test, access, LANDLOCK_ACCESS_FS_READ_FILE); 243 244 access = LANDLOCK_ACCESS_FS_READ_DIR; 245 KUNIT_EXPECT_EQ(test, 1, 246 get_denied_layer(&dom, &access, &layer_masks, 247 sizeof(layer_masks))); 248 KUNIT_EXPECT_EQ(test, access, LANDLOCK_ACCESS_FS_READ_DIR); 249 250 access = LANDLOCK_ACCESS_FS_READ_FILE | LANDLOCK_ACCESS_FS_READ_DIR; 251 KUNIT_EXPECT_EQ(test, 1, 252 get_denied_layer(&dom, &access, &layer_masks, 253 sizeof(layer_masks))); 254 KUNIT_EXPECT_EQ(test, access, 255 LANDLOCK_ACCESS_FS_READ_FILE | 256 LANDLOCK_ACCESS_FS_READ_DIR); 257 258 access = LANDLOCK_ACCESS_FS_EXECUTE | LANDLOCK_ACCESS_FS_READ_DIR; 259 KUNIT_EXPECT_EQ(test, 1, 260 get_denied_layer(&dom, &access, &layer_masks, 261 sizeof(layer_masks))); 262 KUNIT_EXPECT_EQ(test, access, LANDLOCK_ACCESS_FS_READ_DIR); 263 264 access = LANDLOCK_ACCESS_FS_WRITE_FILE; 265 KUNIT_EXPECT_EQ(test, 4, 266 get_denied_layer(&dom, &access, &layer_masks, 267 sizeof(layer_masks))); 268 KUNIT_EXPECT_EQ(test, access, 0); 269 } 270 271 #endif /* CONFIG_SECURITY_LANDLOCK_KUNIT_TEST */ 272 273 static size_t 274 get_layer_from_deny_masks(access_mask_t *const access_request, 275 const access_mask_t all_existing_optional_access, 276 const deny_masks_t deny_masks) 277 { 278 const unsigned long access_opt = all_existing_optional_access; 279 const unsigned long access_req = *access_request; 280 access_mask_t missing = 0; 281 size_t youngest_layer = 0; 282 size_t access_index = 0; 283 unsigned long access_bit; 284 285 /* This will require change with new object types. */ 286 WARN_ON_ONCE(access_opt != _LANDLOCK_ACCESS_FS_OPTIONAL); 287 288 for_each_set_bit(access_bit, &access_opt, 289 BITS_PER_TYPE(access_mask_t)) { 290 if (access_req & BIT(access_bit)) { 291 const size_t layer = 292 (deny_masks >> (access_index * 4)) & 293 (LANDLOCK_MAX_NUM_LAYERS - 1); 294 295 if (layer > youngest_layer) { 296 youngest_layer = layer; 297 missing = BIT(access_bit); 298 } else if (layer == youngest_layer) { 299 missing |= BIT(access_bit); 300 } 301 } 302 access_index++; 303 } 304 305 *access_request = missing; 306 return youngest_layer; 307 } 308 309 #ifdef CONFIG_SECURITY_LANDLOCK_KUNIT_TEST 310 311 static void test_get_layer_from_deny_masks(struct kunit *const test) 312 { 313 deny_masks_t deny_mask; 314 access_mask_t access; 315 316 /* truncate:0 ioctl_dev:2 */ 317 deny_mask = 0x20; 318 319 access = LANDLOCK_ACCESS_FS_TRUNCATE; 320 KUNIT_EXPECT_EQ(test, 0, 321 get_layer_from_deny_masks(&access, 322 _LANDLOCK_ACCESS_FS_OPTIONAL, 323 deny_mask)); 324 KUNIT_EXPECT_EQ(test, access, LANDLOCK_ACCESS_FS_TRUNCATE); 325 326 access = LANDLOCK_ACCESS_FS_TRUNCATE | LANDLOCK_ACCESS_FS_IOCTL_DEV; 327 KUNIT_EXPECT_EQ(test, 2, 328 get_layer_from_deny_masks(&access, 329 _LANDLOCK_ACCESS_FS_OPTIONAL, 330 deny_mask)); 331 KUNIT_EXPECT_EQ(test, access, LANDLOCK_ACCESS_FS_IOCTL_DEV); 332 333 /* truncate:15 ioctl_dev:15 */ 334 deny_mask = 0xff; 335 336 access = LANDLOCK_ACCESS_FS_TRUNCATE; 337 KUNIT_EXPECT_EQ(test, 15, 338 get_layer_from_deny_masks(&access, 339 _LANDLOCK_ACCESS_FS_OPTIONAL, 340 deny_mask)); 341 KUNIT_EXPECT_EQ(test, access, LANDLOCK_ACCESS_FS_TRUNCATE); 342 343 access = LANDLOCK_ACCESS_FS_TRUNCATE | LANDLOCK_ACCESS_FS_IOCTL_DEV; 344 KUNIT_EXPECT_EQ(test, 15, 345 get_layer_from_deny_masks(&access, 346 _LANDLOCK_ACCESS_FS_OPTIONAL, 347 deny_mask)); 348 KUNIT_EXPECT_EQ(test, access, 349 LANDLOCK_ACCESS_FS_TRUNCATE | 350 LANDLOCK_ACCESS_FS_IOCTL_DEV); 351 } 352 353 #endif /* CONFIG_SECURITY_LANDLOCK_KUNIT_TEST */ 354 355 static bool is_valid_request(const struct landlock_request *const request) 356 { 357 if (WARN_ON_ONCE(request->layer_plus_one > LANDLOCK_MAX_NUM_LAYERS)) 358 return false; 359 360 if (WARN_ON_ONCE(!(!!request->layer_plus_one ^ !!request->access))) 361 return false; 362 363 if (request->access) { 364 if (WARN_ON_ONCE(!(!!request->layer_masks ^ 365 !!request->all_existing_optional_access))) 366 return false; 367 } else { 368 if (WARN_ON_ONCE(request->layer_masks || 369 request->all_existing_optional_access)) 370 return false; 371 } 372 373 if (WARN_ON_ONCE(!!request->layer_masks ^ !!request->layer_masks_size)) 374 return false; 375 376 if (request->deny_masks) { 377 if (WARN_ON_ONCE(!request->all_existing_optional_access)) 378 return false; 379 } 380 381 return true; 382 } 383 384 /** 385 * landlock_log_denial - Create audit records related to a denial 386 * 387 * @subject: The Landlock subject's credential denying an action. 388 * @request: Detail of the user space request. 389 */ 390 void landlock_log_denial(const struct landlock_cred_security *const subject, 391 const struct landlock_request *const request) 392 { 393 struct audit_buffer *ab; 394 struct landlock_hierarchy *youngest_denied; 395 size_t youngest_layer; 396 access_mask_t missing; 397 398 if (WARN_ON_ONCE(!subject || !subject->domain || 399 !subject->domain->hierarchy || !request)) 400 return; 401 402 if (!is_valid_request(request)) 403 return; 404 405 missing = request->access; 406 if (missing) { 407 /* Gets the nearest domain that denies the request. */ 408 if (request->layer_masks) { 409 youngest_layer = get_denied_layer( 410 subject->domain, &missing, request->layer_masks, 411 request->layer_masks_size); 412 } else { 413 youngest_layer = get_layer_from_deny_masks( 414 &missing, request->all_existing_optional_access, 415 request->deny_masks); 416 } 417 youngest_denied = 418 get_hierarchy(subject->domain, youngest_layer); 419 } else { 420 youngest_layer = request->layer_plus_one - 1; 421 youngest_denied = 422 get_hierarchy(subject->domain, youngest_layer); 423 } 424 425 if (READ_ONCE(youngest_denied->log_status) == LANDLOCK_LOG_DISABLED) 426 return; 427 428 /* 429 * Consistently keeps track of the number of denied access requests 430 * even if audit is currently disabled, or if audit rules currently 431 * exclude this record type, or if landlock_restrict_self(2)'s flags 432 * quiet logs. 433 */ 434 atomic64_inc(&youngest_denied->num_denials); 435 436 if (!audit_enabled) 437 return; 438 439 /* Checks if the current exec was restricting itself. */ 440 if (subject->domain_exec & (1 << youngest_layer)) { 441 /* Ignores denials for the same execution. */ 442 if (!youngest_denied->log_same_exec) 443 return; 444 } else { 445 /* Ignores denials after a new execution. */ 446 if (!youngest_denied->log_new_exec) 447 return; 448 } 449 450 /* Uses consistent allocation flags wrt common_lsm_audit(). */ 451 ab = audit_log_start(audit_context(), GFP_ATOMIC | __GFP_NOWARN, 452 AUDIT_LANDLOCK_ACCESS); 453 if (!ab) 454 return; 455 456 audit_log_format(ab, "domain=%llx blockers=", youngest_denied->id); 457 log_blockers(ab, request->type, missing); 458 audit_log_lsm_data(ab, &request->audit); 459 audit_log_end(ab); 460 461 /* Logs this domain the first time it shows in log. */ 462 log_domain(youngest_denied); 463 } 464 465 /** 466 * landlock_log_drop_domain - Create an audit record on domain deallocation 467 * 468 * @hierarchy: The domain's hierarchy being deallocated. 469 * 470 * Only domains which previously appeared in the audit logs are logged again. 471 * This is useful to know when a domain will never show again in the audit log. 472 * 473 * Called in a work queue scheduled by landlock_put_ruleset_deferred() called 474 * by hook_cred_free(). 475 */ 476 void landlock_log_drop_domain(const struct landlock_hierarchy *const hierarchy) 477 { 478 struct audit_buffer *ab; 479 480 if (WARN_ON_ONCE(!hierarchy)) 481 return; 482 483 if (!audit_enabled) 484 return; 485 486 /* Ignores domains that were not logged. */ 487 if (READ_ONCE(hierarchy->log_status) != LANDLOCK_LOG_RECORDED) 488 return; 489 490 /* 491 * If logging of domain allocation succeeded, warns about failure to log 492 * domain deallocation to highlight unbalanced domain lifetime logs. 493 */ 494 ab = audit_log_start(audit_context(), GFP_KERNEL, 495 AUDIT_LANDLOCK_DOMAIN); 496 if (!ab) 497 return; 498 499 audit_log_format(ab, "domain=%llx status=deallocated denials=%llu", 500 hierarchy->id, atomic64_read(&hierarchy->num_denials)); 501 audit_log_end(ab); 502 } 503 504 #ifdef CONFIG_SECURITY_LANDLOCK_KUNIT_TEST 505 506 static struct kunit_case test_cases[] = { 507 /* clang-format off */ 508 KUNIT_CASE(test_get_hierarchy), 509 KUNIT_CASE(test_get_denied_layer), 510 KUNIT_CASE(test_get_layer_from_deny_masks), 511 {} 512 /* clang-format on */ 513 }; 514 515 static struct kunit_suite test_suite = { 516 .name = "landlock_audit", 517 .test_cases = test_cases, 518 }; 519 520 kunit_test_suite(test_suite); 521 522 #endif /* CONFIG_SECURITY_LANDLOCK_KUNIT_TEST */ 523