1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * Copyright © 2025 Microsoft Corporation 4 * Copyright © 2026 Cloudflare, Inc. 5 */ 6 7 #undef TRACE_SYSTEM 8 #define TRACE_SYSTEM landlock 9 10 #if !defined(_TRACE_LANDLOCK_H) || defined(TRACE_HEADER_MULTI_READ) 11 #define _TRACE_LANDLOCK_H 12 13 #include <linux/landlock.h> 14 #include <linux/string.h> 15 #include <linux/string_helpers.h> 16 #include <linux/tracepoint.h> 17 #include <linux/trace_seq.h> 18 19 struct dentry; 20 struct landlock_domain; 21 struct landlock_hierarchy; 22 struct landlock_rule; 23 struct landlock_ruleset; 24 struct path; 25 struct sock; 26 27 #ifdef CREATE_TRACE_POINTS 28 29 /* 30 * Escapes @len bytes of an untrusted string into the trace sequence @p so it 31 * cannot inject field separators or control characters into the ftrace text 32 * output, and can be unambiguously recovered. Called from the TP_printk() of 33 * the tracepoints that expose paths and process names. @len is passed by the 34 * caller (rather than derived with strlen()) so a name that is not 35 * NUL-terminated or carries embedded NUL bytes (an abstract socket name) is 36 * escaped in full instead of being truncated at the first NUL. 37 * 38 * Return: a pointer into @p's buffer, or NULL if @src is NULL or the buffer is 39 * exhausted (normal when the trace buffer is full). 40 */ 41 static inline const char * 42 __trace_print_untrusted_str(struct trace_seq *p, const char *src, size_t len) 43 { 44 int escaped_size; 45 char *buf; 46 size_t buf_size = seq_buf_get_buf(&p->seq, &buf); 47 const char *ret = trace_seq_buffer_ptr(p); 48 49 /* Buffer exhaustion is normal when the trace buffer is full. */ 50 if (!src || buf_size == 0) 51 return NULL; 52 53 escaped_size = 54 string_escape_mem(src, len, buf, buf_size, 55 ESCAPE_SPACE | ESCAPE_SPECIAL | ESCAPE_NAP | 56 ESCAPE_APPEND | ESCAPE_OCTAL, 57 " ='\"\\"); 58 if (unlikely(escaped_size >= buf_size)) { 59 /* We need some room for the final '\0'. */ 60 seq_buf_set_overflow(&p->seq); 61 p->full = 1; 62 return NULL; 63 } 64 seq_buf_commit(&p->seq, escaped_size); 65 trace_seq_putc(p, 0); 66 return ret; 67 } 68 69 /* 70 * Fills the dense per-domain-layer array layers (one access mask per layer, 71 * indexed by level - 1) from rule's sparse layer stack, keeping only the 72 * requested rights (access_request). Layers with no matching rule entry get 73 * a zero mask. Shared by the check_rule_fs and check_rule_net events. 74 * 75 * rule->layers is sorted by ascending level, with levels in the domain's 76 * [1, num_layers] range (see landlock_merge_ruleset()), so every entry maps 77 * to a slot. A leftover entry would be a malformed rule; the zero-filled 78 * slots keep the output and the array bounds safe regardless. 79 */ 80 static inline void 81 __trace_landlock_fill_layers(access_mask_t *const layers, 82 const size_t num_layers, 83 const struct landlock_rule *const rule, 84 const access_mask_t access_request) 85 { 86 size_t i = 0; 87 88 for (size_t level = 1; level <= num_layers; level++) { 89 access_mask_t grants = 0; 90 91 if (i < rule->num_layers && level == rule->layers[i].level) { 92 grants = rule->layers[i].access & access_request; 93 i++; 94 } 95 layers[level - 1] = grants; 96 } 97 98 /* A leftover entry means an out-of-range or unsorted rule level. */ 99 WARN_ON_ONCE(i < rule->num_layers); 100 } 101 102 /* 103 * Renders the dense per-domain-layer access array as symbolic flag names for 104 * the grants field: layers wrapped in "{}", flags within a layer joined by 105 * "|", layers separated by ",", an empty layer rendered as nothing. 106 * Open-codes the flag walk because trace_print_flags_seq() NUL-terminates per 107 * call and so cannot be chained into a single field. The shared names table 108 * covers every access right, so masked bits are always named. Returns the 109 * trace_seq position like __print_flags(). 110 */ 111 static inline const char *__trace_landlock_print_layers( 112 struct trace_seq *p, const access_mask_t *const layers, 113 const size_t num_layers, const struct trace_print_flags *const names, 114 const size_t names_size) 115 { 116 const char *const ret = trace_seq_buffer_ptr(p); 117 118 trace_seq_putc(p, '{'); 119 for (size_t i = 0; i < num_layers; i++) { 120 access_mask_t mask = layers[i]; 121 bool first = true; 122 123 if (i) 124 trace_seq_putc(p, ','); 125 for (size_t j = 0; mask && j < names_size; j++) { 126 if ((mask & names[j].mask) != names[j].mask) 127 continue; 128 if (!first) 129 trace_seq_putc(p, '|'); 130 trace_seq_puts(p, names[j].name); 131 mask &= ~names[j].mask; 132 first = false; 133 } 134 } 135 trace_seq_putc(p, '}'); 136 trace_seq_putc(p, 0); 137 return ret; 138 } 139 140 #endif /* CREATE_TRACE_POINTS */ 141 142 /* clang-format off */ 143 144 /* Maps a shared _LANDLOCK_*_NAMES entry to a __print_flags() pair. */ 145 #define _LANDLOCK_NAME_ENTRY(mask, name) { mask, name } 146 147 /** 148 * DOC: Landlock trace events 149 * 150 * These guarantees and constraints hold for every Landlock tracepoint. 151 * A new tracepoint must uphold them, and an eBPF consumer can rely on 152 * them. 153 * 154 * Lifecycle consistency 155 * ~~~~~~~~~~~~~~~~~~~~~~ 156 * 157 * Lifecycle events are balanced: a creation event always has a matching 158 * deallocation event and vice versa, so an eBPF program can model object 159 * lifetimes from the trace stream without reconciliation logic. A creation 160 * event fires while the object is still private to the calling thread 161 * (landlock_create_ruleset fires before the ruleset's file descriptor is 162 * installed, so it cannot race a concurrent :manpage:`close(2)`); if fd 163 * installation later fails and the ruleset is freed, free_ruleset still 164 * fires, keeping the pair balanced. The domain pair (create_domain and 165 * free_domain) is balanced the same way: create_domain fires when the 166 * domain is created (under the ruleset lock, before thread-sync), and 167 * free_domain fires when it is freed. A rare thread-sync failure aborts 168 * the just-created domain, which then emits both events (its creation, then 169 * an immediate free). Denial events fire only for denials that actually 170 * happen. 171 * 172 * Pointer access 173 * ~~~~~~~~~~~~~~ 174 * 175 * All pointer arguments in TP_PROTO are guaranteed non-NULL by the 176 * caller, but pointers reached through them may still be NULL (e.g., 177 * hierarchy->parent at a root domain) and must be checked. eBPF programs 178 * read these pointers via BTF for richer introspection than the 179 * TP_STRUCT__entry fields, which serve TP_printk display only. 180 * 181 * Mutable object pointers are passed while the caller holds the object's 182 * lock, so TP_fast_assign and a BTF reader see the exact object the event 183 * reports, a snapshot no concurrent writer can change: add_rule holds the 184 * modified ruleset's lock, and create_domain holds the ruleset lock across 185 * the emission (before the thread-sync wait) so the inspected ruleset is 186 * the one merged into the domain. Objects immutable at the emission site 187 * (a domain after creation, a hierarchy at its last reference) need no 188 * lock. A few values that no held lock protects are a best-effort 189 * lockless snapshot instead: a task's comm, and the deny_access_net struct 190 * sock (whose network hook holds no socket lock), matching how the sched 191 * and signal trace events sample comm. 192 * 193 * Field encoding 194 * ~~~~~~~~~~~~~~ 195 * 196 * Fields that mirror the Landlock UAPI use the same C types and endianness 197 * (e.g. network ports are __u64 in host endianness, like 198 * landlock_net_port_attr.port). Per-event details, such as where a value 199 * is byte-swapped, live in the field's own kdoc. 200 * 201 * Rule-check fields 202 * ~~~~~~~~~~~~~~~~~ 203 * 204 * The check_rule events fire during an access check, once per matching 205 * rule, before the final allow-or-deny verdict. They share domain (the 206 * enforcing domain being evaluated), access_request (the access mask being 207 * checked), and rule (the matching rule, with per-layer access masks). 208 * 209 * Denial fields 210 * ~~~~~~~~~~~~~ 211 * 212 * Every denial event shares three fields. domain is the ID of the 213 * innermost domain that blocked the access. same_exec tells whether the 214 * current task is the same executable that entered that domain. logged is 215 * the domain's audit-logging decision for this denial (its log_status is 216 * enabled and the per-execution flag selected by same_exec is set); a 217 * stateless ftrace filter can select the denials the domain submits to 218 * audit with logged==1, without reconstructing it from the per-execution 219 * log flags. Denial events order their fields as domain, same_exec, 220 * logged, then blockers (deny_access events only), then the type-specific 221 * object fields, then any variable-length field. 222 */ 223 224 /* 225 * Prints a per-layer access mask array (the dynamic array @array) as symbolic 226 * flag names using the shared @flag_names list (a _LANDLOCK_*_NAMES macro). 227 * Stays outside CREATE_TRACE_POINTS: TP_printk is expanded in the print-output 228 * pass where that macro is undefined. 229 */ 230 #define __print_landlock_layers(array, flag_names...) \ 231 ({ \ 232 static const struct trace_print_flags __layer_names[] = { \ 233 flag_names \ 234 }; \ 235 __trace_landlock_print_layers( \ 236 p, __get_dynamic_array(array), \ 237 __get_dynamic_array_len(array) / \ 238 sizeof(access_mask_t), \ 239 __layer_names, ARRAY_SIZE(__layer_names)); \ 240 }) 241 242 /** 243 * landlock_create_ruleset - New ruleset created 244 * 245 * @ruleset: Newly created ruleset (never NULL); not yet shared via an fd, 246 * so no lock is needed. 247 * 248 * Emitted by sys_landlock_create_ruleset() while the new ruleset is still 249 * private to the calling thread, before its file descriptor is installed, 250 * so it cannot race a concurrent :manpage:`close(2)`. Balanced by a 251 * matching landlock_free_ruleset event. 252 */ 253 TRACE_EVENT(landlock_create_ruleset, 254 255 TP_PROTO(const struct landlock_ruleset *ruleset), 256 257 TP_ARGS(ruleset), 258 259 TP_STRUCT__entry( 260 __field( __u64, ruleset_id ) 261 __field( __u32, ruleset_version ) 262 __field( access_mask_t, handled_fs ) 263 __field( access_mask_t, handled_net ) 264 __field( access_mask_t, scoped ) 265 ), 266 267 TP_fast_assign( 268 __entry->ruleset_id = ruleset->id; 269 __entry->ruleset_version = ruleset->version; 270 __entry->handled_fs = ruleset->handled_masks.fs; 271 __entry->handled_net = ruleset->handled_masks.net; 272 __entry->scoped = ruleset->handled_masks.scope; 273 ), 274 275 TP_printk("ruleset=%llx.%u handled_fs=%s handled_net=%s scoped=%s", 276 __entry->ruleset_id, __entry->ruleset_version, 277 __print_flags(__entry->handled_fs, "|", _LANDLOCK_ACCESS_FS_NAMES), 278 __print_flags(__entry->handled_net, "|", _LANDLOCK_ACCESS_NET_NAMES), 279 __print_flags(__entry->scoped, "|", _LANDLOCK_SCOPE_NAMES)) 280 ); 281 282 /** 283 * landlock_free_ruleset - Ruleset freed 284 * 285 * @ruleset: Ruleset being freed (never NULL); at its last reference, so no 286 * lock is needed. 287 * 288 * Emitted when a ruleset's last reference is dropped (typically when 289 * the creating process closes the ruleset file descriptor). Fires even 290 * when file-descriptor installation failed after creation, keeping the 291 * create/free pair balanced. 292 */ 293 TRACE_EVENT(landlock_free_ruleset, 294 295 TP_PROTO(const struct landlock_ruleset *ruleset), 296 297 TP_ARGS(ruleset), 298 299 TP_STRUCT__entry( 300 __field( __u64, ruleset_id ) 301 __field( __u32, ruleset_version ) 302 ), 303 304 TP_fast_assign( 305 __entry->ruleset_id = ruleset->id; 306 __entry->ruleset_version = ruleset->version; 307 ), 308 309 TP_printk("ruleset=%llx.%u", 310 __entry->ruleset_id, __entry->ruleset_version) 311 ); 312 313 /** 314 * landlock_add_rule_fs - Filesystem rule added to a ruleset 315 * 316 * @ruleset: Source ruleset (never NULL). 317 * @access_rights: Effective access mask stored in the rule, not the raw 318 * sys_landlock_add_rule() argument (unhandled rights 319 * added). 320 * @path: Filesystem path for the rule (never NULL). 321 * @pathname: Resolved absolute path string (never NULL; error placeholder 322 * on resolution failure). 323 * 324 * Emitted by sys_landlock_add_rule() under the modified ruleset's lock, so 325 * the reported ruleset is a stable snapshot that no concurrent writer can 326 * change. 327 */ 328 TRACE_EVENT(landlock_add_rule_fs, 329 330 TP_PROTO(const struct landlock_ruleset *ruleset, 331 access_mask_t access_rights, const struct path *path, 332 const char *pathname), 333 334 TP_ARGS(ruleset, access_rights, path, pathname), 335 336 TP_STRUCT__entry( 337 __field( __u64, ruleset_id ) 338 __field( __u32, ruleset_version ) 339 __field( access_mask_t, access_rights ) 340 __field( dev_t, dev ) 341 __field( ino_t, ino ) 342 __string( pathname, pathname ) 343 ), 344 345 TP_fast_assign( 346 lockdep_assert_held(&ruleset->lock); 347 __entry->ruleset_id = ruleset->id; 348 __entry->ruleset_version = ruleset->version; 349 __entry->access_rights = access_rights; 350 __entry->dev = path->dentry->d_sb->s_dev; 351 /* 352 * The inode number may not be the user-visible one, 353 * but it will be the same used by audit. 354 */ 355 __entry->ino = d_backing_inode(path->dentry)->i_ino; 356 __assign_str(pathname); 357 ), 358 359 TP_printk("ruleset=%llx.%u access_rights=%s dev=%u:%u ino=%lu path=%s", 360 __entry->ruleset_id, __entry->ruleset_version, 361 __print_flags(__entry->access_rights, "|", _LANDLOCK_ACCESS_FS_NAMES), 362 MAJOR(__entry->dev), MINOR(__entry->dev), __entry->ino, 363 __trace_print_untrusted_str(p, __get_str(pathname), 364 __get_dynamic_array_len(pathname) - 1)) 365 ); 366 367 /** 368 * landlock_add_rule_net - Network port rule added to a ruleset 369 * 370 * @ruleset: Source ruleset (never NULL). 371 * @access_rights: Effective access mask stored in the rule, not the raw 372 * sys_landlock_add_rule() argument (unhandled rights 373 * added). 374 * @port: Network port, the landlock_net_port_attr.port UAPI value 375 * forwarded directly. 376 * 377 * Emitted by sys_landlock_add_rule() under the modified ruleset's lock, so 378 * the reported ruleset is a stable snapshot that no concurrent writer can 379 * change. 380 */ 381 TRACE_EVENT(landlock_add_rule_net, 382 383 TP_PROTO(const struct landlock_ruleset *ruleset, 384 access_mask_t access_rights, __u64 port), 385 386 TP_ARGS(ruleset, access_rights, port), 387 388 TP_STRUCT__entry( 389 __field( __u64, ruleset_id ) 390 __field( __u32, ruleset_version ) 391 __field( access_mask_t, access_rights ) 392 __field( __u64, port ) 393 ), 394 395 TP_fast_assign( 396 lockdep_assert_held(&ruleset->lock); 397 __entry->ruleset_id = ruleset->id; 398 __entry->ruleset_version = ruleset->version; 399 __entry->access_rights = access_rights; 400 __entry->port = port; 401 ), 402 403 TP_printk("ruleset=%llx.%u access_rights=%s port=%llu", 404 __entry->ruleset_id, __entry->ruleset_version, 405 __print_flags(__entry->access_rights, "|", _LANDLOCK_ACCESS_NET_NAMES), 406 __entry->port) 407 ); 408 409 /** 410 * landlock_create_domain - New domain created 411 * 412 * @domain: Newly created domain (never NULL, immutable after creation). 413 * @domain->hierarchy->id is its unique ID, shared with the 414 * landlock_enforce_domain and landlock_free_domain events; 415 * @domain->hierarchy->details holds the requesting process. 416 * @ruleset: Source ruleset frozen into the domain (never NULL). The 417 * ruleset lock is held across the emission, so a BPF program 418 * reading it via BTF sees the exact merged ruleset; 419 * @ruleset->id / @ruleset->version identify it. 420 * 421 * Emitted by sys_landlock_restrict_self() once, in the requesting 422 * thread's context, right after the merge and before thread-sync. The 423 * flags-only path (ruleset_fd == -1) creates no domain and does not 424 * emit this event. Paired with the per-thread landlock_enforce_domain 425 * (join on @domain->hierarchy->id) and balanced by a matching 426 * landlock_free_domain event. 427 */ 428 TRACE_EVENT(landlock_create_domain, 429 430 TP_PROTO(const struct landlock_domain *domain, 431 const struct landlock_ruleset *ruleset), 432 433 TP_ARGS(domain, ruleset), 434 435 TP_STRUCT__entry( 436 __field( __u64, domain_id ) 437 __field( __u64, parent_id ) 438 __field( __u64, ruleset_id ) 439 __field( __u32, ruleset_version ) 440 ), 441 442 TP_fast_assign( 443 lockdep_assert_held(&ruleset->lock); 444 __entry->domain_id = domain->hierarchy->id; 445 __entry->parent_id = domain->hierarchy->parent ? 446 domain->hierarchy->parent->id : 0; 447 __entry->ruleset_id = ruleset->id; 448 __entry->ruleset_version = ruleset->version; 449 ), 450 451 TP_printk("domain=%llx parent=%llx ruleset=%llx.%u", 452 __entry->domain_id, __entry->parent_id, 453 __entry->ruleset_id, __entry->ruleset_version) 454 ); 455 456 /** 457 * landlock_enforce_domain - Domain enforced on a thread 458 * 459 * @domain: Domain now enforced on the current thread (never NULL, 460 * immutable; read locklessly). Correlate to 461 * landlock_create_domain via @domain->hierarchy->id for the 462 * source ruleset and requesting thread, or read 463 * @domain->hierarchy->details for the requesting process. 464 * @complete: Set on the single event that concludes the operation, after 465 * all its other enforcements; filter on it for one event per 466 * operation. 467 * @process_wide: The enforcement covers every eligible (non-exiting) 468 * thread of the process: set when the caller used 469 * %LANDLOCK_RESTRICT_SELF_TSYNC or the process is 470 * single-threaded. A lone thread whose group still 471 * holds a zombie leader is not counted single-threaded, 472 * so process_wide == 0 never proves the opposite. 473 * @no_new_privs: The enforcing thread's no_new_privs state at 474 * enforcement time: 1 if set (by a prior 475 * :manpage:`prctl(2)` %PR_SET_NO_NEW_PRIVS or by 476 * %LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS), 0 if the domain 477 * was enforced with %CAP_SYS_ADMIN instead. 478 * 479 * Emitted for each thread sys_landlock_restrict_self() enforces the 480 * domain on, in that thread's own context, right after its 481 * commit_creds(), so it fires only once the thread is irreversibly 482 * enforcing the domain (aborted operations emit none). Not 483 * balanced; every enforcement falls between the domain's 484 * landlock_create_domain and landlock_free_domain events. 485 * 486 * @complete == 1 && @process_wide == 1 means the whole process is 487 * sandboxed by @domain, durably (Landlock domains are monotonic and 488 * inherited on :manpage:`clone(2)`). 489 */ 490 TRACE_EVENT(landlock_enforce_domain, 491 492 TP_PROTO(const struct landlock_domain *domain, bool complete, 493 bool process_wide, bool no_new_privs), 494 495 TP_ARGS(domain, complete, process_wide, no_new_privs), 496 497 TP_STRUCT__entry( 498 __field( __u64, domain_id ) 499 __field( bool, complete ) 500 __field( bool, process_wide ) 501 __field( bool, no_new_privs ) 502 ), 503 504 TP_fast_assign( 505 __entry->domain_id = domain->hierarchy->id; 506 __entry->complete = complete; 507 __entry->process_wide = process_wide; 508 __entry->no_new_privs = no_new_privs; 509 ), 510 511 TP_printk("domain=%llx complete=%d process_wide=%d no_new_privs=%d", 512 __entry->domain_id, __entry->complete, __entry->process_wide, 513 __entry->no_new_privs) 514 ); 515 516 /** 517 * landlock_free_domain - Domain freed 518 * 519 * @hierarchy: Hierarchy node being freed (never NULL). 520 * 521 * Emitted when the hierarchy node's last reference is dropped: its 522 * refcount reaches zero after all child domains have released their 523 * parent reference. A committed domain is 524 * freed from a kworker via landlock_put_domain_deferred() (the credential 525 * free path runs in RCU context, where sleeping is forbidden), so the 526 * current task is not the sandboxed task that triggered the free. Balanced 527 * by a matching landlock_create_domain event. 528 */ 529 TRACE_EVENT(landlock_free_domain, 530 531 TP_PROTO(const struct landlock_hierarchy *hierarchy), 532 533 TP_ARGS(hierarchy), 534 535 TP_STRUCT__entry( 536 __field( __u64, domain_id ) 537 __field( __u64, denials ) 538 ), 539 540 TP_fast_assign( 541 __entry->domain_id = hierarchy->id; 542 __entry->denials = atomic64_read(&hierarchy->num_denials); 543 ), 544 545 TP_printk("domain=%llx denials=%llu", 546 __entry->domain_id, __entry->denials) 547 ); 548 549 /** 550 * landlock_check_rule_fs - Filesystem rule evaluated during access check 551 * 552 * @domain: Enforcing domain (never NULL). 553 * @rule: Matching rule with per-layer access masks (never NULL). 554 * @access_request: Access mask evaluated against the rule (the domain's 555 * handled mask during rename/link double-checks). 556 * @dentry: Filesystem dentry being checked (never NULL). 557 * 558 * Emitted for each rule that matches during a filesystem access check. 559 * The grants array shows the requested rights the rule grants at each 560 * domain layer. See Documentation/trace/events-landlock.rst for how to 561 * interpret it. 562 */ 563 TRACE_EVENT(landlock_check_rule_fs, 564 565 TP_PROTO(const struct landlock_domain *domain, 566 const struct landlock_rule *rule, 567 access_mask_t access_request, const struct dentry *dentry), 568 569 TP_ARGS(domain, rule, access_request, dentry), 570 571 TP_STRUCT__entry( 572 __field( __u64, domain_id ) 573 __field( access_mask_t, access_request ) 574 __field( dev_t, dev ) 575 __field( ino_t, ino ) 576 __dynamic_array(access_mask_t, grants, 577 domain->num_layers) 578 ), 579 580 TP_fast_assign( 581 __entry->domain_id = domain->hierarchy->id; 582 __entry->access_request = access_request; 583 __entry->dev = dentry->d_sb->s_dev; 584 __entry->ino = d_backing_inode(dentry)->i_ino; 585 586 __trace_landlock_fill_layers(__get_dynamic_array(grants), 587 __get_dynamic_array_len(grants) / 588 sizeof(access_mask_t), 589 rule, access_request); 590 ), 591 592 TP_printk("domain=%llx access_request=%s dev=%u:%u ino=%lu grants=%s", 593 __entry->domain_id, 594 __print_flags(__entry->access_request, "|", _LANDLOCK_ACCESS_FS_NAMES), 595 MAJOR(__entry->dev), MINOR(__entry->dev), __entry->ino, 596 __print_landlock_layers(grants, _LANDLOCK_ACCESS_FS_NAMES)) 597 ); 598 599 /** 600 * landlock_check_rule_net - Network port rule evaluated during access check 601 * 602 * @domain: Enforcing domain (never NULL). 603 * @rule: Matching rule with per-layer access masks (never NULL). 604 * @access_request: Access mask being requested. 605 * @port: Network port being checked (host endianness). 606 * 607 * Emitted for each rule that matches during a network access check. The 608 * grants array shows the requested rights the rule grants at each domain 609 * layer. See Documentation/trace/events-landlock.rst for how to 610 * interpret it. 611 */ 612 TRACE_EVENT(landlock_check_rule_net, 613 614 TP_PROTO(const struct landlock_domain *domain, 615 const struct landlock_rule *rule, 616 access_mask_t access_request, __u64 port), 617 618 TP_ARGS(domain, rule, access_request, port), 619 620 TP_STRUCT__entry( 621 __field( __u64, domain_id ) 622 __field( access_mask_t, access_request ) 623 __field( __u64, port ) 624 __dynamic_array(access_mask_t, grants, 625 domain->num_layers) 626 ), 627 628 TP_fast_assign( 629 __entry->domain_id = domain->hierarchy->id; 630 __entry->access_request = access_request; 631 __entry->port = port; 632 633 __trace_landlock_fill_layers(__get_dynamic_array(grants), 634 __get_dynamic_array_len(grants) / 635 sizeof(access_mask_t), 636 rule, access_request); 637 ), 638 639 TP_printk("domain=%llx access_request=%s port=%llu grants=%s", 640 __entry->domain_id, 641 __print_flags(__entry->access_request, "|", _LANDLOCK_ACCESS_NET_NAMES), 642 __entry->port, 643 __print_landlock_layers(grants, _LANDLOCK_ACCESS_NET_NAMES)) 644 ); 645 646 /** 647 * landlock_deny_access_fs - Filesystem access denied 648 * 649 * @hierarchy: Denying domain's hierarchy node (never NULL); its id is the 650 * domain field. 651 * @same_exec: Whether the current task entered the denying domain itself. 652 * @logged: The domain's audit-logging decision for this denial. 653 * @blockers: Access mask that was blocked (zero for a mount-topology 654 * change, whose only blocker is the operation itself). 655 * @path: Filesystem path that was denied (never NULL). 656 * @pathname: Resolved path string (never NULL; an error placeholder on 657 * resolution failure). 658 * 659 * Emitted when a Landlock domain denies a filesystem access. 660 */ 661 TRACE_EVENT(landlock_deny_access_fs, 662 663 TP_PROTO(const struct landlock_hierarchy *hierarchy, bool same_exec, 664 bool logged, access_mask_t blockers, const struct path *path, 665 const char *pathname), 666 667 TP_ARGS(hierarchy, same_exec, logged, blockers, path, pathname), 668 669 TP_STRUCT__entry( 670 __field( __u64, domain_id ) 671 __field( bool, same_exec ) 672 __field( bool, logged ) 673 __field( access_mask_t, blockers ) 674 __field( dev_t, dev ) 675 __field( ino_t, ino ) 676 __string( pathname, pathname ) 677 ), 678 679 TP_fast_assign( 680 const struct inode *inode = d_backing_inode(path->dentry); 681 682 __entry->domain_id = hierarchy->id; 683 __entry->same_exec = same_exec; 684 __entry->logged = logged; 685 __entry->blockers = blockers; 686 __entry->dev = path->dentry->d_sb->s_dev; 687 /* 688 * A negative dentry has no backing inode, so mirror the 689 * guard in dump_common_audit_data() and report inode 0. 690 */ 691 __entry->ino = inode ? inode->i_ino : 0; 692 __assign_str(pathname); 693 ), 694 695 TP_printk("domain=%llx same_exec=%d logged=%d blockers=%s dev=%u:%u ino=%lu path=%s", 696 __entry->domain_id, __entry->same_exec, __entry->logged, 697 __print_flags(__entry->blockers, "|", _LANDLOCK_ACCESS_FS_NAMES), 698 MAJOR(__entry->dev), MINOR(__entry->dev), __entry->ino, 699 __trace_print_untrusted_str(p, __get_str(pathname), 700 __get_dynamic_array_len(pathname) - 1)) 701 ); 702 703 /** 704 * landlock_deny_access_net - Network access denied 705 * 706 * @hierarchy: Denying domain's hierarchy node (never NULL); its id is the 707 * domain field. 708 * @same_exec: Whether the current task entered the denying domain itself. 709 * @logged: The domain's audit-logging decision for this denial. 710 * @blockers: Access mask that was blocked. 711 * @sk: Socket object (never NULL), read without a socket lock, so its 712 * fields are a best-effort snapshot. The denied endpoint is not 713 * available: the hook runs before :manpage:`bind(2)` / 714 * :manpage:`connect(2)` sets the socket addresses. 715 * @sport: Source port in host endianness, set for bind denials (zero for 716 * an autobind/ephemeral port); zero for connect and send denials. 717 * @dport: Destination port in host endianness, set for connect and send 718 * denials; zero for bind denials, and also zero for a UDP send to 719 * an AF_UNSPEC address on an IPv6 socket (indistinguishable from a 720 * real destination port 0). The bind-vs-connect direction is 721 * given by @blockers, not by which port is set. 722 * 723 * Emitted when a Landlock domain denies a network operation. 724 * 725 * The port fields are converted from the socket's network byte order to 726 * host endianness before emitting. 727 */ 728 TRACE_EVENT(landlock_deny_access_net, 729 730 TP_PROTO(const struct landlock_hierarchy *hierarchy, bool same_exec, 731 bool logged, access_mask_t blockers, const struct sock *sk, 732 __u64 sport, __u64 dport), 733 734 TP_ARGS(hierarchy, same_exec, logged, blockers, sk, sport, dport), 735 736 TP_STRUCT__entry( 737 __field( __u64, domain_id ) 738 __field( bool, same_exec ) 739 __field( bool, logged ) 740 __field( access_mask_t, blockers ) 741 __field( __u64, sport ) 742 __field( __u64, dport ) 743 ), 744 745 TP_fast_assign( 746 __entry->domain_id = hierarchy->id; 747 __entry->same_exec = same_exec; 748 __entry->logged = logged; 749 __entry->blockers = blockers; 750 __entry->sport = sport; 751 __entry->dport = dport; 752 ), 753 754 TP_printk("domain=%llx same_exec=%d logged=%d blockers=%s sport=%llu dport=%llu", 755 __entry->domain_id, __entry->same_exec, __entry->logged, 756 __print_flags(__entry->blockers, "|", _LANDLOCK_ACCESS_NET_NAMES), 757 __entry->sport, __entry->dport) 758 ); 759 760 #undef _LANDLOCK_NAME_ENTRY 761 762 #endif /* _TRACE_LANDLOCK_H */ 763 764 /* This part must be outside protection */ 765 #include <trace/define_trace.h> 766 767 /* clang-format on */ 768