Skip to content

Commit 5ef7bcd

Browse files
author
Miklos Szeredi
committed
ovl: relax redirect/metacopy requirements for lower -> data redirect
Allow the special case of a redirect from a lower layer to a data layer without having to turn on metacopy. This makes the feature work with userxattr, which in turn allows data layers to be usable in user namespaces. Minimize the risk by only enabling redirect from a single lower layer to a data layer iff a data layer is specified. The only way to access a data layer is to enable this, so there's really no reason not to enable this. This can be used safely if the lower layer is read-only and the user.overlay.redirect xattr cannot be modified. Reviewed-by: Amir Goldstein <[email protected]> Signed-off-by: Miklos Szeredi <[email protected]>
1 parent a6fcfe9 commit 5ef7bcd

File tree

3 files changed

+17
-13
lines changed

3 files changed

+17
-13
lines changed

Documentation/filesystems/overlayfs.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,13 @@ Only the data of the files in the "data-only" lower layers may be visible
443443
when a "metacopy" file in one of the lower layers above it, has a "redirect"
444444
to the absolute path of the "lower data" file in the "data-only" lower layer.
445445

446+
Instead of explicitly enabling "metacopy=on" it is sufficient to specify at
447+
least one data-only layer to enable redirection of data to a data-only layer.
448+
In this case other forms of metacopy are rejected. Note: this way data-only
449+
layers may be used toghether with "userxattr", in which case careful attention
450+
must be given to privileges needed to change the "user.overlay.redirect" xattr
451+
to prevent misuse.
452+
446453
Since kernel version v6.8, "data-only" lower layers can also be added using
447454
the "datadir+" mount options and the fsconfig syscall from new mount api.
448455
For example::

fs/overlayfs/namei.c

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1066,6 +1066,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
10661066
unsigned int ctr = 0;
10671067
struct inode *inode = NULL;
10681068
bool upperopaque = false;
1069+
bool check_redirect = (ovl_redirect_follow(ofs) || ofs->numdatalayer);
10691070
struct dentry *this;
10701071
unsigned int i;
10711072
int err;
@@ -1078,7 +1079,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
10781079
.is_dir = false,
10791080
.opaque = false,
10801081
.stop = false,
1081-
.last = ovl_redirect_follow(ofs) ? false : !ovl_numlower(poe),
1082+
.last = check_redirect ? false : !ovl_numlower(poe),
10821083
.redirect = NULL,
10831084
.upperredirect = NULL,
10841085
.metacopy = 0,
@@ -1146,7 +1147,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
11461147
goto out_put;
11471148
}
11481149

1149-
if (!ovl_redirect_follow(ofs))
1150+
if (!check_redirect)
11501151
d.last = i == ovl_numlower(poe) - 1;
11511152
else if (d.is_dir || !ofs->numdatalayer)
11521153
d.last = lower.layer->idx == ovl_numlower(roe);
@@ -1221,15 +1222,16 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
12211222
}
12221223
}
12231224

1224-
if (!ovl_check_follow_redirect(&d)) {
1225-
err = -EPERM;
1226-
goto out_put;
1227-
}
1228-
1229-
/* Defer lookup of lowerdata in data-only layers to first access */
1225+
/*
1226+
* Defer lookup of lowerdata in data-only layers to first access.
1227+
* Don't require redirect=follow and metacopy=on in this case.
1228+
*/
12301229
if (d.metacopy && ctr && ofs->numdatalayer && d.absolute_redirect) {
12311230
d.metacopy = 0;
12321231
ctr++;
1232+
} else if (!ovl_check_follow_redirect(&d)) {
1233+
err = -EPERM;
1234+
goto out_put;
12331235
}
12341236

12351237
/*

fs/overlayfs/params.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1025,11 +1025,6 @@ int ovl_fs_params_verify(const struct ovl_fs_context *ctx,
10251025
*/
10261026
}
10271027

1028-
if (ctx->nr_data > 0 && !config->metacopy) {
1029-
pr_err("lower data-only dirs require metacopy support.\n");
1030-
return -EINVAL;
1031-
}
1032-
10331028
return 0;
10341029
}
10351030

0 commit comments

Comments
 (0)