From: Sasha Levin <sashal@kernel.org>
To: stable@vger.kernel.org
Cc: Vivek Parikh <vivek.parikh@breachx.ai>,
Amir Goldstein <amir73il@gmail.com>,
"Christian Brauner (Amutable)" <brauner@kernel.org>,
Sasha Levin <sashal@kernel.org>
Subject: [PATCH 6.18.y] ovl: fix double end_creating() on the casefold-mismatch path
Date: Thu, 3 Sep 2026 08:22:32 -0400 [thread overview]
Message-ID: <20260903122232.708987-1-sashal@kernel.org> (raw)
In-Reply-To: <2026090319-clanking-sandstone-d89f@gregkh>
From: Vivek Parikh <vivek.parikh@breachx.ai>
[ Upstream commit 077ab8985ee278c3d8618182d335b0f0cd919e16 ]
ovl_create_real() releases the new dentry twice when the casefold
consistency check fails. The S_IFDIR branch calls end_creating() and
sets err, then falls through to the common out: label which calls
end_creating() on the same dentry again:
case S_IFDIR:
newdentry = ovl_do_mkdir(ofs, dir, newdentry, attr->mode);
err = PTR_ERR_OR_ZERO(newdentry);
if (!err && ofs->casefold != ovl_dentry_casefolded(newdentry)) {
pr_warn_ratelimited(...);
end_creating(newdentry); /* first */
err = -EINVAL;
}
break;
...
if (err)
goto out;
...
out:
if (err) {
end_creating(newdentry); /* second, same dentry */
return ERR_PTR(err);
}
end_creating() is end_dirop(), which does inode_unlock() on the parent
and dput() on the dentry, so the parent directory's i_rwsem is unlocked
twice and the dentry is put twice. The second unlock releases a lock
that is not held, which is what wedges every later creation under that
parent, and the second dput() drops a reference that was never taken.
The branch was added by commit dfc7da402ccc ("ovl: Check for casefold
consistency when creating new dentries") as a bare dput(), which already
released the reference twice; commit fe497f0759e0 ("VFS: change
vfs_mkdir() to unlock on failure.") converted both sites to
end_creating(), adding the double unlock.
This is reachable by an unprivileged user. The casefold consistency of
the layers is validated at mount time in ovl_parse_layer(), and again on
every lookup in ovl_lookup_single(), but ofs->workdir is the internal
"work" subdirectory created inside the user-supplied workdir, and that
subdirectory is not re-checked. Marking it casefolded after the mount
therefore makes every ovl_create_temp() inherit the wrong state - and
that path reaches ovl_create_real() through ovl_start_creating_temp(),
which uses start_creating() with a generated name and so never runs the
lookup-time check.
unshare -Urm
mount -t tmpfs -o casefold=utf8-12.1.0 tmpfs mnt
mkdir -p mnt/lower/d mnt/upper mnt/work mnt/merged
mount -t overlay ovl -o lowerdir=mnt/lower,\
upperdir=mnt/upper,workdir=mnt/work mnt/merged
chattr +F mnt/work/work
mkdir mnt/merged/d/sub # directory copy-up
overlayfs: wrong inherited casefold (work/#5)
and the next copy-up blocks forever on the parent's i_rwsem:
mkdir D start_creating+0x65/0xb0
ovl_start_creating_temp+0xb0/0xe0 [overlay]
ovl_create_temp+0xa3/0x1d0 [overlay]
ovl_copy_up_one+0x1f1c/0x21c0 [overlay]
ovl_copy_up_flags+0xf5/0x140 [overlay]
ovl_create_object+0xb7/0x220 [overlay]
ovl_mkdir+0x23/0x40 [overlay]
Drop the end_creating() from the branch and let out: own the cleanup,
which is what every other error path in this function already does.
Fixes: dfc7da402ccc ("ovl: Check for casefold consistency when creating new dentries")
Cc: stable@vger.kernel.org
Signed-off-by: Vivek Parikh <vivek.parikh@breachx.ai>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
[ adapted end_creating() cleanup removal to the older dput() API ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/overlayfs/dir.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c
index e924321b64025..1abe533304ba4 100644
--- a/fs/overlayfs/dir.c
+++ b/fs/overlayfs/dir.c
@@ -191,7 +191,6 @@ struct dentry *ovl_create_real(struct ovl_fs *ofs, struct dentry *parent,
if (!err && ofs->casefold != ovl_dentry_casefolded(newdentry)) {
pr_warn_ratelimited("wrong inherited casefold (%pd2)\n",
newdentry);
- dput(newdentry);
err = -EINVAL;
}
break;
--
2.53.0
prev parent reply other threads:[~2026-09-03 12:22 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-03 9:56 FAILED: patch "[PATCH] ovl: fix double end_creating() on the casefold-mismatch path" failed to apply to 6.18-stable tree gregkh
2026-09-03 12:22 ` Sasha Levin [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260903122232.708987-1-sashal@kernel.org \
--to=sashal@kernel.org \
--cc=amir73il@gmail.com \
--cc=brauner@kernel.org \
--cc=stable@vger.kernel.org \
--cc=vivek.parikh@breachx.ai \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.