diff options
| author | Chris Mason <mason@kernel.org> | 2026-10-16 21:17:21 +0000 |
|---|---|---|
| committer | Amir Goldstein <amir73il@gmail.com> | 2026-11-03 22:17:23 +0100 |
| commit | e803c82dcdd15e87b48fca1ea8d2cfe6a7ed83d4 (patch) | |
| tree | 0f22aa8f236fee382227dd0cf1bc59579ac48cf7 /scripts/livepatch | |
| parent | 83b351c3ade542bbfa1073e8c2d919826628252a (diff) | |
ovl: fix whiteout creation in casefolded directories
unlink and rmdir fail with EINVAL on an overlay with casefolded
(case-insensitive) layers, if the name exists in a lower layer.
Casefolded layers need CONFIG_UNICODE. Root can mount such an overlay,
and so can an unprivileged user in a user namespace, with tmpfs layers.
Overlayfs does not change a lower layer. To remove a name that exists
there, it hides the name with a marker file, a whiteout. It creates the
whiteout in the work directory, a scratch directory on the upper
filesystem, and renames it over the name in the upper directory:
- ovl_whiteout() creates the whiteout with mknod, or as a hard link to
an earlier whiteout.
- ovl_cleanup_and_whiteout() then prepares the rename with
start_renaming_two_dentries(), which returns -EINVAL if the source or
the target dentry is unhashed, that is, not in the dentry hash table.
With casefolded directories, both dentries can be unhashed:
- The target. Lookup in a casefolded directory leaves a negative dentry
unhashed, so the rename target is unhashed if the name does not exist
in the upper directory.
- The source, which is the new whiteout. tmpfs hashes a dentry when
mknod or link makes it positive, but ext4 does not, so on ext4 the
source is unhashed as well.
The cleanup after the failure also refuses an unhashed dentry, so on
ext4 the whiteout is left behind in the work directory.
Reproduced with rm and rmdir on casefolded tmpfs and ext4 layers, also
as uid 1000 in a user namespace.
Fix this by creating the whiteout with ovl_create_temp(), which repeats
the lookup if the new dentry is unhashed. Prepare the rename with
start_renaming_dentry(), which looks up the target name with the
directories locked. The caller looked the name up without a lock, so
return -ESTALE if the name now refers to a different inode.
Fixes: 833d2b3a072f ("Add start_renaming_two_dentries()")
Cc: stable@vger.kernel.org
Signed-off-by: Chris Mason <mason@kernel.org>
[amir: pass the name used for lookup instead of taking a name snapshot]
Tested-by: Hungyu Lin <dennylin0707@gmail.com>
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Diffstat (limited to 'scripts/livepatch')
0 files changed, 0 insertions, 0 deletions
