/* 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 , sets 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 layer_mask_t (*const layer_masks)[],
size_t layer_masks_size);
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 */
Messung V0.5 in Prozent C=89 H=96 G=92
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-09-29)
¤
*© Formatika GbR, Deutschland