diff options
Diffstat (limited to 'security')
| -rw-r--r-- | security/landlock/Kconfig | 2 | ||||
| -rw-r--r-- | security/landlock/Makefile | 2 | ||||
| -rw-r--r-- | security/landlock/ruleset.c | 8 | ||||
| -rw-r--r-- | security/landlock/ruleset.h | 9 | ||||
| -rw-r--r-- | security/landlock/syscalls.c | 11 | ||||
| -rw-r--r-- | security/landlock/trace.c | 17 |
6 files changed, 48 insertions, 1 deletions
diff --git a/security/landlock/Kconfig b/security/landlock/Kconfig index b4e7f0e9ba9b..7aeac29160e8 100644 --- a/security/landlock/Kconfig +++ b/security/landlock/Kconfig @@ -24,7 +24,7 @@ config SECURITY_LANDLOCK config SECURITY_LANDLOCK_LOG bool depends on SECURITY_LANDLOCK - default y if AUDIT + default y if AUDIT || TRACEPOINTS config SECURITY_LANDLOCK_KUNIT_TEST bool "KUnit tests for Landlock" if !KUNIT_ALL_TESTS diff --git a/security/landlock/Makefile b/security/landlock/Makefile index 2462e6c5921e..2711f4876939 100644 --- a/security/landlock/Makefile +++ b/security/landlock/Makefile @@ -18,3 +18,5 @@ landlock-$(CONFIG_SECURITY_LANDLOCK_LOG) += \ log.o landlock-$(CONFIG_AUDIT) += audit.o + +landlock-$(CONFIG_TRACEPOINTS) += trace.o diff --git a/security/landlock/ruleset.c b/security/landlock/ruleset.c index 2b74542ac3d1..30f3897a56d4 100644 --- a/security/landlock/ruleset.c +++ b/security/landlock/ruleset.c @@ -23,10 +23,13 @@ #include <uapi/linux/landlock.h> #include "access.h" +#include "id.h" #include "limits.h" #include "object.h" #include "ruleset.h" +#include <trace/events/landlock.h> + struct landlock_ruleset * landlock_create_ruleset(const access_mask_t fs_access_mask, const access_mask_t net_access_mask, @@ -50,6 +53,10 @@ landlock_create_ruleset(const access_mask_t fs_access_mask, new_ruleset->rules.root_net_port = RB_ROOT; #endif /* IS_ENABLED(CONFIG_INET) */ +#ifdef CONFIG_TRACEPOINTS + new_ruleset->id = landlock_get_id_range(1); +#endif /* CONFIG_TRACEPOINTS */ + /* Should already be checked in landlock_create_ruleset(). */ if (fs_access_mask) { const access_mask_t mask = fs_access_mask & @@ -325,6 +332,7 @@ void landlock_free_rules(struct landlock_rules *const rules) static void free_ruleset(struct landlock_ruleset *const ruleset) { might_sleep(); + trace_landlock_free_ruleset(ruleset); landlock_free_rules(&ruleset->rules); kfree(ruleset); } diff --git a/security/landlock/ruleset.h b/security/landlock/ruleset.h index 3a9fc39e947c..dcc363740b85 100644 --- a/security/landlock/ruleset.h +++ b/security/landlock/ruleset.h @@ -4,6 +4,7 @@ * * Copyright © 2016-2020 Mickaël Salaün <mic@digikod.net> * Copyright © 2018-2020 ANSSI + * Copyright © 2026 Cloudflare, Inc. */ #ifndef _SECURITY_LANDLOCK_RULESET_H @@ -164,6 +165,14 @@ struct landlock_ruleset { * @usage: Number of file descriptors referencing this ruleset. */ refcount_t usage; + +#ifdef CONFIG_TRACEPOINTS + /** + * @id: Unique identifier for this ruleset, used for tracing. + */ + u64 id; +#endif /* CONFIG_TRACEPOINTS */ + /** * @quiet_masks: Stores the quiet flags for an unmerged ruleset. For a * merged domain, this is stored in each layer's struct diff --git a/security/landlock/syscalls.c b/security/landlock/syscalls.c index 37cadb63db9f..7f168802b584 100644 --- a/security/landlock/syscalls.c +++ b/security/landlock/syscalls.c @@ -38,6 +38,8 @@ #include "setup.h" #include "tsync.h" +#include <trace/events/landlock.h> + static bool is_initialized(void) { if (likely(landlock_initialized)) @@ -281,6 +283,15 @@ SYSCALL_DEFINE3(landlock_create_ruleset, ruleset->quiet_masks.net = ruleset_attr.quiet_access_net; ruleset->quiet_masks.scope = ruleset_attr.quiet_scoped; + /* + * Emits before anon_inode_getfd() installs the file descriptor, while + * the ruleset is still private to this thread: no lock is needed, and + * the event cannot race a concurrent close() freeing the ruleset under + * the tracepoint's BTF read. This is the last point at which the + * ruleset is guaranteed alive and unshared. + */ + trace_landlock_create_ruleset(ruleset); + /* Creates anonymous FD referring to the ruleset. */ ruleset_fd = anon_inode_getfd("[landlock-ruleset]", &ruleset_fops, ruleset, O_RDWR | O_CLOEXEC); diff --git a/security/landlock/trace.c b/security/landlock/trace.c new file mode 100644 index 000000000000..aeb6eeebe42a --- /dev/null +++ b/security/landlock/trace.c @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Landlock - Tracepoint helpers + * + * Copyright © 2025 Microsoft Corporation + * Copyright © 2026 Cloudflare, Inc. + */ + +#include "ruleset.h" + +/* + * Generates the tracepoint definitions in this translation unit. The trace + * event header dereferences the traced objects in TP_fast_assign, so the full + * struct definitions (e.g. ruleset.h) must be included before it. + */ +#define CREATE_TRACE_POINTS +#include <trace/events/landlock.h> |
