Skip to content

Commit 083957f

Browse files
amir73ilbrauner
authored andcommitted
ovl: support layers on case-folding capable filesystems
Case folding is often applied to subtrees and not on an entire filesystem. Disallowing layers from filesystems that support case folding is over limiting. Replace the rule that case-folding capable are not allowed as layers with a rule that case folded directories are not allowed in a merged directory stack. Should case folding be enabled on an underlying directory while overlayfs is mounted the outcome is generally undefined. Specifically in ovl_lookup(), we check the base underlying directory and fail with -ESTALE and write a warning to kmsg if an underlying directory case folding is enabled. Suggested-by: Kent Overstreet <[email protected]> Link: https://lore.kernel.org/linux-fsdevel/[email protected]/ Signed-off-by: Amir Goldstein <[email protected]> Link: https://lore.kernel.org/[email protected] Reviewed-by: Kent Overstreet <[email protected]> Signed-off-by: Christian Brauner <[email protected]>
1 parent 04060e7 commit 083957f

File tree

4 files changed

+49
-13
lines changed

4 files changed

+49
-13
lines changed

fs/overlayfs/namei.c

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -230,13 +230,26 @@ static int ovl_lookup_single(struct dentry *base, struct ovl_lookup_data *d,
230230
struct dentry **ret, bool drop_negative)
231231
{
232232
struct ovl_fs *ofs = OVL_FS(d->sb);
233-
struct dentry *this;
233+
struct dentry *this = NULL;
234+
const char *warn;
234235
struct path path;
235236
int err;
236237
bool last_element = !post[0];
237238
bool is_upper = d->layer->idx == 0;
238239
char val;
239240

241+
/*
242+
* We allow filesystems that are case-folding capable but deny composing
243+
* ovl stack from case-folded directories. If someone has enabled case
244+
* folding on a directory on underlying layer, the warranty of the ovl
245+
* stack is voided.
246+
*/
247+
if (ovl_dentry_casefolded(base)) {
248+
warn = "case folded parent";
249+
err = -ESTALE;
250+
goto out_warn;
251+
}
252+
240253
this = ovl_lookup_positive_unlocked(d, name, base, namelen, drop_negative);
241254
if (IS_ERR(this)) {
242255
err = PTR_ERR(this);
@@ -246,10 +259,17 @@ static int ovl_lookup_single(struct dentry *base, struct ovl_lookup_data *d,
246259
goto out_err;
247260
}
248261

262+
if (ovl_dentry_casefolded(this)) {
263+
warn = "case folded child";
264+
err = -EREMOTE;
265+
goto out_warn;
266+
}
267+
249268
if (ovl_dentry_weird(this)) {
250269
/* Don't support traversing automounts and other weirdness */
270+
warn = "unsupported object type";
251271
err = -EREMOTE;
252-
goto out_err;
272+
goto out_warn;
253273
}
254274

255275
path.dentry = this;
@@ -283,8 +303,9 @@ static int ovl_lookup_single(struct dentry *base, struct ovl_lookup_data *d,
283303
} else {
284304
if (ovl_lookup_trap_inode(d->sb, this)) {
285305
/* Caught in a trap of overlapping layers */
306+
warn = "overlapping layers";
286307
err = -ELOOP;
287-
goto out_err;
308+
goto out_warn;
288309
}
289310

290311
if (last_element)
@@ -316,6 +337,10 @@ static int ovl_lookup_single(struct dentry *base, struct ovl_lookup_data *d,
316337
this = NULL;
317338
goto out;
318339

340+
out_warn:
341+
pr_warn_ratelimited("failed lookup in %s (%pd2, name='%.*s', err=%i): %s\n",
342+
is_upper ? "upper" : "lower", base,
343+
namelen, name, err, warn);
319344
out_err:
320345
dput(this);
321346
return err;

fs/overlayfs/overlayfs.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,12 @@ void ovl_dentry_init_reval(struct dentry *dentry, struct dentry *upperdentry,
446446
void ovl_dentry_init_flags(struct dentry *dentry, struct dentry *upperdentry,
447447
struct ovl_entry *oe, unsigned int mask);
448448
bool ovl_dentry_weird(struct dentry *dentry);
449+
450+
static inline bool ovl_dentry_casefolded(struct dentry *dentry)
451+
{
452+
return sb_has_encoding(dentry->d_sb) && IS_CASEFOLDED(d_inode(dentry));
453+
}
454+
449455
enum ovl_path_type ovl_path_type(struct dentry *dentry);
450456
void ovl_path_upper(struct dentry *dentry, struct path *path);
451457
void ovl_path_lower(struct dentry *dentry, struct path *path);

fs/overlayfs/params.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -282,13 +282,11 @@ static int ovl_mount_dir_check(struct fs_context *fc, const struct path *path,
282282
return invalfc(fc, "%s is not a directory", name);
283283

284284
/*
285-
* Root dentries of case-insensitive capable filesystems might
286-
* not have the dentry operations set, but still be incompatible
287-
* with overlayfs. Check explicitly to prevent post-mount
288-
* failures.
285+
* Allow filesystems that are case-folding capable but deny composing
286+
* ovl stack from case-folded directories.
289287
*/
290-
if (sb_has_encoding(path->mnt->mnt_sb))
291-
return invalfc(fc, "case-insensitive capable filesystem on %s not supported", name);
288+
if (ovl_dentry_casefolded(path->dentry))
289+
return invalfc(fc, "case-insensitive directory on %s not supported", name);
292290

293291
if (ovl_dentry_weird(path->dentry))
294292
return invalfc(fc, "filesystem on %s not supported", name);

fs/overlayfs/util.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -206,10 +206,17 @@ bool ovl_dentry_weird(struct dentry *dentry)
206206
if (!d_can_lookup(dentry) && !d_is_file(dentry) && !d_is_symlink(dentry))
207207
return true;
208208

209-
return dentry->d_flags & (DCACHE_NEED_AUTOMOUNT |
210-
DCACHE_MANAGE_TRANSIT |
211-
DCACHE_OP_HASH |
212-
DCACHE_OP_COMPARE);
209+
if (dentry->d_flags & (DCACHE_NEED_AUTOMOUNT | DCACHE_MANAGE_TRANSIT))
210+
return true;
211+
212+
/*
213+
* Allow filesystems that are case-folding capable but deny composing
214+
* ovl stack from case-folded directories.
215+
*/
216+
if (sb_has_encoding(dentry->d_sb))
217+
return IS_CASEFOLDED(d_inode(dentry));
218+
219+
return dentry->d_flags & (DCACHE_OP_HASH | DCACHE_OP_COMPARE);
213220
}
214221

215222
enum ovl_path_type ovl_path_type(struct dentry *dentry)

0 commit comments

Comments
 (0)