diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-07-03 14:57:09 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-07-03 14:57:09 -0400 |
commit | 236bfd8ed868edfc42a656682487683ade3fede4 (patch) | |
tree | e1311ab7ca76f663f837c7adf9aacd27492939bb | |
parent | 4f302921c1458d790ae21147f7043f4e6b6a1085 (diff) | |
parent | e7c0b5991dd1be7b6f6dc2b54a15a0f47b64b007 (diff) |
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
-rw-r--r-- | fs/overlayfs/inode.c | 29 | ||||
-rw-r--r-- | fs/overlayfs/super.c | 12 |
2 files changed, 33 insertions, 8 deletions
diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c index 1dbeab6cf96e..c831c2e5f803 100644 --- a/fs/overlayfs/inode.c +++ b/fs/overlayfs/inode.c | |||
@@ -59,16 +59,37 @@ int ovl_setattr(struct dentry *dentry, struct iattr *attr) | |||
59 | if (err) | 59 | if (err) |
60 | goto out; | 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 | err = ovl_copy_up(dentry); | 70 | err = ovl_copy_up(dentry); |
63 | if (!err) { | 71 | if (!err) { |
72 | struct inode *winode = NULL; | ||
73 | |||
64 | upperdentry = ovl_dentry_upper(dentry); | 74 | upperdentry = ovl_dentry_upper(dentry); |
65 | 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 | } | ||
82 | |||
66 | inode_lock(upperdentry->d_inode); | 83 | inode_lock(upperdentry->d_inode); |
67 | err = notify_change(upperdentry, attr, NULL); | 84 | err = notify_change(upperdentry, attr, NULL); |
68 | if (!err) | 85 | if (!err) |
69 | ovl_copyattr(upperdentry->d_inode, dentry->d_inode); | 86 | ovl_copyattr(upperdentry->d_inode, dentry->d_inode); |
70 | inode_unlock(upperdentry->d_inode); | 87 | inode_unlock(upperdentry->d_inode); |
88 | |||
89 | if (winode) | ||
90 | put_write_access(winode); | ||
71 | } | 91 | } |
92 | out_drop_write: | ||
72 | ovl_drop_write(dentry); | 93 | ovl_drop_write(dentry); |
73 | out: | 94 | out: |
74 | return err; | 95 | return err; |
@@ -121,16 +142,18 @@ int ovl_permission(struct inode *inode, int mask) | |||
121 | 142 | ||
122 | err = vfs_getattr(&realpath, &stat); | 143 | err = vfs_getattr(&realpath, &stat); |
123 | if (err) | 144 | if (err) |
124 | return err; | 145 | goto out_dput; |
125 | 146 | ||
147 | err = -ESTALE; | ||
126 | if ((stat.mode ^ inode->i_mode) & S_IFMT) | 148 | if ((stat.mode ^ inode->i_mode) & S_IFMT) |
127 | return -ESTALE; | 149 | goto out_dput; |
128 | 150 | ||
129 | inode->i_mode = stat.mode; | 151 | inode->i_mode = stat.mode; |
130 | inode->i_uid = stat.uid; | 152 | inode->i_uid = stat.uid; |
131 | inode->i_gid = stat.gid; | 153 | inode->i_gid = stat.gid; |
132 | 154 | ||
133 | return generic_permission(inode, mask); | 155 | err = generic_permission(inode, mask); |
156 | goto out_dput; | ||
134 | } | 157 | } |
135 | 158 | ||
136 | /* Careful in RCU walk mode */ | 159 | /* Careful in RCU walk mode */ |
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index ce02f46029da..9a7693d5f8ff 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c | |||
@@ -1082,11 +1082,13 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) | |||
1082 | if (err < 0) | 1082 | if (err < 0) |
1083 | goto out_put_workdir; | 1083 | goto out_put_workdir; |
1084 | 1084 | ||
1085 | if (!err) { | 1085 | /* |
1086 | pr_err("overlayfs: upper fs needs to support d_type.\n"); | 1086 | * We allowed this configuration and don't want to |
1087 | err = -EINVAL; | 1087 | * break users over kernel upgrade. So warn instead |
1088 | goto out_put_workdir; | 1088 | * of erroring out. |
1089 | } | 1089 | */ |
1090 | if (!err) | ||
1091 | pr_warn("overlayfs: upper fs needs to support d_type.\n"); | ||
1090 | } | 1092 | } |
1091 | } | 1093 | } |
1092 | 1094 | ||