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

Changed files
+33 -8
fs
overlayfs
+26 -3
fs/overlayfs/inode.c
··· 59 59 if (err) 60 60 goto out; 61 61 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 + 62 70 err = ovl_copy_up(dentry); 63 71 if (!err) { 72 + struct inode *winode = NULL; 73 + 64 74 upperdentry = ovl_dentry_upper(dentry); 75 + 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 + } 65 82 66 83 inode_lock(upperdentry->d_inode); 67 84 err = notify_change(upperdentry, attr, NULL); 68 85 if (!err) 69 86 ovl_copyattr(upperdentry->d_inode, dentry->d_inode); 70 87 inode_unlock(upperdentry->d_inode); 88 + 89 + if (winode) 90 + put_write_access(winode); 71 91 } 92 + out_drop_write: 72 93 ovl_drop_write(dentry); 73 94 out: 74 95 return err; ··· 142 121 143 122 err = vfs_getattr(&realpath, &stat); 144 123 if (err) 145 - return err; 124 + goto out_dput; 146 125 126 + err = -ESTALE; 147 127 if ((stat.mode ^ inode->i_mode) & S_IFMT) 148 - return -ESTALE; 128 + goto out_dput; 149 129 150 130 inode->i_mode = stat.mode; 151 131 inode->i_uid = stat.uid; 152 132 inode->i_gid = stat.gid; 153 133 154 - return generic_permission(inode, mask); 134 + err = generic_permission(inode, mask); 135 + goto out_dput; 155 136 } 156 137 157 138 /* Careful in RCU walk mode */
+7 -5
fs/overlayfs/super.c
··· 1082 1082 if (err < 0) 1083 1083 goto out_put_workdir; 1084 1084 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"); 1090 1092 } 1091 1093 } 1092 1094