* FAILED: patch "[PATCH] ovl: take a snapshot of the name for copy up" failed to apply to 5.10-stable tree
@ 2026-11-04 14:35 gregkh
2026-11-05 13:45 ` [PATCH 5.10.y] ovl: take a snapshot of the name for copy up Sasha Levin
0 siblings, 1 reply; 2+ messages in thread
From: gregkh @ 2026-11-04 14:35 UTC (permalink / raw)
To: mason, amir73il, josef; +Cc: stable
The patch below does not apply to the 5.10-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 <stable@vger.kernel.org>.
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-5.10.y
git checkout FETCH_HEAD
git cherry-pick -x 65bf000962a33ec9d2488e4e1797b6cf630abcbb
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<stable@vger.kernel.org>' --in-reply-to '2026110415-exemplify-juvenile-57b8@gregkh' --subject-prefix 'PATCH 5.10.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 65bf000962a33ec9d2488e4e1797b6cf630abcbb Mon Sep 17 00:00:00 2001
From: Chris Mason <mason@kernel.org>
Date: Wed, 7 Oct 2026 10:34:08 +0000
Subject: [PATCH] ovl: take a snapshot of the name for copy up
The copy up of a directory reads a freed dentry name when a lookup
moves the directory at the same time.
A pointer to the name of a dentry is only valid while something stops
a move of the dentry. ovl_do_copy_up() keeps a plain copy of
c->dentry->d_name in c->destname, and ovl_copy_up_start() only keeps
ovl_rename() away. When a lookup finds the same directory under another
name after a change to the lower layer, d_splice_alias() moves the
dentry and frees its external name.
With a delay in ovl_do_copy_up(), a chmod of a lower-only directory with
a 60 byte name raced with a rename of that directory in the lower layer
and a stat of the new name, and KASAN reported a use-after-free in
lookup_noperm_common().
Fix this by using take_dentry_name_snapshot() for c->destname.
Fixes: 829c28be9bb9 ("ovl: use d_splice_alias() in place of d_add() in lookup")
Cc: stable@vger.kernel.org
Signed-off-by: Chris Mason <mason@kernel.org>
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c
index 92b3d08a0234..12000e45fefc 100644
--- a/fs/overlayfs/copy_up.c
+++ b/fs/overlayfs/copy_up.c
@@ -920,6 +920,7 @@ static int ovl_do_copy_up(struct ovl_copy_up_ctx *c)
struct ovl_fs *ofs = OVL_FS(c->dentry->d_sb);
struct dentry *origin = c->lowerpath.dentry;
struct ovl_fh *fh = NULL;
+ struct name_snapshot name;
bool to_index = false;
/*
@@ -957,12 +958,15 @@ static int ovl_do_copy_up(struct ovl_copy_up_ctx *c)
goto out_free_fh;
} else {
/*
- * c->dentry->d_name is stabilzed by ovl_copy_up_start(),
- * because if we got here, it means that c->dentry has no upper
- * alias and changing ->d_name means going through ovl_rename()
- * that will call ovl_copy_up() on source and target dentry.
+ * ovl_copy_up_start() keeps ovl_rename() away from c->dentry,
+ * because ovl_rename() calls ovl_copy_up() on source and target
+ * dentry. It does not stop d_splice_alias() from moving a
+ * directory that a lookup found under another name after a
+ * change to the lower layer. That move frees an external name,
+ * so take a snapshot.
*/
- c->destname = c->dentry->d_name;
+ take_dentry_name_snapshot(&name, c->dentry);
+ c->destname = name.name;
/*
* Mark parent "impure" because it may now contain non-pure
* upper
@@ -971,7 +975,7 @@ static int ovl_do_copy_up(struct ovl_copy_up_ctx *c)
err = ovl_set_impure(c->parent, c->destdir);
ovl_end_write(c->dentry);
if (err)
- goto out_free_fh;
+ goto out;
}
/* Should we copyup with O_TMPFILE or with workdir? */
@@ -1005,6 +1009,8 @@ static int ovl_do_copy_up(struct ovl_copy_up_ctx *c)
out:
if (to_index)
kfree(c->destname.name);
+ else
+ release_dentry_name_snapshot(&name);
out_free_fh:
kfree(fh);
return err;
^ permalink raw reply related [flat|nested] 2+ messages in thread
* [PATCH 5.10.y] ovl: take a snapshot of the name for copy up
2026-11-04 14:35 FAILED: patch "[PATCH] ovl: take a snapshot of the name for copy up" failed to apply to 5.10-stable tree gregkh
@ 2026-11-05 13:45 ` Sasha Levin
0 siblings, 0 replies; 2+ messages in thread
From: Sasha Levin @ 2026-11-05 13:45 UTC (permalink / raw)
To: stable; +Cc: Chris Mason, Josef Bacik, Amir Goldstein, Sasha Levin
From: Chris Mason <mason@kernel.org>
[ Upstream commit 65bf000962a33ec9d2488e4e1797b6cf630abcbb ]
The copy up of a directory reads a freed dentry name when a lookup
moves the directory at the same time.
A pointer to the name of a dentry is only valid while something stops
a move of the dentry. ovl_do_copy_up() keeps a plain copy of
c->dentry->d_name in c->destname, and ovl_copy_up_start() only keeps
ovl_rename() away. When a lookup finds the same directory under another
name after a change to the lower layer, d_splice_alias() moves the
dentry and frees its external name.
With a delay in ovl_do_copy_up(), a chmod of a lower-only directory with
a 60 byte name raced with a rename of that directory in the lower layer
and a stat of the new name, and KASAN reported a use-after-free in
lookup_noperm_common().
Fix this by using take_dentry_name_snapshot() for c->destname.
Fixes: 829c28be9bb9 ("ovl: use d_splice_alias() in place of d_add() in lookup")
Cc: stable@vger.kernel.org
Signed-off-by: Chris Mason <mason@kernel.org>
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
[ sashal: adapted snapshot handling to caller-side destination-name initialization and direct-return error paths ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/overlayfs/copy_up.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c
index 018867303a93a..bd5526904eea6 100644
--- a/fs/overlayfs/copy_up.c
+++ b/fs/overlayfs/copy_up.c
@@ -709,6 +709,7 @@ static int ovl_do_copy_up(struct ovl_copy_up_ctx *c)
{
int err;
struct ovl_fs *ofs = c->dentry->d_sb->s_fs_info;
+ struct name_snapshot name;
bool to_index = false;
/*
@@ -737,13 +738,23 @@ static int ovl_do_copy_up(struct ovl_copy_up_ctx *c)
/* Disconnected dentry must be copied up to index dir */
return -EIO;
} else {
+ /*
+ * ovl_copy_up_start() keeps ovl_rename() away from c->dentry,
+ * because ovl_rename() calls ovl_copy_up() on source and target
+ * dentry. It does not stop d_splice_alias() from moving a
+ * directory that a lookup found under another name after a
+ * change to the lower layer. That move frees an external name,
+ * so take a snapshot.
+ */
+ take_dentry_name_snapshot(&name, c->dentry);
+ c->destname = name.name;
/*
* Mark parent "impure" because it may now contain non-pure
* upper
*/
err = ovl_set_impure(c->parent, c->destdir);
if (err)
- return err;
+ goto out;
}
/* Should we copyup with O_TMPFILE or with workdir? */
@@ -775,6 +786,8 @@ static int ovl_do_copy_up(struct ovl_copy_up_ctx *c)
out:
if (to_index)
kfree(c->destname.name);
+ else
+ release_dentry_name_snapshot(&name);
return err;
}
@@ -895,7 +908,6 @@ static int ovl_copy_up_one(struct dentry *parent, struct dentry *dentry,
if (parent) {
ovl_path_upper(parent, &parentpath);
ctx.destdir = parentpath.dentry;
- ctx.destname = dentry->d_name;
err = vfs_getattr(&parentpath, &ctx.pstat,
STATX_ATIME | STATX_MTIME,
--
2.53.0
^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-11-05 13:45 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-04 14:35 FAILED: patch "[PATCH] ovl: take a snapshot of the name for copy up" failed to apply to 5.10-stable tree gregkh
2026-11-05 13:45 ` [PATCH 5.10.y] ovl: take a snapshot of the name for copy up Sasha Levin
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.