diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index 87cf9b1d2eca..f036d7544d4a 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c @@ -1525,7 +1525,8 @@ out_err: * - upper/work dir of any overlayfs instance */ static int ovl_check_layer(struct super_block *sb, struct ovl_fs *ofs, - struct dentry *dentry, const char *name) + struct dentry *dentry, const char *name, + bool is_lower) { struct dentry *next = dentry, *parent; int err = 0; @@ -1537,7 +1538,7 @@ static int ovl_check_layer(struct super_block *sb, struct ovl_fs *ofs, /* Walk back ancestors to root (inclusive) looking for traps */ while (!err && parent != next) { - if (ovl_lookup_trap_inode(sb, parent)) { + if (is_lower && ovl_lookup_trap_inode(sb, parent)) { err = -ELOOP; pr_err("overlayfs: overlapping %s path\n", name); } else if (ovl_is_inuse(parent)) { @@ -1563,7 +1564,7 @@ static int ovl_check_overlapping_layers(struct super_block *sb, if (ofs->upper_mnt) { err = ovl_check_layer(sb, ofs, ofs->upper_mnt->mnt_root, - "upperdir"); + "upperdir", false); if (err) return err; @@ -1574,7 +1575,8 @@ static int ovl_check_overlapping_layers(struct super_block *sb, * workbasedir. In that case, we already have their traps in * inode cache and we will catch that case on lookup. */ - err = ovl_check_layer(sb, ofs, ofs->workbasedir, "workdir"); + err = ovl_check_layer(sb, ofs, ofs->workbasedir, "workdir", + false); if (err) return err; } @@ -1582,7 +1584,7 @@ static int ovl_check_overlapping_layers(struct super_block *sb, for (i = 0; i < ofs->numlower; i++) { err = ovl_check_layer(sb, ofs, ofs->lower_layers[i].mnt->mnt_root, - "lowerdir"); + "lowerdir", true); if (err) return err; }