mirror of
https://github.com/torvalds/linux.git
synced 2026-03-08 01:04:41 +01:00
The layer masks data structure tracks the requested but unfulfilled access rights during an operation's security check. It stores one bit for each combination of access right and layer index. If the bit is set, that access right is not granted (yet) in the given layer and we have to traverse the path further upwards to grant it. Previously, the layer masks were stored as arrays mapping from access right indices to layer_mask_t. The layer_mask_t value then indicates all layers in which the given access right is still (tentatively) denied. This patch introduces struct layer_access_masks instead: This struct contains an array with the access_mask_t of each (tentatively) denied access right in that layer. The hypothesis of this patch is that this simplifies the code enough so that the resulting code will run faster: * We can use bitwise operations in multiple places where we previously looped over bits individually with macros. (Should require less branch speculation and lends itself to better loop unrolling.) * Code is ~75 lines smaller. Other noteworthy changes: * In no_more_access(), call a new helper function may_refer(), which only solves the asymmetric case. Previously, the code interleaved the checks for the two symmetric cases in RENAME_EXCHANGE. It feels that the code is clearer when renames without RENAME_EXCHANGE are more obviously the normal case. Tradeoffs: This change improves performance, at a slight size increase to the layer masks data structure. This fixes the size of the data structure at 32 bytes for all types of access rights. (64, once we introduce a 17th filesystem access right). For filesystem access rights, at the moment, the data structure has the same size as before, but once we introduce the 17th filesystem access right, it will double in size (from 32 to 64 bytes), as access_mask_t grows from 16 to 32 bit [1]. Link: https://lore.kernel.org/all/20260120.haeCh4li9Vae@digikod.net/ [1] Signed-off-by: Günther Noack <gnoack3000@gmail.com> Link: https://lore.kernel.org/r/20260206151154.97915-5-gnoack3000@gmail.com [mic: Cosmetic fixes, moved struct layer_access_masks definition] Signed-off-by: Mickaël Salaün <mic@digikod.net>
75 lines
1.8 KiB
C
75 lines
1.8 KiB
C
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
/*
|
|
* Landlock - Audit helpers
|
|
*
|
|
* Copyright © 2023-2025 Microsoft Corporation
|
|
*/
|
|
|
|
#ifndef _SECURITY_LANDLOCK_AUDIT_H
|
|
#define _SECURITY_LANDLOCK_AUDIT_H
|
|
|
|
#include <linux/audit.h>
|
|
#include <linux/lsm_audit.h>
|
|
|
|
#include "access.h"
|
|
#include "cred.h"
|
|
|
|
enum landlock_request_type {
|
|
LANDLOCK_REQUEST_PTRACE = 1,
|
|
LANDLOCK_REQUEST_FS_CHANGE_TOPOLOGY,
|
|
LANDLOCK_REQUEST_FS_ACCESS,
|
|
LANDLOCK_REQUEST_NET_ACCESS,
|
|
LANDLOCK_REQUEST_SCOPE_ABSTRACT_UNIX_SOCKET,
|
|
LANDLOCK_REQUEST_SCOPE_SIGNAL,
|
|
};
|
|
|
|
/*
|
|
* We should be careful to only use a variable of this type for
|
|
* landlock_log_denial(). This way, the compiler can remove it entirely if
|
|
* CONFIG_AUDIT is not set.
|
|
*/
|
|
struct landlock_request {
|
|
/* Mandatory fields. */
|
|
enum landlock_request_type type;
|
|
struct common_audit_data audit;
|
|
|
|
/**
|
|
* layer_plus_one: First layer level that denies the request + 1. The
|
|
* extra one is useful to detect uninitialized field.
|
|
*/
|
|
size_t layer_plus_one;
|
|
|
|
/* Required field for configurable access control. */
|
|
access_mask_t access;
|
|
|
|
/* Required fields for requests with layer masks. */
|
|
const struct layer_access_masks *layer_masks;
|
|
|
|
/* Required fields for requests with deny masks. */
|
|
const access_mask_t all_existing_optional_access;
|
|
deny_masks_t deny_masks;
|
|
};
|
|
|
|
#ifdef CONFIG_AUDIT
|
|
|
|
void landlock_log_drop_domain(const struct landlock_hierarchy *const hierarchy);
|
|
|
|
void landlock_log_denial(const struct landlock_cred_security *const subject,
|
|
const struct landlock_request *const request);
|
|
|
|
#else /* CONFIG_AUDIT */
|
|
|
|
static inline void
|
|
landlock_log_drop_domain(const struct landlock_hierarchy *const hierarchy)
|
|
{
|
|
}
|
|
|
|
static inline void
|
|
landlock_log_denial(const struct landlock_cred_security *const subject,
|
|
const struct landlock_request *const request)
|
|
{
|
|
}
|
|
|
|
#endif /* CONFIG_AUDIT */
|
|
|
|
#endif /* _SECURITY_LANDLOCK_AUDIT_H */
|