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

From: Jori Koolstra

Date: Sat Jul 04 2026 - 12:46:12 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 -EEXIST in that case
(matching the errorno returned by mkdir(2).) 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. Thus 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 76916caa264d..030cac4fbe55 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -4546,6 +4546,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 = -EEXIST;
}
if (create_error)
open_flag &= ~O_CREAT;
--
2.55.0