Re: [PATCH v3 1/2] ovl: reject different lower idmaps on the same fs

From: Amir Goldstein

Date: Thu Nov 12 2026 - 07:36:32 EST


On Wed, Nov 11, 2026 at 11:43 PM Jérémy Jean
<Jeremy.Jean@xxxxxxxxxxxxxxxxx> wrote:
>
> Overlay file handles identify a backing filesystem, but not the lower
> mount used to decode it. If lower layers share a superblock and use
> different idmaps, a handle can decode through the wrong layer.
>
> Record the first idmap on a private lower clone for each backing
> filesystem. Fail if another clone has a different idmap. Comparing
> the private clones prevents mount_setattr() from changing the checked
> state. Distinct idmap objects are treated as ambiguous.

I got a bit concerned from regressions, when lower layers have idmap
from same userns, but not the same idmap objects, becauses I have
no idea how different runtimes setup overlayfs.

To reduce the risk, I took a conservative interpretations of Chritian's
"just fail the mount" [1] so we just fail the mount if index/nfs_export
are requested and leave a way out for the poor user.

[1] https://lore.kernel.org/all/20260925-server-hager-riskieren-06116eded213@brauner/

Applied with some changes below...

Thanks,
Amir.

>
> Fixes: bc70682a497c ("ovl: support idmapped layers")
> Cc: stable@xxxxxxxxxxxxxxx
> Signed-off-by: Jérémy Jean <Jeremy.Jean@xxxxxxxxxxxxxxxxx>
> ---
> fs/overlayfs/ovl_entry.h | 2 ++
> fs/overlayfs/super.c | 15 +++++++++++++++
> 2 files changed, 17 insertions(+)
>
> diff --git a/fs/overlayfs/ovl_entry.h b/fs/overlayfs/ovl_entry.h
> index ac07e8769f9b..5b2f1b930daa 100644
> --- a/fs/overlayfs/ovl_entry.h
> +++ b/fs/overlayfs/ovl_entry.h
> @@ -24,6 +24,8 @@ struct ovl_config {
> struct ovl_sb {
> struct super_block *sb;
> dev_t pseudo_dev;
> + /* Idmap of the first lower layer on this fs */
> + const struct mnt_idmap *lower_idmap;
> /* Unusable (conflicting) uuid */
> bool bad_uuid;
> /* Used as a lower layer (but maybe also as upper) */
> diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
> index 8bc970748b96..40eb8428a718 100644
> --- a/fs/overlayfs/super.c
> +++ b/fs/overlayfs/super.c
> @@ -1141,6 +1141,21 @@ static int ovl_get_layers(struct super_block *sb, struct ovl_fs *ofs,
> return err;
> }
>
> + if (i < nr_merged_lower) {
> + const struct mnt_idmap *idmap = mnt_idmap(mnt);
> + struct ovl_sb *fs = &ofs->fs[fsid];
> +
> + if (!fs->lower_idmap)
> + fs->lower_idmap = idmap;
> + if (fs->lower_idmap != idmap) {
> + pr_err("lower layer '%pd2' conflicts with idmap of another layer on the same fs\n",
> + l->path.dentry);


/*
* Lower file handles identify the lower fs, but not the layer,
* so with different idmaps on the same lower fs, index and
* nfs_export may decode a file handle through a layer with the
* wrong idmap. Following copy up origin without index is only
* used for st_ino, which does not depend on the idmap.
*/
if (i < nr_merged_lower &&
(ofs->config.index || ofs->config.nfs_export)) {
const struct mnt_idmap *idmap = mnt_idmap(mnt);
struct ovl_sb *fs = &ofs->fs[fsid];

if (!fs->lower_idmap) {
fs->lower_idmap = idmap;
} else if (fs->lower_idmap != idmap) {
pr_err("lower layer '%pd2' conflicts
with idmap of another lower layer on the same fs, mount with '-o
index=off,nfs_export=off' to override.\n",
l->path.dentry);

> + iput(trap);
> + kern_unmount(mnt);
> + return -EINVAL;
> + }
> + }
> +
> /*
> * Make lower layers R/O. That way fchmod/fchown on lower file
> * will fail instead of modifying lower fs.
> --
> 2.47.3
>