Skip to content

Commit 236bfd8

Browse files
committed
Merge branch 'overlayfs-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs
Pull overlayfs fixes from Miklos Szeredi: "This contains fixes for a dentry leak, a regression in 4.6 noticed by Docker users and missing write access checking in truncate" * 'overlayfs-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs: ovl: warn instead of error if d_type is not supported ovl: get_write_access() in truncate ovl: fix dentry leak for default_permissions
2 parents 4f30292 + e7c0b59 commit 236bfd8

File tree

2 files changed

+33
-8
lines changed

2 files changed

+33
-8
lines changed

fs/overlayfs/inode.c

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,16 +59,37 @@ int ovl_setattr(struct dentry *dentry, struct iattr *attr)
5959
if (err)
6060
goto out;
6161

62+
if (attr->ia_valid & ATTR_SIZE) {
63+
struct inode *realinode = d_inode(ovl_dentry_real(dentry));
64+
65+
err = -ETXTBSY;
66+
if (atomic_read(&realinode->i_writecount) < 0)
67+
goto out_drop_write;
68+
}
69+
6270
err = ovl_copy_up(dentry);
6371
if (!err) {
72+
struct inode *winode = NULL;
73+
6474
upperdentry = ovl_dentry_upper(dentry);
6575

76+
if (attr->ia_valid & ATTR_SIZE) {
77+
winode = d_inode(upperdentry);
78+
err = get_write_access(winode);
79+
if (err)
80+
goto out_drop_write;
81+
}
82+
6683
inode_lock(upperdentry->d_inode);
6784
err = notify_change(upperdentry, attr, NULL);
6885
if (!err)
6986
ovl_copyattr(upperdentry->d_inode, dentry->d_inode);
7087
inode_unlock(upperdentry->d_inode);
88+
89+
if (winode)
90+
put_write_access(winode);
7191
}
92+
out_drop_write:
7293
ovl_drop_write(dentry);
7394
out:
7495
return err;
@@ -121,16 +142,18 @@ int ovl_permission(struct inode *inode, int mask)
121142

122143
err = vfs_getattr(&realpath, &stat);
123144
if (err)
124-
return err;
145+
goto out_dput;
125146

147+
err = -ESTALE;
126148
if ((stat.mode ^ inode->i_mode) & S_IFMT)
127-
return -ESTALE;
149+
goto out_dput;
128150

129151
inode->i_mode = stat.mode;
130152
inode->i_uid = stat.uid;
131153
inode->i_gid = stat.gid;
132154

133-
return generic_permission(inode, mask);
155+
err = generic_permission(inode, mask);
156+
goto out_dput;
134157
}
135158

136159
/* Careful in RCU walk mode */

fs/overlayfs/super.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1082,11 +1082,13 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
10821082
if (err < 0)
10831083
goto out_put_workdir;
10841084

1085-
if (!err) {
1086-
pr_err("overlayfs: upper fs needs to support d_type.\n");
1087-
err = -EINVAL;
1088-
goto out_put_workdir;
1089-
}
1085+
/*
1086+
* We allowed this configuration and don't want to
1087+
* break users over kernel upgrade. So warn instead
1088+
* of erroring out.
1089+
*/
1090+
if (!err)
1091+
pr_warn("overlayfs: upper fs needs to support d_type.\n");
10901092
}
10911093
}
10921094

0 commit comments

Comments
 (0)