]>
Commit | Line | Data |
---|---|---|
4d1e5b62 AF |
1 | From: Tony Jones <tonyj@suse.de> |
2 | Subject: Add a vfsmount parameter to notify_change() | |
3 | ||
4 | The vfsmount parameter must be set appropriately for files visibile | |
5 | outside the kernel. Files that are only used in a filesystem (e.g., | |
6 | reiserfs xattr files) will have a NULL vfsmount. | |
7 | ||
8 | Signed-off-by: Tony Jones <tonyj@suse.de> | |
9 | Signed-off-by: Andreas Gruenbacher <agruen@suse.de> | |
10 | Signed-off-by: John Johansen <jjohansen@suse.de> | |
11 | ||
12 | --- | |
13 | fs/attr.c | 3 ++- | |
14 | fs/ecryptfs/inode.c | 4 +++- | |
15 | fs/exec.c | 3 ++- | |
16 | fs/hpfs/namei.c | 2 +- | |
17 | fs/namei.c | 2 +- | |
18 | fs/nfsd/vfs.c | 8 ++++---- | |
19 | fs/open.c | 28 +++++++++++++++------------- | |
20 | fs/utimes.c | 2 +- | |
21 | include/linux/fs.h | 6 +++--- | |
22 | mm/filemap.c | 2 +- | |
23 | 10 files changed, 33 insertions(+), 27 deletions(-) | |
24 | ||
25 | --- a/fs/attr.c | |
26 | +++ b/fs/attr.c | |
27 | @@ -100,7 +100,8 @@ int inode_setattr(struct inode * inode, | |
28 | } | |
29 | EXPORT_SYMBOL(inode_setattr); | |
30 | ||
31 | -int notify_change(struct dentry * dentry, struct iattr * attr) | |
32 | +int notify_change(struct dentry *dentry, struct vfsmount *mnt, | |
33 | + struct iattr *attr) | |
34 | { | |
35 | struct inode *inode = dentry->d_inode; | |
36 | mode_t mode = inode->i_mode; | |
37 | --- a/fs/ecryptfs/inode.c | |
38 | +++ b/fs/ecryptfs/inode.c | |
39 | @@ -850,6 +850,7 @@ static int ecryptfs_setattr(struct dentr | |
40 | { | |
41 | int rc = 0; | |
42 | struct dentry *lower_dentry; | |
43 | + struct vfsmount *lower_mnt; | |
44 | struct inode *inode; | |
45 | struct inode *lower_inode; | |
46 | struct ecryptfs_crypt_stat *crypt_stat; | |
47 | @@ -860,6 +861,7 @@ static int ecryptfs_setattr(struct dentr | |
48 | inode = dentry->d_inode; | |
49 | lower_inode = ecryptfs_inode_to_lower(inode); | |
50 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | |
51 | + lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); | |
52 | mutex_lock(&crypt_stat->cs_mutex); | |
53 | if (S_ISDIR(dentry->d_inode->i_mode)) | |
54 | crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); | |
55 | @@ -911,7 +913,7 @@ static int ecryptfs_setattr(struct dentr | |
56 | ia->ia_valid &= ~ATTR_MODE; | |
57 | ||
58 | mutex_lock(&lower_dentry->d_inode->i_mutex); | |
59 | - rc = notify_change(lower_dentry, ia); | |
60 | + rc = notify_change(lower_dentry, lower_mnt, ia); | |
61 | mutex_unlock(&lower_dentry->d_inode->i_mutex); | |
62 | out: | |
63 | fsstack_copy_attr_all(inode, lower_inode, NULL); | |
64 | --- a/fs/exec.c | |
65 | +++ b/fs/exec.c | |
66 | @@ -1841,7 +1841,8 @@ int do_coredump(long signr, int exit_cod | |
67 | goto close_fail; | |
68 | if (!file->f_op->write) | |
69 | goto close_fail; | |
70 | - if (!ispipe && do_truncate(file->f_path.dentry, 0, 0, file) != 0) | |
71 | + if (!ispipe && | |
72 | + do_truncate(file->f_path.dentry, file->f_path.mnt, 0, 0, file) != 0) | |
73 | goto close_fail; | |
74 | ||
75 | retval = binfmt->core_dump(signr, regs, file, core_limit); | |
76 | --- a/fs/hpfs/namei.c | |
77 | +++ b/fs/hpfs/namei.c | |
78 | @@ -426,7 +426,7 @@ again: | |
79 | /*printk("HPFS: truncating file before delete.\n");*/ | |
80 | newattrs.ia_size = 0; | |
81 | newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME; | |
82 | - err = notify_change(dentry, &newattrs); | |
83 | + err = notify_change(dentry, NULL, &newattrs); | |
84 | put_write_access(inode); | |
85 | if (!err) | |
86 | goto again; | |
87 | --- a/fs/namei.c | |
88 | +++ b/fs/namei.c | |
89 | @@ -1619,7 +1619,7 @@ int may_open(struct nameidata *nd, int a | |
90 | if (!error) { | |
91 | DQUOT_INIT(inode); | |
92 | ||
93 | - error = do_truncate(dentry, 0, | |
94 | + error = do_truncate(dentry, nd->path.mnt, 0, | |
95 | ATTR_MTIME|ATTR_CTIME|ATTR_OPEN, | |
96 | NULL); | |
97 | } | |
98 | --- a/fs/nfsd/vfs.c | |
99 | +++ b/fs/nfsd/vfs.c | |
100 | @@ -397,7 +397,7 @@ nfsd_setattr(struct svc_rqst *rqstp, str | |
101 | err = nfserr_notsync; | |
102 | if (!check_guard || guardtime == inode->i_ctime.tv_sec) { | |
103 | fh_lock(fhp); | |
104 | - host_err = notify_change(dentry, iap); | |
105 | + host_err = notify_change(dentry, fhp->fh_export->ex_path.mnt, iap); | |
106 | /* to get NFSERR_JUKEBOX on the wire, need -ETIMEDOUT */ | |
107 | if (host_err == -EAGAIN) | |
108 | host_err = -ETIMEDOUT; | |
109 | @@ -964,13 +964,13 @@ out: | |
110 | return err; | |
111 | } | |
112 | ||
113 | -static void kill_suid(struct dentry *dentry) | |
114 | +static void kill_suid(struct dentry *dentry, struct vfsmount *mnt) | |
115 | { | |
116 | struct iattr ia; | |
117 | ia.ia_valid = ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV; | |
118 | ||
119 | mutex_lock(&dentry->d_inode->i_mutex); | |
120 | - notify_change(dentry, &ia); | |
121 | + notify_change(dentry, mnt, &ia); | |
122 | mutex_unlock(&dentry->d_inode->i_mutex); | |
123 | } | |
124 | ||
125 | @@ -1033,7 +1033,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, s | |
126 | ||
127 | /* clear setuid/setgid flag after write */ | |
128 | if (host_err >= 0 && (inode->i_mode & (S_ISUID | S_ISGID))) | |
129 | - kill_suid(dentry); | |
130 | + kill_suid(dentry, exp->ex_path.mnt); | |
131 | ||
132 | if (host_err >= 0 && stable) { | |
133 | static ino_t last_ino; | |
134 | --- a/fs/open.c | |
135 | +++ b/fs/open.c | |
136 | @@ -195,8 +195,8 @@ out: | |
137 | return error; | |
138 | } | |
139 | ||
140 | -int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs, | |
141 | - struct file *filp) | |
142 | +int do_truncate(struct dentry *dentry, struct vfsmount *mnt, loff_t length, | |
143 | + unsigned int time_attrs, struct file *filp) | |
144 | { | |
145 | int err; | |
146 | struct iattr newattrs; | |
147 | @@ -216,7 +216,7 @@ int do_truncate(struct dentry *dentry, l | |
148 | newattrs.ia_valid |= should_remove_suid(dentry); | |
149 | ||
150 | mutex_lock(&dentry->d_inode->i_mutex); | |
151 | - err = notify_change(dentry, &newattrs); | |
152 | + err = notify_change(dentry, mnt, &newattrs); | |
153 | mutex_unlock(&dentry->d_inode->i_mutex); | |
154 | return err; | |
155 | } | |
156 | @@ -272,7 +272,7 @@ static long do_sys_truncate(const char _ | |
157 | error = locks_verify_truncate(inode, NULL, length); | |
158 | if (!error) { | |
159 | DQUOT_INIT(inode); | |
160 | - error = do_truncate(path.dentry, length, 0, NULL); | |
161 | + error = do_truncate(path.dentry, path.mnt, length, 0, NULL); | |
162 | } | |
163 | ||
164 | put_write_and_out: | |
165 | @@ -327,7 +327,8 @@ static long do_sys_ftruncate(unsigned in | |
166 | ||
167 | error = locks_verify_truncate(inode, file, length); | |
168 | if (!error) | |
169 | - error = do_truncate(dentry, length, ATTR_MTIME|ATTR_CTIME, file); | |
170 | + error = do_truncate(dentry, file->f_path.mnt, length, | |
171 | + ATTR_MTIME|ATTR_CTIME, file); | |
172 | out_putf: | |
173 | fput(file); | |
174 | out: | |
175 | @@ -624,7 +625,7 @@ SYSCALL_DEFINE2(fchmod, unsigned int, fd | |
176 | mode = inode->i_mode; | |
177 | newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); | |
178 | newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; | |
179 | - err = notify_change(dentry, &newattrs); | |
180 | + err = notify_change(dentry, file->f_path.mnt, &newattrs); | |
181 | mutex_unlock(&inode->i_mutex); | |
182 | mnt_drop_write(file->f_path.mnt); | |
183 | out_putf: | |
184 | @@ -653,7 +654,7 @@ SYSCALL_DEFINE3(fchmodat, int, dfd, cons | |
185 | mode = inode->i_mode; | |
186 | newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); | |
187 | newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; | |
188 | - error = notify_change(path.dentry, &newattrs); | |
189 | + error = notify_change(path.dentry, path.mnt, &newattrs); | |
190 | mutex_unlock(&inode->i_mutex); | |
191 | mnt_drop_write(path.mnt); | |
192 | dput_and_out: | |
193 | @@ -667,7 +668,8 @@ SYSCALL_DEFINE2(chmod, const char __user | |
194 | return sys_fchmodat(AT_FDCWD, filename, mode); | |
195 | } | |
196 | ||
197 | -static int chown_common(struct dentry * dentry, uid_t user, gid_t group) | |
198 | +static int chown_common(struct dentry * dentry, struct vfsmount *mnt, | |
199 | + uid_t user, gid_t group) | |
200 | { | |
201 | struct inode *inode = dentry->d_inode; | |
202 | int error; | |
203 | @@ -686,7 +688,7 @@ static int chown_common(struct dentry * | |
204 | newattrs.ia_valid |= | |
205 | ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV; | |
206 | mutex_lock(&inode->i_mutex); | |
207 | - error = notify_change(dentry, &newattrs); | |
208 | + error = notify_change(dentry, mnt, &newattrs); | |
209 | mutex_unlock(&inode->i_mutex); | |
210 | ||
211 | return error; | |
212 | @@ -703,7 +705,7 @@ SYSCALL_DEFINE3(chown, const char __user | |
213 | error = mnt_want_write(path.mnt); | |
214 | if (error) | |
215 | goto out_release; | |
216 | - error = chown_common(path.dentry, user, group); | |
217 | + error = chown_common(path.dentry, path.mnt, user, group); | |
218 | mnt_drop_write(path.mnt); | |
219 | out_release: | |
220 | path_put(&path); | |
221 | @@ -728,7 +730,7 @@ SYSCALL_DEFINE5(fchownat, int, dfd, cons | |
222 | error = mnt_want_write(path.mnt); | |
223 | if (error) | |
224 | goto out_release; | |
225 | - error = chown_common(path.dentry, user, group); | |
226 | + error = chown_common(path.dentry, path.mnt, user, group); | |
227 | mnt_drop_write(path.mnt); | |
228 | out_release: | |
229 | path_put(&path); | |
230 | @@ -747,7 +749,7 @@ SYSCALL_DEFINE3(lchown, const char __use | |
231 | error = mnt_want_write(path.mnt); | |
232 | if (error) | |
233 | goto out_release; | |
234 | - error = chown_common(path.dentry, user, group); | |
235 | + error = chown_common(path.dentry, path.mnt, user, group); | |
236 | mnt_drop_write(path.mnt); | |
237 | out_release: | |
238 | path_put(&path); | |
239 | @@ -770,7 +772,7 @@ SYSCALL_DEFINE3(fchown, unsigned int, fd | |
240 | goto out_fput; | |
241 | dentry = file->f_path.dentry; | |
242 | audit_inode(NULL, dentry); | |
243 | - error = chown_common(dentry, user, group); | |
244 | + error = chown_common(dentry, file->f_path.mnt, user, group); | |
245 | mnt_drop_write(file->f_path.mnt); | |
246 | out_fput: | |
247 | fput(file); | |
248 | --- a/fs/utimes.c | |
249 | +++ b/fs/utimes.c | |
250 | @@ -102,7 +102,7 @@ static int utimes_common(struct path *pa | |
251 | } | |
252 | } | |
253 | mutex_lock(&inode->i_mutex); | |
254 | - error = notify_change(path->dentry, &newattrs); | |
255 | + error = notify_change(path->dentry, path->mnt, &newattrs); | |
256 | mutex_unlock(&inode->i_mutex); | |
257 | ||
258 | mnt_drop_write_and_out: | |
259 | --- a/include/linux/fs.h | |
260 | +++ b/include/linux/fs.h | |
261 | @@ -1636,8 +1636,8 @@ static inline int break_lease(struct ino | |
262 | ||
263 | /* fs/open.c */ | |
264 | ||
265 | -extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs, | |
266 | - struct file *filp); | |
267 | +extern int do_truncate(struct dentry *, struct vfsmount *, loff_t start, | |
268 | + unsigned int time_attrs, struct file *filp); | |
269 | extern long do_sys_open(int dfd, const char __user *filename, int flags, | |
270 | int mode); | |
271 | extern struct file *filp_open(const char *, int, int); | |
272 | @@ -1798,7 +1798,7 @@ extern int do_remount_sb(struct super_bl | |
273 | #ifdef CONFIG_BLOCK | |
274 | extern sector_t bmap(struct inode *, sector_t); | |
275 | #endif | |
276 | -extern int notify_change(struct dentry *, struct iattr *); | |
277 | +extern int notify_change(struct dentry *, struct vfsmount *, struct iattr *); | |
278 | extern int inode_permission(struct inode *, int); | |
279 | extern int generic_permission(struct inode *, int, | |
280 | int (*check_acl)(struct inode *, int)); | |
281 | --- a/mm/filemap.c | |
282 | +++ b/mm/filemap.c | |
283 | @@ -1831,7 +1831,7 @@ static int __remove_suid(struct path *pa | |
284 | struct iattr newattrs; | |
285 | ||
286 | newattrs.ia_valid = ATTR_FORCE | kill; | |
287 | - return notify_change(path->dentry, &newattrs); | |
288 | + return notify_change(path->dentry, path->mnt, &newattrs); | |
289 | } | |
290 | ||
291 | int file_remove_suid(struct file *file) |