Skip to content

Commit e6333d7

Browse files
committed
Merge tag 'ovl-fixes-4.20-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs
Pull overlayfs fixes from Miklos Szeredi: "Needed to revert a patch, because it possibly introduces a security hole. Since the patch is basically a conceptual cleanup, not a bug fix, it's safe to revert. I'm not giving up on this, and discussions seemed to have reached an agreement over how to move forward, but that can wait 'till the next release. The other two patches are fixes for bugs introduced in recent releases" * tag 'ovl-fixes-4.20-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs: Revert "ovl: relax permission checking on underlying layers" ovl: fix decode of dir file handle with multi lower layers ovl: fix missing override creds in link of a metacopy upper
2 parents 70f4828 + ec7ba11 commit e6333d7

File tree

3 files changed

+20
-17
lines changed

3 files changed

+20
-17
lines changed

fs/overlayfs/dir.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,18 @@ static int ovl_symlink(struct inode *dir, struct dentry *dentry,
651651
return ovl_create_object(dentry, S_IFLNK, 0, link);
652652
}
653653

654+
static int ovl_set_link_redirect(struct dentry *dentry)
655+
{
656+
const struct cred *old_cred;
657+
int err;
658+
659+
old_cred = ovl_override_creds(dentry->d_sb);
660+
err = ovl_set_redirect(dentry, false);
661+
revert_creds(old_cred);
662+
663+
return err;
664+
}
665+
654666
static int ovl_link(struct dentry *old, struct inode *newdir,
655667
struct dentry *new)
656668
{
@@ -670,7 +682,7 @@ static int ovl_link(struct dentry *old, struct inode *newdir,
670682
goto out_drop_write;
671683

672684
if (ovl_is_metacopy_dentry(old)) {
673-
err = ovl_set_redirect(old, false);
685+
err = ovl_set_link_redirect(old);
674686
if (err)
675687
goto out_drop_write;
676688
}

fs/overlayfs/export.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -754,9 +754,8 @@ static struct dentry *ovl_lower_fh_to_d(struct super_block *sb,
754754
goto out;
755755
}
756756

757-
/* Otherwise, get a connected non-upper dir or disconnected non-dir */
758-
if (d_is_dir(origin.dentry) &&
759-
(origin.dentry->d_flags & DCACHE_DISCONNECTED)) {
757+
/* Find origin.dentry again with ovl_acceptable() layer check */
758+
if (d_is_dir(origin.dentry)) {
760759
dput(origin.dentry);
761760
origin.dentry = NULL;
762761
err = ovl_check_origin_fh(ofs, fh, true, NULL, &stack);
@@ -769,6 +768,7 @@ static struct dentry *ovl_lower_fh_to_d(struct super_block *sb,
769768
goto out_err;
770769
}
771770

771+
/* Get a connected non-upper dir or disconnected non-dir */
772772
dentry = ovl_get_dentry(sb, NULL, &origin, index);
773773

774774
out:

fs/overlayfs/inode.c

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -286,22 +286,13 @@ int ovl_permission(struct inode *inode, int mask)
286286
if (err)
287287
return err;
288288

289-
/* No need to do any access on underlying for special files */
290-
if (special_file(realinode->i_mode))
291-
return 0;
292-
293-
/* No need to access underlying for execute */
294-
mask &= ~MAY_EXEC;
295-
if ((mask & (MAY_READ | MAY_WRITE)) == 0)
296-
return 0;
297-
298-
/* Lower files get copied up, so turn write access into read */
299-
if (!upperinode && mask & MAY_WRITE) {
289+
old_cred = ovl_override_creds(inode->i_sb);
290+
if (!upperinode &&
291+
!special_file(realinode->i_mode) && mask & MAY_WRITE) {
300292
mask &= ~(MAY_WRITE | MAY_APPEND);
293+
/* Make sure mounter can read file for copy up later */
301294
mask |= MAY_READ;
302295
}
303-
304-
old_cred = ovl_override_creds(inode->i_sb);
305296
err = inode_permission(realinode, mask);
306297
revert_creds(old_cred);
307298

0 commit comments

Comments
 (0)