| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- /* 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. Contrary to most other Landlock object types, this one is
- * not allocated with GFP_KERNEL_ACCOUNT because its size may not be under the
- * caller's control (e.g. unknown exe_path) and the data is not explicitly
- * requested nor used by tasks.
- */
- 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;
- #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_access_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 */
|