Skip to contentSkip to conversation

FAILED: patch "[PATCH] ovl: do not copy up a dentry that was removed" failed to apply to 6.12-stable tree

PATCH New [email protected] 2 participants 2 messages Nov 4 – Nov 5

Subsystems (2)
lore
Share & tools
lore

[email protected]

author maintainer
#0 lore raw

The patch below does not apply to the 6.12-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.

To reproduce the conflict and resubmit, you may use the following commands:

git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.12.y
git checkout FETCH_HEAD
git cherry-pick -x f635192ad223d2009ee640b63adf5ce3198aa338
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026110407-elevation-shale-f903@gregkh' --subject-prefix 'PATCH 6.12.y' 'HEAD^..'

Possible dependencies:

thanks,

greg k-h

------------------ original commit in Linus's tree ------------------

From f635192ad223d2009ee640b63adf5ce3198aa338 Mon Sep 17 00:00:00 2001
From: Chris Mason <[email protected]>
Date: Wed, 7 Oct 2026 11:00:06 +0000
Subject: [PATCH] ovl: do not copy up a dentry that was removed

A change to a removed file through an open descriptor replaces whatever has its old name in the upper layer.

Copy up must only create a name in the upper directory, never replace one. After an unlink, an rmdir or a rename over a lower dentry, a dentry that an open file keeps alive still has its old parent and name, but in the upper directory that name is now a whiteout or a new object. ovl_copy_up_workdir() renames the copy over it, which brings back the removed object and destroys whatever took its name.

An unprivileged user opened a lower FIFO and unlinked it, root created a file at that name, and fchmod on the old descriptor replaced the file of root with the FIFO.

Fix this by looking up the target name of the rename in ovl_copy_up_workdir() with LOOKUP_EXCL, so that copy up fails with -EEXIST if the name is taken, as copy up with O_TMPFILE already does when it links the copy to the name.

Fixes e9be9d5e76e3 ("overlay filesystem")
[amir: use LOOKUP_EXCL instead of relying on d_unhashed()]
fs/overlayfs/copy_up.c +3 -2
index 12000e45fefc..286978d47ef7 100644
@@ -793,9 +793,10 @@ static int ovl_copy_up_workdir(struct ovl_copy_up_ctx *c)
 	rd.old_parent = c->workdir;
 	rd.new_parent = c->destdir;
 	rd.flags = 0;
-	err = start_renaming_dentry(&rd, 0, temp,
+	/* The name may have been taken since lookup, never replace it */
+	err = start_renaming_dentry(&rd, LOOKUP_EXCL, temp,
 				    &QSTR_LEN(c->destname.name, c->destname.len));
-	if (err) {
+	if (err && err != -EEXIST) {
 		/* temp or workdir moved underneath us? map to -EIO */
 		err = -EIO;
 	}
maintainer
#1 lore raw

PATCH 1/1 ovl: do not copy up a dentry that was removed

From: Chris Mason <[email protected]>

[ Upstream commit f635192ad223d2009ee640b63adf5ce3198aa338 ]

A change to a removed file through an open descriptor replaces whatever has its old name in the upper layer.

Copy up must only create a name in the upper directory, never replace one. After an unlink, an rmdir or a rename over a lower dentry, a dentry that an open file keeps alive still has its old parent and name, but in the upper directory that name is now a whiteout or a new object. ovl_copy_up_workdir() renames the copy over it, which brings back the removed object and destroys whatever took its name.

An unprivileged user opened a lower FIFO and unlinked it, root created a file at that name, and fchmod on the old descriptor replaced the file of root with the FIFO.

Fix this by looking up the target name of the rename in ovl_copy_up_workdir() with LOOKUP_EXCL, so that copy up fails with -EEXIST if the name is taken, as copy up with O_TMPFILE already does when it links the copy to the name.

Fixes e9be9d5e76e3 ("overlay filesystem")
[amir: use LOOKUP_EXCL instead of relying on d_unhashed()]
[ sashal: Replaced start_renaming_dentry()'s LOOKUP_EXCL check with an explicit d_is_positive() check before ovl_do_rename(). ]
---
 fs/overlayfs/copy_up.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
fs/overlayfs/copy_up.c +4 -1
index db128e1f2eb05..7ec9cb89ec063 100644
@@ -831,7 +831,10 @@ static int ovl_copy_up_workdir(struct ovl_copy_up_ctx *c)
 	if (IS_ERR(upper))
 		goto cleanup;
 
-	err = ovl_do_rename(ofs, wdir, temp, udir, upper, 0);
+	/* The name may have been taken since lookup, never replace it */
+	err = -EEXIST;
+	if (!d_is_positive(upper))
+		err = ovl_do_rename(ofs, wdir, temp, udir, upper, 0);
 	dput(upper);
 	if (err)
 		goto cleanup;
Signature · 1 line
2.53.0