[PATCH v2 2/2] landlock: Refactor path access checks
Justin Suess
utilityemal77 at gmail.com
Tue Mar 3 04:05:40 UTC 2026
Introduce struct landlock_check to bundle per-check state,
refactor is_access_to_paths_allowed() and its callers,
inline collect_domain_accesses() into current_check_refer_path(),
and reuse current_check_access_path() for same-directory refer checks.
Signed-off-by: Justin Suess <utilityemal77 at gmail.com>
---
security/landlock/fs.c | 419 +++++++++++++++++------------------------
1 file changed, 175 insertions(+), 244 deletions(-)
diff --git a/security/landlock/fs.c b/security/landlock/fs.c
index 180ab149be74..7526414501ed 100644
--- a/security/landlock/fs.c
+++ b/security/landlock/fs.c
@@ -430,6 +430,14 @@ static const struct access_masks any_fs = {
.fs = ~0,
};
+struct landlock_check {
+ access_mask_t access_request;
+ access_mask_t access_masked;
+ struct layer_access_masks layer_masks;
+ struct landlock_request request;
+ bool allowed;
+};
+
/*
* Returns true iff the child file with the given src_child access rights under
* src_parent would result in having the same or fewer access rights if it were
@@ -734,28 +742,17 @@ static void test_is_eacces_with_write(struct kunit *const test)
* @domain: Domain to check against.
* @path: File hierarchy to walk through. For refer checks, this would be
* the common mountpoint.
- * @access_request_parent1: Accesses to check, once @layer_masks_parent1 is
- * equal to @layer_masks_parent2 (if any). This is tied to the unique
- * requested path for most actions, or the source in case of a refer action
- * (i.e. rename or link), or the source and destination in case of
- * RENAME_EXCHANGE.
- * @layer_masks_parent1: Pointer to a matrix of layer masks per access
- * masks, identifying the layers that forbid a specific access. Bits from
- * this matrix can be unset according to the @path walk. An empty matrix
- * means that @domain allows all possible Landlock accesses (i.e. not only
- * those identified by @access_request_parent1). This matrix can
- * initially refer to domain layer masks and, when the accesses for the
- * destination and source are the same, to requested layer masks.
- * @log_request_parent1: Audit request to fill if the related access is denied.
+ * @check_parent1: Accesses and associated metadata to check, once
+ * @check_parent1.layer_masks is equal to @check_parent2.layer_masks
+ * (if any). This is tied to the unique requested path for most actions,
+ * or the source in case of a refer action (i.e. rename or link), or the
+ * source and destination in case of RENAME_EXCHANGE.
* @dentry_child1: Dentry to the initial child of the parent1 path. This
* pointer must be NULL for non-refer actions (i.e. not link nor rename).
- * @access_request_parent2: Similar to @access_request_parent1 but for a
- * request involving a source and a destination. This refers to the
- * destination, except in case of RENAME_EXCHANGE where it also refers to
- * the source. Must be set to 0 when using a simple path request.
- * @layer_masks_parent2: Similar to @layer_masks_parent1 but for a refer
- * action. This must be NULL otherwise.
- * @log_request_parent2: Audit request to fill if the related access is denied.
+ * @check_parent2: Similar to @check_parent1 but for a request involving a
+ * source and a destination. This refers to the destination, except in
+ * case of RENAME_EXCHANGE where it also refers to the source. This must
+ * be NULL when using a simple path request.
* @dentry_child2: Dentry to the initial child of the parent2 path. This
* pointer is only set for RENAME_EXCHANGE actions and must be NULL
* otherwise.
@@ -773,24 +770,24 @@ static void test_is_eacces_with_write(struct kunit *const test)
static bool
is_access_to_paths_allowed(const struct landlock_ruleset *const domain,
const struct path *const path,
- const access_mask_t access_request_parent1,
- struct layer_access_masks *layer_masks_parent1,
- struct landlock_request *const log_request_parent1,
+ struct landlock_check *const check_parent1,
struct dentry *const dentry_child1,
- const access_mask_t access_request_parent2,
- struct layer_access_masks *layer_masks_parent2,
- struct landlock_request *const log_request_parent2,
+ struct landlock_check *const check_parent2,
struct dentry *const dentry_child2)
{
- bool allowed_parent1 = false, allowed_parent2 = false, is_dom_check,
- child1_is_directory = true, child2_is_directory = true;
+ struct landlock_check *const checks[] = {
+ check_parent1,
+ check_parent2,
+ };
+ struct layer_access_masks layer_masks_child[2] = {};
+ bool is_dom_check, child_is_directory[2] = { true, true };
struct path walker_path;
- access_mask_t access_masked_parent1, access_masked_parent2;
- struct layer_access_masks _layer_masks_child1, _layer_masks_child2;
- struct layer_access_masks *layer_masks_child1 = NULL,
- *layer_masks_child2 = NULL;
- if (!access_request_parent1 && !access_request_parent2)
+ if (WARN_ON_ONCE(!check_parent1))
+ return false;
+
+ if (!check_parent1->access_request &&
+ (!check_parent2 || !check_parent2->access_request))
return true;
if (WARN_ON_ONCE(!path))
@@ -799,51 +796,45 @@ is_access_to_paths_allowed(const struct landlock_ruleset *const domain,
if (is_nouser_or_private(path->dentry))
return true;
- if (WARN_ON_ONCE(!layer_masks_parent1))
- return false;
-
- allowed_parent1 = is_layer_masks_allowed(layer_masks_parent1);
+ check_parent1->allowed =
+ is_layer_masks_allowed(&check_parent1->layer_masks);
+ if (check_parent2)
+ check_parent2->allowed =
+ is_layer_masks_allowed(&check_parent2->layer_masks);
- if (unlikely(layer_masks_parent2)) {
+ if (unlikely(check_parent2)) {
if (WARN_ON_ONCE(!dentry_child1))
return false;
- allowed_parent2 = is_layer_masks_allowed(layer_masks_parent2);
-
/*
* For a double request, first check for potential privilege
* escalation by looking at domain handled accesses (which are
* a superset of the meaningful requested accesses).
*/
- access_masked_parent1 = access_masked_parent2 =
- landlock_union_access_masks(domain).fs;
+ for (size_t i = 0; i < ARRAY_SIZE(checks); i++)
+ checks[i]->access_masked =
+ landlock_union_access_masks(domain).fs;
is_dom_check = true;
} else {
if (WARN_ON_ONCE(dentry_child1 || dentry_child2))
return false;
/* For a simple request, only check for requested accesses. */
- access_masked_parent1 = access_request_parent1;
- access_masked_parent2 = access_request_parent2;
+ check_parent1->access_masked = check_parent1->access_request;
is_dom_check = false;
}
- if (unlikely(dentry_child1)) {
- if (landlock_init_layer_masks(domain, LANDLOCK_MASK_ACCESS_FS,
- &_layer_masks_child1,
- LANDLOCK_KEY_INODE))
- landlock_unmask_layers(find_rule(domain, dentry_child1),
- &_layer_masks_child1);
- layer_masks_child1 = &_layer_masks_child1;
- child1_is_directory = d_is_dir(dentry_child1);
- }
- if (unlikely(dentry_child2)) {
+ for (size_t i = 0; i < ARRAY_SIZE(layer_masks_child); i++) {
+ const struct dentry *const dentry_child =
+ i ? dentry_child2 : dentry_child1;
+
+ if (unlikely(!dentry_child))
+ continue;
if (landlock_init_layer_masks(domain, LANDLOCK_MASK_ACCESS_FS,
- &_layer_masks_child2,
+ &layer_masks_child[i],
LANDLOCK_KEY_INODE))
- landlock_unmask_layers(find_rule(domain, dentry_child2),
- &_layer_masks_child2);
- layer_masks_child2 = &_layer_masks_child2;
- child2_is_directory = d_is_dir(dentry_child2);
+ landlock_unmask_layers(find_rule(domain, dentry_child),
+ &layer_masks_child[i]);
+ child_is_directory[i] = d_is_dir(dentry_child);
}
walker_path = *path;
@@ -869,42 +860,47 @@ is_access_to_paths_allowed(const struct landlock_ruleset *const domain,
*/
if (unlikely(is_dom_check &&
no_more_access(
- layer_masks_parent1, layer_masks_child1,
- child1_is_directory, layer_masks_parent2,
- layer_masks_child2,
- child2_is_directory))) {
+ &check_parent1->layer_masks,
+ dentry_child1 ? &layer_masks_child[0] : NULL,
+ child_is_directory[0],
+ check_parent2 ?
+ &check_parent2->layer_masks :
+ NULL,
+ dentry_child2 ? &layer_masks_child[1] : NULL,
+ child_is_directory[1]))) {
/*
* Now, downgrades the remaining checks from domain
* handled accesses to requested accesses.
*/
is_dom_check = false;
- access_masked_parent1 = access_request_parent1;
- access_masked_parent2 = access_request_parent2;
-
- allowed_parent1 =
- allowed_parent1 ||
- scope_to_request(access_masked_parent1,
- layer_masks_parent1);
- allowed_parent2 =
- allowed_parent2 ||
- scope_to_request(access_masked_parent2,
- layer_masks_parent2);
+ for (size_t i = 0; i < ARRAY_SIZE(checks); i++) {
+ if (!checks[i])
+ continue;
+ checks[i]->access_masked = checks[i]->access_request;
+ checks[i]->allowed =
+ checks[i]->allowed ||
+ scope_to_request(checks[i]->access_masked,
+ &checks[i]->layer_masks);
+ }
/* Stops when all accesses are granted. */
- if (allowed_parent1 && allowed_parent2)
+ if (check_parent1->allowed &&
+ (!check_parent2 || check_parent2->allowed))
break;
}
rule = find_rule(domain, walker_path.dentry);
- allowed_parent1 =
- allowed_parent1 ||
- landlock_unmask_layers(rule, layer_masks_parent1);
- allowed_parent2 =
- allowed_parent2 ||
- landlock_unmask_layers(rule, layer_masks_parent2);
+ for (size_t i = 0; i < ARRAY_SIZE(checks); i++) {
+ if (!checks[i])
+ continue;
+ checks[i]->allowed =
+ checks[i]->allowed ||
+ landlock_unmask_layers(rule, &checks[i]->layer_masks);
+ }
/* Stops when a rule from each layer grants access. */
- if (allowed_parent1 && allowed_parent2)
+ if (check_parent1->allowed &&
+ (!check_parent2 || check_parent2->allowed))
break;
switch (landlock_walk_path_up(&walker_path)) {
/*
@@ -913,8 +909,9 @@ is_access_to_paths_allowed(const struct landlock_ruleset *const domain,
* which is reachable through /proc/<pid>/ns/<namespace>).
*/
case LANDLOCK_WALK_INTERNAL:
- allowed_parent1 = true;
- allowed_parent2 = true;
+ check_parent1->allowed = true;
+ if (check_parent2)
+ check_parent2->allowed = true;
break;
/*
* Stops at the real root. Denies access
@@ -931,28 +928,25 @@ is_access_to_paths_allowed(const struct landlock_ruleset *const domain,
path_put(&walker_path);
/*
- * Check CONFIG_AUDIT to enable elision of log_request_parent* and
- * associated caller's stack variables thanks to dead code elimination.
+ * Check CONFIG_AUDIT to enable elision of request fields and related
+ * caller stack usage thanks to dead code elimination.
*/
#ifdef CONFIG_AUDIT
- if (!allowed_parent1 && log_request_parent1) {
- log_request_parent1->type = LANDLOCK_REQUEST_FS_ACCESS;
- log_request_parent1->audit.type = LSM_AUDIT_DATA_PATH;
- log_request_parent1->audit.u.path = *path;
- log_request_parent1->access = access_masked_parent1;
- log_request_parent1->layer_masks = layer_masks_parent1;
- }
+ for (size_t i = 0; i < 2; i++) {
+ struct landlock_check *const check = checks[i];
+
+ if (!check || check->allowed)
+ continue;
- if (!allowed_parent2 && log_request_parent2) {
- log_request_parent2->type = LANDLOCK_REQUEST_FS_ACCESS;
- log_request_parent2->audit.type = LSM_AUDIT_DATA_PATH;
- log_request_parent2->audit.u.path = *path;
- log_request_parent2->access = access_masked_parent2;
- log_request_parent2->layer_masks = layer_masks_parent2;
+ check->request.type = LANDLOCK_REQUEST_FS_ACCESS;
+ check->request.audit.type = LSM_AUDIT_DATA_PATH;
+ check->request.audit.u.path = *path;
+ check->request.access = check->access_masked;
+ check->request.layer_masks = &check->layer_masks;
}
#endif /* CONFIG_AUDIT */
- return allowed_parent1 && allowed_parent2;
+ return check_parent1->allowed && (!check_parent2 || check_parent2->allowed);
}
static int current_check_access_path(const struct path *const path,
@@ -963,21 +957,22 @@ static int current_check_access_path(const struct path *const path,
};
const struct landlock_cred_security *const subject =
landlock_get_applicable_subject(current_cred(), masks, NULL);
- struct layer_access_masks layer_masks;
- struct landlock_request request = {};
+ struct landlock_check check = {
+ .access_request = access_request,
+ };
if (!subject)
return 0;
- access_request = landlock_init_layer_masks(subject->domain,
- access_request, &layer_masks,
- LANDLOCK_KEY_INODE);
- if (is_access_to_paths_allowed(subject->domain, path, access_request,
- &layer_masks, &request, NULL, 0, NULL,
+ check.access_request =
+ landlock_init_layer_masks(subject->domain, check.access_request,
+ &check.layer_masks,
+ LANDLOCK_KEY_INODE);
+ if (is_access_to_paths_allowed(subject->domain, path, &check, NULL,
NULL, NULL))
return 0;
- landlock_log_denial(subject, &request);
+ landlock_log_denial(subject, &check.request);
return -EACCES;
}
@@ -1013,77 +1008,6 @@ static access_mask_t maybe_remove(const struct dentry *const dentry)
LANDLOCK_ACCESS_FS_REMOVE_FILE;
}
-/**
- * collect_domain_accesses - Walk through a file path and collect accesses
- *
- * @domain: Domain to check against.
- * @mnt_root: Last directory to check.
- * @dir: Directory to start the walk from.
- * @layer_masks_dom: Where to store the collected accesses.
- *
- * This helper is useful to begin a path walk from the @dir directory to a
- * @mnt_root directory used as a mount point. This mount point is the common
- * ancestor between the source and the destination of a renamed and linked
- * file. While walking from @dir to @mnt_root, we record all the domain's
- * allowed accesses in @layer_masks_dom.
- *
- * Because of disconnected directories, this walk may not reach @mnt_dir. In
- * this case, the walk will continue to @mnt_dir after this call.
- *
- * This is similar to is_access_to_paths_allowed() but much simpler because it
- * only handles walking on the same mount point and only checks one set of
- * accesses.
- *
- * Returns:
- * - true if all the domain access rights are allowed for @dir;
- * - false if the walk reached @mnt_root.
- */
-static bool collect_domain_accesses(const struct landlock_ruleset *const domain,
- const struct dentry *const mnt_root,
- struct dentry *dir,
- struct layer_access_masks *layer_masks_dom)
-{
- bool ret = false;
-
- if (WARN_ON_ONCE(!domain || !mnt_root || !dir || !layer_masks_dom))
- return true;
- if (is_nouser_or_private(dir))
- return true;
-
- if (!landlock_init_layer_masks(domain, LANDLOCK_MASK_ACCESS_FS,
- layer_masks_dom, LANDLOCK_KEY_INODE))
- return true;
-
- dget(dir);
- while (true) {
- struct dentry *parent_dentry;
-
- /* Gets all layers allowing all domain accesses. */
- if (landlock_unmask_layers(find_rule(domain, dir),
- layer_masks_dom)) {
- /*
- * Stops when all handled accesses are allowed by at
- * least one rule in each layer.
- */
- ret = true;
- break;
- }
-
- /*
- * Stops at the mount point or the filesystem root for a disconnected
- * directory.
- */
- if (dir == mnt_root || unlikely(IS_ROOT(dir)))
- break;
-
- parent_dentry = dget_parent(dir);
- dput(dir);
- dir = parent_dentry;
- }
- dput(dir);
- return ret;
-}
-
/**
* current_check_refer_path - Check if a rename or link action is allowed
*
@@ -1144,32 +1068,24 @@ static int current_check_refer_path(struct dentry *const old_dentry,
{
const struct landlock_cred_security *const subject =
landlock_get_applicable_subject(current_cred(), any_fs, NULL);
- bool allow_parent1, allow_parent2;
- access_mask_t access_request_parent1, access_request_parent2;
struct path mnt_dir;
- struct dentry *old_parent;
- struct layer_access_masks layer_masks_parent1 = {},
- layer_masks_parent2 = {};
- struct landlock_request request1 = {}, request2 = {};
+ struct path old_parent_path;
+ struct landlock_check checks[2] = {};
if (!subject)
return 0;
if (unlikely(d_is_negative(old_dentry)))
return -ENOENT;
- if (exchange) {
- if (unlikely(d_is_negative(new_dentry)))
- return -ENOENT;
- access_request_parent1 =
- get_mode_access(d_backing_inode(new_dentry)->i_mode);
- } else {
- access_request_parent1 = 0;
- }
- access_request_parent2 =
+ if (exchange && unlikely(d_is_negative(new_dentry)))
+ return -ENOENT;
+ checks[0].access_request =
+ exchange ? get_mode_access(d_backing_inode(new_dentry)->i_mode) : 0;
+ checks[1].access_request =
get_mode_access(d_backing_inode(old_dentry)->i_mode);
if (removable) {
- access_request_parent1 |= maybe_remove(old_dentry);
- access_request_parent2 |= maybe_remove(new_dentry);
+ checks[0].access_request |= maybe_remove(old_dentry);
+ checks[1].access_request |= maybe_remove(new_dentry);
}
/* The mount points are the same for old and new paths, cf. EXDEV. */
@@ -1178,22 +1094,12 @@ static int current_check_refer_path(struct dentry *const old_dentry,
* The LANDLOCK_ACCESS_FS_REFER access right is not required
* for same-directory referer (i.e. no reparenting).
*/
- access_request_parent1 = landlock_init_layer_masks(
- subject->domain,
- access_request_parent1 | access_request_parent2,
- &layer_masks_parent1, LANDLOCK_KEY_INODE);
- if (is_access_to_paths_allowed(subject->domain, new_dir,
- access_request_parent1,
- &layer_masks_parent1, &request1,
- NULL, 0, NULL, NULL, NULL))
- return 0;
-
- landlock_log_denial(subject, &request1);
- return -EACCES;
+ return current_check_access_path(new_dir,
+ checks[0].access_request | checks[1].access_request);
}
- access_request_parent1 |= LANDLOCK_ACCESS_FS_REFER;
- access_request_parent2 |= LANDLOCK_ACCESS_FS_REFER;
+ checks[0].access_request |= LANDLOCK_ACCESS_FS_REFER;
+ checks[1].access_request |= LANDLOCK_ACCESS_FS_REFER;
/* Saves the common mount point. */
mnt_dir.mnt = new_dir->mnt;
@@ -1202,21 +1108,46 @@ static int current_check_refer_path(struct dentry *const old_dentry,
/*
* old_dentry may be the root of the common mount point and
* !IS_ROOT(old_dentry) at the same time (e.g. with open_tree() and
- * OPEN_TREE_CLONE). We do not need to call dget(old_parent) because
+ * OPEN_TREE_CLONE). We do not need to path_get(old_parent_path) because
* we keep a reference to old_dentry.
*/
- old_parent = (old_dentry == mnt_dir.dentry) ? old_dentry :
- old_dentry->d_parent;
+ old_parent_path.mnt = mnt_dir.mnt;
+ old_parent_path.dentry = unlikely(old_dentry == mnt_dir.dentry) ?
+ old_dentry :
+ old_dentry->d_parent;
/* new_dir->dentry is equal to new_dentry->d_parent */
- allow_parent1 = collect_domain_accesses(subject->domain, mnt_dir.dentry,
- old_parent,
- &layer_masks_parent1);
- allow_parent2 = collect_domain_accesses(subject->domain, mnt_dir.dentry,
- new_dir->dentry,
- &layer_masks_parent2);
-
- if (allow_parent1 && allow_parent2)
+ for (size_t i = 0; i < 2; i++) {
+ struct path parent_path = i ? *new_dir : old_parent_path;
+ struct landlock_check *const check = &checks[i];
+
+ if (is_nouser_or_private(parent_path.dentry) ||
+ !landlock_init_layer_masks(subject->domain,
+ LANDLOCK_MASK_ACCESS_FS,
+ &check->layer_masks,
+ LANDLOCK_KEY_INODE)) {
+ check->allowed = true;
+ continue;
+ }
+ path_get(&parent_path);
+ do {
+ /* Gets all layers allowing all domain accesses. */
+ if (landlock_unmask_layers(find_rule(subject->domain,
+ parent_path.dentry),
+ &check->layer_masks)) {
+ /*
+ * Stops when all handled accesses are
+ * allowed by at least one rule in each
+ * layer.
+ */
+ check->allowed = true;
+ break;
+ }
+ } while (landlock_walk_path_up(&parent_path) ==
+ LANDLOCK_WALK_CONTINUE);
+ path_put(&parent_path);
+ }
+ if (checks[0].allowed && checks[1].allowed)
return 0;
/*
@@ -1226,27 +1157,26 @@ static int current_check_refer_path(struct dentry *const old_dentry,
* destination parent access rights.
*/
if (is_access_to_paths_allowed(
- subject->domain, &mnt_dir, access_request_parent1,
- &layer_masks_parent1, &request1, old_dentry,
- access_request_parent2, &layer_masks_parent2, &request2,
+ subject->domain, &mnt_dir, &checks[0], old_dentry,
+ &checks[1],
exchange ? new_dentry : NULL))
return 0;
- if (request1.access) {
- request1.audit.u.path.dentry = old_parent;
- landlock_log_denial(subject, &request1);
+ if (checks[0].request.access) {
+ checks[0].request.audit.u.path.dentry = old_parent_path.dentry;
+ landlock_log_denial(subject, &checks[0].request);
}
- if (request2.access) {
- request2.audit.u.path.dentry = new_dir->dentry;
- landlock_log_denial(subject, &request2);
+ if (checks[1].request.access) {
+ checks[1].request.audit.u.path.dentry = new_dir->dentry;
+ landlock_log_denial(subject, &checks[1].request);
}
/*
* This prioritizes EACCES over EXDEV for all actions, including
* renames with RENAME_EXCHANGE.
*/
- if (likely(is_eacces(&layer_masks_parent1, access_request_parent1) ||
- is_eacces(&layer_masks_parent2, access_request_parent2)))
+ if (likely(is_eacces(&checks[0].layer_masks, checks[0].access_request) ||
+ is_eacces(&checks[1].layer_masks, checks[1].access_request)))
return -EACCES;
/*
@@ -1625,12 +1555,11 @@ static bool is_device(const struct file *const file)
static int hook_file_open(struct file *const file)
{
- struct layer_access_masks layer_masks = {};
+ struct landlock_check check = {};
access_mask_t open_access_request, full_access_request, allowed_access,
optional_access;
const struct landlock_cred_security *const subject =
landlock_get_applicable_subject(file->f_cred, any_fs, NULL);
- struct landlock_request request = {};
if (!subject)
return 0;
@@ -1651,13 +1580,14 @@ static int hook_file_open(struct file *const file)
optional_access |= LANDLOCK_ACCESS_FS_IOCTL_DEV;
full_access_request = open_access_request | optional_access;
+ check.access_request =
+ landlock_init_layer_masks(subject->domain, full_access_request,
+ &check.layer_masks,
+ LANDLOCK_KEY_INODE);
if (is_access_to_paths_allowed(
- subject->domain, &file->f_path,
- landlock_init_layer_masks(subject->domain,
- full_access_request, &layer_masks,
- LANDLOCK_KEY_INODE),
- &layer_masks, &request, NULL, 0, NULL, NULL, NULL)) {
+ subject->domain, &file->f_path, &check, NULL, NULL,
+ NULL)) {
allowed_access = full_access_request;
} else {
/*
@@ -1666,8 +1596,8 @@ static int hook_file_open(struct file *const file)
* are still unfulfilled in any of the layers.
*/
allowed_access = full_access_request;
- for (size_t i = 0; i < ARRAY_SIZE(layer_masks.access); i++)
- allowed_access &= ~layer_masks.access[i];
+ for (size_t i = 0; i < ARRAY_SIZE(check.layer_masks.access); i++)
+ allowed_access &= ~check.layer_masks.access[i];
}
/*
@@ -1679,15 +1609,16 @@ static int hook_file_open(struct file *const file)
landlock_file(file)->allowed_access = allowed_access;
#ifdef CONFIG_AUDIT
landlock_file(file)->deny_masks = landlock_get_deny_masks(
- _LANDLOCK_ACCESS_FS_OPTIONAL, optional_access, &layer_masks);
+ _LANDLOCK_ACCESS_FS_OPTIONAL, optional_access,
+ &check.layer_masks);
#endif /* CONFIG_AUDIT */
if (access_mask_subset(open_access_request, allowed_access))
return 0;
/* Sets access to reflect the actual request. */
- request.access = open_access_request;
- landlock_log_denial(subject, &request);
+ check.request.access = open_access_request;
+ landlock_log_denial(subject, &check.request);
return -EACCES;
}
--
2.51.0
More information about the Linux-security-module-archive
mailing list