summaryrefslogtreecommitdiffstats
path: root/security/landlock/domain.h
diff options
context:
space:
mode:
authorEduard Zingerman <eddyz87@gmail.com>2026-09-04 17:05:56 -0700
committerAlexei Starovoitov <ast@kernel.org>2026-09-04 18:17:30 -0700
commit506ada89629ec7059b96ecfb0dc7d33ece0103ca (patch)
tree0b07297409b68d2333fb4f0eae7f3b072eb68d4c /security/landlock/domain.h
downloadlinux-stable-506ada89629ec7059b96ecfb0dc7d33ece0103ca.tar.gz
linux-stable-506ada89629ec7059b96ecfb0dc7d33ece0103ca.zip
bpf: mark a NULL kfunc argument precisegrafted
check_kfunc_arg() allows bpf_register_is_null() for nullable arguments w/o marking the underlying scalar register precise. Hence a checkpoint created on such a path would prune against arbitrary scalar value. Fixes: 3bda08b63670 ("bpf: Allow NULL buffers in bpf_dynptr_slice(_rw)") Signed-off-by: Eduard Zingerman <eddyz87@gmail.com> Link: https://lore.kernel.org/r/20260904-register-is-null-precise-fixes-v1-5-0f5a360ff15d@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Diffstat (limited to 'security/landlock/domain.h')
-rw-r--r--security/landlock/domain.h179
1 files changed, 179 insertions, 0 deletions
diff --git a/security/landlock/domain.h b/security/landlock/domain.h
new file mode 100644
index 000000000..2a1660e3d
--- /dev/null
+++ b/security/landlock/domain.h
@@ -0,0 +1,179 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Landlock - Domain management
+ *
+ * Copyright © 2016-2020 Mickaël Salaün <mic@digikod.net>
+ * Copyright © 2018-2020 ANSSI
+ * Copyright © 2024-2025 Microsoft Corporation
+ */
+
+#ifndef _SECURITY_LANDLOCK_DOMAIN_H
+#define _SECURITY_LANDLOCK_DOMAIN_H
+
+#include <linux/limits.h>
+#include <linux/mm.h>
+#include <linux/path.h>
+#include <linux/pid.h>
+#include <linux/refcount.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+
+#include "access.h"
+#include "audit.h"
+
+enum landlock_log_status {
+ LANDLOCK_LOG_PENDING = 0,
+ LANDLOCK_LOG_RECORDED,
+ LANDLOCK_LOG_DISABLED,
+};
+
+/**
+ * struct landlock_details - Domain's creation information
+ *
+ * Rarely accessed, mainly when logging the first domain's denial.
+ *
+ * The contained pointers are initialized at the domain creation time and never
+ * changed again.
+ */
+struct landlock_details {
+ /**
+ * @pid: PID of the task that initially restricted itself. It still
+ * identifies the same task. Keeping a reference to this PID ensures that
+ * it will not be recycled.
+ */
+ struct pid *pid;
+ /**
+ * @uid: UID of the task that initially restricted itself, at creation time.
+ */
+ uid_t uid;
+ /**
+ * @comm: Command line of the task that initially restricted itself, at
+ * creation time. Always NULL terminated.
+ */
+ char comm[TASK_COMM_LEN];
+ /**
+ * @exe_path: Executable path of the task that initially restricted
+ * itself, at creation time. Always NULL terminated, and never greater
+ * than LANDLOCK_PATH_MAX_SIZE.
+ */
+ char exe_path[];
+};
+
+/* Adds 11 extra characters for the potential " (deleted)" suffix. */
+#define LANDLOCK_PATH_MAX_SIZE (PATH_MAX + 11)
+
+/* Makes sure the greatest landlock_details can be allocated. */
+static_assert(struct_size_t(struct landlock_details, exe_path,
+ LANDLOCK_PATH_MAX_SIZE) <= KMALLOC_MAX_SIZE);
+
+/**
+ * struct landlock_hierarchy - Node in a domain hierarchy
+ */
+struct landlock_hierarchy {
+ /**
+ * @parent: Pointer to the parent node, or NULL if it is a root
+ * Landlock domain.
+ */
+ struct landlock_hierarchy *parent;
+ /**
+ * @usage: Number of potential children domains plus their parent
+ * domain.
+ */
+ refcount_t usage;
+
+#ifdef CONFIG_AUDIT
+ /**
+ * @log_status: Whether this domain should be logged or not. Because
+ * concurrent log entries may be created at the same time, it is still
+ * possible to have several domain records of the same domain.
+ */
+ enum landlock_log_status log_status;
+ /**
+ * @num_denials: Number of access requests denied by this domain.
+ * Masked (i.e. never logged) denials are still counted.
+ */
+ atomic64_t num_denials;
+ /**
+ * @id: Landlock domain ID, set once at domain creation time.
+ */
+ u64 id;
+ /**
+ * @details: Information about the related domain.
+ */
+ const struct landlock_details *details;
+ /**
+ * @log_same_exec: Set if the domain is *not* configured with
+ * %LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF. Set to true by default.
+ */
+ u32 log_same_exec : 1,
+ /**
+ * @log_new_exec: Set if the domain is configured with
+ * %LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON. Set to false by default.
+ */
+ log_new_exec : 1;
+ /**
+ * @quiet_masks: Bitmasks of access that should be quieted (i.e. not
+ * logged) if the related object is marked as quiet.
+ */
+ struct access_masks quiet_masks;
+#endif /* CONFIG_AUDIT */
+};
+
+#ifdef CONFIG_AUDIT
+
+deny_masks_t
+landlock_get_deny_masks(const access_mask_t all_existing_optional_access,
+ const access_mask_t optional_access,
+ const struct layer_masks *const masks);
+
+optional_access_t landlock_get_quiet_optional_accesses(
+ const access_mask_t all_existing_optional_access,
+ const deny_masks_t deny_masks, const struct layer_masks *const masks);
+
+int landlock_init_hierarchy_log(struct landlock_hierarchy *const hierarchy);
+
+static inline void
+landlock_free_hierarchy_details(struct landlock_hierarchy *const hierarchy)
+{
+ if (!hierarchy || !hierarchy->details)
+ return;
+
+ put_pid(hierarchy->details->pid);
+ kfree(hierarchy->details);
+}
+
+#else /* CONFIG_AUDIT */
+
+static inline int
+landlock_init_hierarchy_log(struct landlock_hierarchy *const hierarchy)
+{
+ return 0;
+}
+
+static inline void
+landlock_free_hierarchy_details(struct landlock_hierarchy *const hierarchy)
+{
+}
+
+#endif /* CONFIG_AUDIT */
+
+static inline void
+landlock_get_hierarchy(struct landlock_hierarchy *const hierarchy)
+{
+ if (hierarchy)
+ refcount_inc(&hierarchy->usage);
+}
+
+static inline void landlock_put_hierarchy(struct landlock_hierarchy *hierarchy)
+{
+ while (hierarchy && refcount_dec_and_test(&hierarchy->usage)) {
+ const struct landlock_hierarchy *const freeme = hierarchy;
+
+ landlock_log_drop_domain(hierarchy);
+ landlock_free_hierarchy_details(hierarchy);
+ hierarchy = hierarchy->parent;
+ kfree(freeme);
+ }
+}
+
+#endif /* _SECURITY_LANDLOCK_DOMAIN_H */