/* SPDX-License-Identifier: GPL-2.0-only */1/*2* Landlock - Domain management3*4* Copyright © 2016-2020 Mickaël Salaün <[email protected]>5* Copyright © 2018-2020 ANSSI6* Copyright © 2024-2025 Microsoft Corporation7*/89#ifndef _SECURITY_LANDLOCK_DOMAIN_H10#define _SECURITY_LANDLOCK_DOMAIN_H1112#include <linux/limits.h>13#include <linux/mm.h>14#include <linux/path.h>15#include <linux/pid.h>16#include <linux/refcount.h>17#include <linux/sched.h>18#include <linux/slab.h>1920#include "access.h"21#include "audit.h"2223enum landlock_log_status {24LANDLOCK_LOG_PENDING = 0,25LANDLOCK_LOG_RECORDED,26LANDLOCK_LOG_DISABLED,27};2829/**30* struct landlock_details - Domain's creation information31*32* Rarely accessed, mainly when logging the first domain's denial.33*34* The contained pointers are initialized at the domain creation time and never35* changed again. Contrary to most other Landlock object types, this one is36* not allocated with GFP_KERNEL_ACCOUNT because its size may not be under the37* caller's control (e.g. unknown exe_path) and the data is not explicitly38* requested nor used by tasks.39*/40struct landlock_details {41/**42* @pid: PID of the task that initially restricted itself. It still43* identifies the same task. Keeping a reference to this PID ensures that44* it will not be recycled.45*/46struct pid *pid;47/**48* @uid: UID of the task that initially restricted itself, at creation time.49*/50uid_t uid;51/**52* @comm: Command line of the task that initially restricted itself, at53* creation time. Always NULL terminated.54*/55char comm[TASK_COMM_LEN];56/**57* @exe_path: Executable path of the task that initially restricted58* itself, at creation time. Always NULL terminated, and never greater59* than LANDLOCK_PATH_MAX_SIZE.60*/61char exe_path[];62};6364/* Adds 11 extra characters for the potential " (deleted)" suffix. */65#define LANDLOCK_PATH_MAX_SIZE (PATH_MAX + 11)6667/* Makes sure the greatest landlock_details can be allocated. */68static_assert(struct_size_t(struct landlock_details, exe_path,69LANDLOCK_PATH_MAX_SIZE) <= KMALLOC_MAX_SIZE);7071/**72* struct landlock_hierarchy - Node in a domain hierarchy73*/74struct landlock_hierarchy {75/**76* @parent: Pointer to the parent node, or NULL if it is a root77* Landlock domain.78*/79struct landlock_hierarchy *parent;80/**81* @usage: Number of potential children domains plus their parent82* domain.83*/84refcount_t usage;8586#ifdef CONFIG_AUDIT87/**88* @log_status: Whether this domain should be logged or not. Because89* concurrent log entries may be created at the same time, it is still90* possible to have several domain records of the same domain.91*/92enum landlock_log_status log_status;93/**94* @num_denials: Number of access requests denied by this domain.95* Masked (i.e. never logged) denials are still counted.96*/97atomic64_t num_denials;98/**99* @id: Landlock domain ID, sets once at domain creation time.100*/101u64 id;102/**103* @details: Information about the related domain.104*/105const struct landlock_details *details;106/**107* @log_same_exec: Set if the domain is *not* configured with108* %LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF. Set to true by default.109*/110u32 log_same_exec : 1,111/**112* @log_new_exec: Set if the domain is configured with113* %LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON. Set to false by default.114*/115log_new_exec : 1;116#endif /* CONFIG_AUDIT */117};118119#ifdef CONFIG_AUDIT120121deny_masks_t122landlock_get_deny_masks(const access_mask_t all_existing_optional_access,123const access_mask_t optional_access,124const layer_mask_t (*const layer_masks)[],125size_t layer_masks_size);126127int landlock_init_hierarchy_log(struct landlock_hierarchy *const hierarchy);128129static inline void130landlock_free_hierarchy_details(struct landlock_hierarchy *const hierarchy)131{132if (!hierarchy || !hierarchy->details)133return;134135put_pid(hierarchy->details->pid);136kfree(hierarchy->details);137}138139#else /* CONFIG_AUDIT */140141static inline int142landlock_init_hierarchy_log(struct landlock_hierarchy *const hierarchy)143{144return 0;145}146147static inline void148landlock_free_hierarchy_details(struct landlock_hierarchy *const hierarchy)149{150}151152#endif /* CONFIG_AUDIT */153154static inline void155landlock_get_hierarchy(struct landlock_hierarchy *const hierarchy)156{157if (hierarchy)158refcount_inc(&hierarchy->usage);159}160161static inline void landlock_put_hierarchy(struct landlock_hierarchy *hierarchy)162{163while (hierarchy && refcount_dec_and_test(&hierarchy->usage)) {164const struct landlock_hierarchy *const freeme = hierarchy;165166landlock_log_drop_domain(hierarchy);167landlock_free_hierarchy_details(hierarchy);168hierarchy = hierarchy->parent;169kfree(freeme);170}171}172173#endif /* _SECURITY_LANDLOCK_DOMAIN_H */174175176