Skip to content
This repository was archived by the owner on Nov 8, 2023. It is now read-only.

Commit 88da52c

Browse files
committed
landlock: Fix d_parent walk
The WARN_ON_ONCE() in collect_domain_accesses() can be triggered when trying to link a root mount point. This cannot work in practice because this directory is mounted, but the VFS check is done after the call to security_path_link(). Do not use source directory's d_parent when the source directory is the mount point. Cc: Günther Noack <gnoack@google.com> Cc: Paul Moore <paul@paul-moore.com> Cc: stable@vger.kernel.org Reported-by: syzbot+bf4903dc7e12b18ebc87@syzkaller.appspotmail.com Fixes: b91c3e4 ("landlock: Add support for file reparenting with LANDLOCK_ACCESS_FS_REFER") Closes: https://lore.kernel.org/r/000000000000553d3f0618198200@google.com Link: https://lore.kernel.org/r/20240516181935.1645983-2-mic@digikod.net [mic: Fix commit message] Signed-off-by: Mickaël Salaün <mic@digikod.net>
1 parent 1613e60 commit 88da52c

File tree

1 file changed

+11
-2
lines changed
  • security/landlock

1 file changed

+11
-2
lines changed

security/landlock/fs.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,6 +1110,7 @@ static int current_check_refer_path(struct dentry *const old_dentry,
11101110
bool allow_parent1, allow_parent2;
11111111
access_mask_t access_request_parent1, access_request_parent2;
11121112
struct path mnt_dir;
1113+
struct dentry *old_parent;
11131114
layer_mask_t layer_masks_parent1[LANDLOCK_NUM_ACCESS_FS] = {},
11141115
layer_masks_parent2[LANDLOCK_NUM_ACCESS_FS] = {};
11151116

@@ -1157,9 +1158,17 @@ static int current_check_refer_path(struct dentry *const old_dentry,
11571158
mnt_dir.mnt = new_dir->mnt;
11581159
mnt_dir.dentry = new_dir->mnt->mnt_root;
11591160

1161+
/*
1162+
* old_dentry may be the root of the common mount point and
1163+
* !IS_ROOT(old_dentry) at the same time (e.g. with open_tree() and
1164+
* OPEN_TREE_CLONE). We do not need to call dget(old_parent) because
1165+
* we keep a reference to old_dentry.
1166+
*/
1167+
old_parent = (old_dentry == mnt_dir.dentry) ? old_dentry :
1168+
old_dentry->d_parent;
1169+
11601170
/* new_dir->dentry is equal to new_dentry->d_parent */
1161-
allow_parent1 = collect_domain_accesses(dom, mnt_dir.dentry,
1162-
old_dentry->d_parent,
1171+
allow_parent1 = collect_domain_accesses(dom, mnt_dir.dentry, old_parent,
11631172
&layer_masks_parent1);
11641173
allow_parent2 = collect_domain_accesses(
11651174
dom, mnt_dir.dentry, new_dir->dentry, &layer_masks_parent2);

0 commit comments

Comments
 (0)