[PATCH v2 11/14] vfs: refuse O_CREAT for directories through a dangling symlink

From: Jori Koolstra

Date: Mon Jun 29 2026 - 11:43:53 EST


open(O_CREAT) without O_EXCL follows a trailing symlink and, when the
symlink target does not exist, creates it. Refuse to create through a
dangling symlink for directories.

In lookup_open() a negative target reached with nd->depth > 0 was
arrived at by following a trailing symlink; since the dentry is negative
the symlink is dangling. Set create_error to -ELOOP in that case.
Reusing the existing create_error path strips O_CREAT for both the
generic and ->atomic_open create paths and only reports the error when
the target is actually negative, so opening an existing target through a
symlink, interior symlinks, and O_EXCL (which never follows the trailing
link) are all unaffected.

Suggested-by: Christian Brauner (Amutable) <brauner@xxxxxxxxxx>
Signed-off-by: Jori Koolstra <jkoolstra@xxxxxxxxx>
---
fs/namei.c | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/fs/namei.c b/fs/namei.c
index c4b242205707..fef826c04eb5 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -4535,6 +4535,11 @@ static struct dentry *lookup_open(struct nameidata *nd, struct file *file,
dentry, mode, create_dir);
else
create_error = -EROFS;
+ /* Refuse to create a directory through a dangling (trailing)
+ * symlink. For regular files this has been allowed historically
+ * on O_CREAT without O_EXCL. */
+ if (unlikely(nd->depth) && create_dir && !create_error)
+ create_error = -ELOOP;
}
if (create_error)
open_flag &= ~O_CREAT;
--
2.54.0