]>
Commit | Line | Data |
---|---|---|
8f69975d BS |
1 | From: Andreas Gruenbacher <agruen@suse.de> |
2 | Subject: Pass struct file down the inode_*xattr security LSM hooks | |
3 | ||
4 | This allows LSMs to also distinguish between file descriptor and path | |
5 | access for the xattr operations. (The other relevant operations are | |
6 | covered by the setattr hook.) | |
7 | ||
8 | Signed-off-by: Andreas Gruenbacher <agruen@suse.de> | |
9 | Signed-off-by: John Johansen <jjohansen@suse.de> | |
10 | ||
11 | --- | |
12 | fs/xattr.c | 59 +++++++++++++++++++++++---------------------- | |
13 | include/linux/security.h | 38 ++++++++++++++++------------ | |
14 | include/linux/xattr.h | 9 +++--- | |
15 | security/capability.c | 5 ++- | |
16 | security/commoncap.c | 4 +-- | |
17 | security/security.c | 17 ++++++------ | |
18 | security/selinux/hooks.c | 10 ++++--- | |
19 | security/smack/smack_lsm.c | 14 ++++++---- | |
20 | 8 files changed, 87 insertions(+), 69 deletions(-) | |
21 | ||
22 | --- a/fs/xattr.c | |
23 | +++ b/fs/xattr.c | |
24 | @@ -68,7 +68,7 @@ xattr_permission(struct inode *inode, co | |
25 | ||
26 | int | |
27 | vfs_setxattr(struct dentry *dentry, struct vfsmount *mnt, const char *name, | |
28 | - const void *value, size_t size, int flags) | |
29 | + const void *value, size_t size, int flags, struct file *file) | |
30 | { | |
31 | struct inode *inode = dentry->d_inode; | |
32 | int error; | |
33 | @@ -78,7 +78,7 @@ vfs_setxattr(struct dentry *dentry, stru | |
34 | return error; | |
35 | ||
36 | mutex_lock(&inode->i_mutex); | |
37 | - error = security_inode_setxattr(dentry, mnt, name, value, size, flags); | |
38 | + error = security_inode_setxattr(dentry, mnt, name, value, size, flags, file); | |
39 | if (error) | |
40 | goto out; | |
41 | error = -EOPNOTSUPP; | |
42 | @@ -132,7 +132,7 @@ EXPORT_SYMBOL_GPL(xattr_getsecurity); | |
43 | ||
44 | ssize_t | |
45 | vfs_getxattr(struct dentry *dentry, struct vfsmount *mnt, const char *name, | |
46 | - void *value, size_t size) | |
47 | + void *value, size_t size, struct file *file) | |
48 | { | |
49 | struct inode *inode = dentry->d_inode; | |
50 | int error; | |
51 | @@ -141,7 +141,7 @@ vfs_getxattr(struct dentry *dentry, stru | |
52 | if (error) | |
53 | return error; | |
54 | ||
55 | - error = security_inode_getxattr(dentry, mnt, name); | |
56 | + error = security_inode_getxattr(dentry, mnt, name, file); | |
57 | if (error) | |
58 | return error; | |
59 | ||
60 | @@ -169,12 +169,12 @@ EXPORT_SYMBOL_GPL(vfs_getxattr); | |
61 | ||
62 | ssize_t | |
63 | vfs_listxattr(struct dentry *dentry, struct vfsmount *mnt, char *list, | |
64 | - size_t size) | |
65 | + size_t size, struct file *file) | |
66 | { | |
67 | struct inode *inode = dentry->d_inode; | |
68 | ssize_t error; | |
69 | ||
70 | - error = security_inode_listxattr(dentry, mnt); | |
71 | + error = security_inode_listxattr(dentry, mnt, file); | |
72 | if (error) | |
73 | return error; | |
74 | error = -EOPNOTSUPP; | |
75 | @@ -190,7 +190,8 @@ vfs_listxattr(struct dentry *dentry, str | |
76 | EXPORT_SYMBOL_GPL(vfs_listxattr); | |
77 | ||
78 | int | |
79 | -vfs_removexattr(struct dentry *dentry, struct vfsmount *mnt, const char *name) | |
80 | +vfs_removexattr(struct dentry *dentry, struct vfsmount *mnt, const char *name, | |
81 | + struct file *file) | |
82 | { | |
83 | struct inode *inode = dentry->d_inode; | |
84 | int error; | |
85 | @@ -202,7 +203,7 @@ vfs_removexattr(struct dentry *dentry, s | |
86 | if (error) | |
87 | return error; | |
88 | ||
89 | - error = security_inode_removexattr(dentry, mnt, name); | |
90 | + error = security_inode_removexattr(dentry, mnt, name, file); | |
91 | if (error) | |
92 | return error; | |
93 | ||
94 | @@ -222,7 +223,7 @@ EXPORT_SYMBOL_GPL(vfs_removexattr); | |
95 | */ | |
96 | static long | |
97 | setxattr(struct dentry *dentry, struct vfsmount *mnt, const char __user *name, | |
98 | - const void __user *value, size_t size, int flags) | |
99 | + const void __user *value, size_t size, int flags, struct file *file) | |
100 | { | |
101 | int error; | |
102 | void *kvalue = NULL; | |
103 | @@ -249,7 +250,7 @@ setxattr(struct dentry *dentry, struct v | |
104 | } | |
105 | } | |
106 | ||
107 | - error = vfs_setxattr(dentry, mnt, kname, kvalue, size, flags); | |
108 | + error = vfs_setxattr(dentry, mnt, kname, kvalue, size, flags, file); | |
109 | kfree(kvalue); | |
110 | return error; | |
111 | } | |
112 | @@ -266,7 +267,7 @@ SYSCALL_DEFINE5(setxattr, const char __u | |
113 | return error; | |
114 | error = mnt_want_write(path.mnt); | |
115 | if (!error) { | |
116 | - error = setxattr(path.dentry, path.mnt, name, value, size, flags); | |
117 | + error = setxattr(path.dentry, path.mnt, name, value, size, flags, NULL); | |
118 | mnt_drop_write(path.mnt); | |
119 | } | |
120 | path_put(&path); | |
121 | @@ -285,7 +286,7 @@ SYSCALL_DEFINE5(lsetxattr, const char __ | |
122 | return error; | |
123 | error = mnt_want_write(path.mnt); | |
124 | if (!error) { | |
125 | - error = setxattr(path.dentry, path.mnt, name, value, size, flags); | |
126 | + error = setxattr(path.dentry, path.mnt, name, value, size, flags, NULL); | |
127 | mnt_drop_write(path.mnt); | |
128 | } | |
129 | path_put(&path); | |
130 | @@ -306,7 +307,8 @@ SYSCALL_DEFINE5(fsetxattr, int, fd, cons | |
131 | audit_inode(NULL, dentry); | |
132 | error = mnt_want_write_file(f->f_path.mnt, f); | |
133 | if (!error) { | |
134 | - error = setxattr(dentry, f->f_vfsmnt, name, value, size, flags); | |
135 | + error = setxattr(dentry, f->f_vfsmnt, name, value, size, flags, | |
136 | + f); | |
137 | mnt_drop_write(f->f_path.mnt); | |
138 | } | |
139 | fput(f); | |
140 | @@ -318,7 +320,7 @@ SYSCALL_DEFINE5(fsetxattr, int, fd, cons | |
141 | */ | |
142 | static ssize_t | |
143 | getxattr(struct dentry *dentry, struct vfsmount *mnt, const char __user *name, | |
144 | - void __user *value, size_t size) | |
145 | + void __user *value, size_t size, struct file *file) | |
146 | { | |
147 | ssize_t error; | |
148 | void *kvalue = NULL; | |
149 | @@ -338,7 +340,7 @@ getxattr(struct dentry *dentry, struct v | |
150 | return -ENOMEM; | |
151 | } | |
152 | ||
153 | - error = vfs_getxattr(dentry, mnt, kname, kvalue, size); | |
154 | + error = vfs_getxattr(dentry, mnt, kname, kvalue, size, file); | |
155 | if (error > 0) { | |
156 | if (size && copy_to_user(value, kvalue, error)) | |
157 | error = -EFAULT; | |
158 | @@ -360,7 +362,7 @@ SYSCALL_DEFINE4(getxattr, const char __u | |
159 | error = user_path(pathname, &path); | |
160 | if (error) | |
161 | return error; | |
162 | - error = getxattr(path.dentry, path.mnt, name, value, size); | |
163 | + error = getxattr(path.dentry, path.mnt, name, value, size, NULL); | |
164 | path_put(&path); | |
165 | return error; | |
166 | } | |
167 | @@ -374,7 +376,7 @@ SYSCALL_DEFINE4(lgetxattr, const char __ | |
168 | error = user_lpath(pathname, &path); | |
169 | if (error) | |
170 | return error; | |
171 | - error = getxattr(path.dentry, path.mnt, name, value, size); | |
172 | + error = getxattr(path.dentry, path.mnt, name, value, size, NULL); | |
173 | path_put(&path); | |
174 | return error; | |
175 | } | |
176 | @@ -389,7 +391,7 @@ SYSCALL_DEFINE4(fgetxattr, int, fd, cons | |
177 | if (!f) | |
178 | return error; | |
179 | audit_inode(NULL, f->f_path.dentry); | |
180 | - error = getxattr(f->f_path.dentry, f->f_path.mnt, name, value, size); | |
181 | + error = getxattr(f->f_path.dentry, f->f_path.mnt, name, value, size, f); | |
182 | fput(f); | |
183 | return error; | |
184 | } | |
185 | @@ -399,7 +401,7 @@ SYSCALL_DEFINE4(fgetxattr, int, fd, cons | |
186 | */ | |
187 | static ssize_t | |
188 | listxattr(struct dentry *dentry, struct vfsmount *mnt, char __user *list, | |
189 | - size_t size) | |
190 | + size_t size, struct file *file) | |
191 | { | |
192 | ssize_t error; | |
193 | char *klist = NULL; | |
194 | @@ -412,7 +414,7 @@ listxattr(struct dentry *dentry, struct | |
195 | return -ENOMEM; | |
196 | } | |
197 | ||
198 | - error = vfs_listxattr(dentry, mnt, klist, size); | |
199 | + error = vfs_listxattr(dentry, mnt, klist, size, file); | |
200 | if (error > 0) { | |
201 | if (size && copy_to_user(list, klist, error)) | |
202 | error = -EFAULT; | |
203 | @@ -434,7 +436,7 @@ SYSCALL_DEFINE3(listxattr, const char __ | |
204 | error = user_path(pathname, &path); | |
205 | if (error) | |
206 | return error; | |
207 | - error = listxattr(path.dentry, path.mnt, list, size); | |
208 | + error = listxattr(path.dentry, path.mnt, list, size, NULL); | |
209 | path_put(&path); | |
210 | return error; | |
211 | } | |
212 | @@ -448,7 +450,7 @@ SYSCALL_DEFINE3(llistxattr, const char _ | |
213 | error = user_lpath(pathname, &path); | |
214 | if (error) | |
215 | return error; | |
216 | - error = listxattr(path.dentry, path.mnt, list, size); | |
217 | + error = listxattr(path.dentry, path.mnt, list, size, NULL); | |
218 | path_put(&path); | |
219 | return error; | |
220 | } | |
221 | @@ -462,7 +464,7 @@ SYSCALL_DEFINE3(flistxattr, int, fd, cha | |
222 | if (!f) | |
223 | return error; | |
224 | audit_inode(NULL, f->f_path.dentry); | |
225 | - error = listxattr(f->f_path.dentry, f->f_path.mnt, list, size); | |
226 | + error = listxattr(f->f_path.dentry, f->f_path.mnt, list, size, f); | |
227 | fput(f); | |
228 | return error; | |
229 | } | |
230 | @@ -471,7 +473,8 @@ SYSCALL_DEFINE3(flistxattr, int, fd, cha | |
231 | * Extended attribute REMOVE operations | |
232 | */ | |
233 | static long | |
234 | -removexattr(struct dentry *dentry, struct vfsmount *mnt, const char __user *name) | |
235 | +removexattr(struct dentry *dentry, struct vfsmount *mnt, | |
236 | + const char __user *name, struct file *file) | |
237 | { | |
238 | int error; | |
239 | char kname[XATTR_NAME_MAX + 1]; | |
240 | @@ -482,7 +485,7 @@ removexattr(struct dentry *dentry, struc | |
241 | if (error < 0) | |
242 | return error; | |
243 | ||
244 | - return vfs_removexattr(dentry, mnt, kname); | |
245 | + return vfs_removexattr(dentry, mnt, kname, file); | |
246 | } | |
247 | ||
248 | SYSCALL_DEFINE2(removexattr, const char __user *, pathname, | |
249 | @@ -496,7 +499,7 @@ SYSCALL_DEFINE2(removexattr, const char | |
250 | return error; | |
251 | error = mnt_want_write(path.mnt); | |
252 | if (!error) { | |
253 | - error = removexattr(path.dentry, path.mnt, name); | |
254 | + error = removexattr(path.dentry, path.mnt, name, NULL); | |
255 | mnt_drop_write(path.mnt); | |
256 | } | |
257 | path_put(&path); | |
258 | @@ -514,7 +517,7 @@ SYSCALL_DEFINE2(lremovexattr, const char | |
259 | return error; | |
260 | error = mnt_want_write(path.mnt); | |
261 | if (!error) { | |
262 | - error = removexattr(path.dentry, path.mnt, name); | |
263 | + error = removexattr(path.dentry, path.mnt, name, NULL); | |
264 | mnt_drop_write(path.mnt); | |
265 | } | |
266 | path_put(&path); | |
267 | @@ -534,7 +537,7 @@ SYSCALL_DEFINE2(fremovexattr, int, fd, c | |
268 | audit_inode(NULL, dentry); | |
269 | error = mnt_want_write_file(f->f_path.mnt, f); | |
270 | if (!error) { | |
271 | - error = removexattr(dentry, f->f_path.mnt, name); | |
272 | + error = removexattr(dentry, f->f_path.mnt, name, f); | |
273 | mnt_drop_write(f->f_path.mnt); | |
274 | } | |
275 | fput(f); | |
276 | --- a/include/linux/security.h | |
277 | +++ b/include/linux/security.h | |
278 | @@ -56,9 +56,9 @@ extern void cap_bprm_apply_creds(struct | |
279 | extern int cap_bprm_secureexec(struct linux_binprm *bprm); | |
280 | extern int cap_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt, | |
281 | const char *name, const void *value, size_t size, | |
282 | - int flags); | |
283 | + int flags, struct file *file); | |
284 | extern int cap_inode_removexattr(struct dentry *dentry, struct vfsmount *mnt, | |
285 | - const char *name); | |
286 | + const char *name, struct file *file); | |
287 | extern int cap_inode_need_killpriv(struct dentry *dentry); | |
288 | extern int cap_inode_killpriv(struct dentry *dentry); | |
289 | extern int cap_task_post_setuid(uid_t old_ruid, uid_t old_euid, uid_t old_suid, int flags); | |
290 | @@ -1396,16 +1396,17 @@ struct security_operations { | |
291 | void (*inode_delete) (struct inode *inode); | |
292 | int (*inode_setxattr) (struct dentry *dentry, struct vfsmount *mnt, | |
293 | const char *name, const void *value, size_t size, | |
294 | - int flags); | |
295 | + int flags, struct file *file); | |
296 | void (*inode_post_setxattr) (struct dentry *dentry, | |
297 | struct vfsmount *mnt, | |
298 | const char *name, const void *value, | |
299 | size_t size, int flags); | |
300 | int (*inode_getxattr) (struct dentry *dentry, struct vfsmount *mnt, | |
301 | - const char *name); | |
302 | - int (*inode_listxattr) (struct dentry *dentry, struct vfsmount *mnt); | |
303 | + const char *name, struct file *file); | |
304 | + int (*inode_listxattr) (struct dentry *dentry, struct vfsmount *mnt, | |
305 | + struct file *file); | |
306 | int (*inode_removexattr) (struct dentry *dentry, struct vfsmount *mnt, | |
307 | - const char *name); | |
308 | + const char *name, struct file *file); | |
309 | int (*inode_need_killpriv) (struct dentry *dentry); | |
310 | int (*inode_killpriv) (struct dentry *dentry); | |
311 | int (*inode_getsecurity) (const struct inode *inode, const char *name, void **buffer, bool alloc); | |
312 | @@ -1675,15 +1676,16 @@ int security_inode_getattr(struct vfsmou | |
313 | void security_inode_delete(struct inode *inode); | |
314 | int security_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt, | |
315 | const char *name, const void *value, | |
316 | - size_t size, int flags); | |
317 | + size_t size, int flags, struct file *file); | |
318 | void security_inode_post_setxattr(struct dentry *dentry, struct vfsmount *mnt, | |
319 | const char *name, const void *value, | |
320 | size_t size, int flags); | |
321 | int security_inode_getxattr(struct dentry *dentry, struct vfsmount *mnt, | |
322 | - const char *name); | |
323 | -int security_inode_listxattr(struct dentry *dentry, struct vfsmount *mnt); | |
324 | + const char *name, struct file *file); | |
325 | +int security_inode_listxattr(struct dentry *dentry, struct vfsmount *mnt, | |
326 | + struct file *file); | |
327 | int security_inode_removexattr(struct dentry *dentry, struct vfsmount *mnt, | |
328 | - const char *name); | |
329 | + const char *name, struct file *file); | |
330 | int security_inode_need_killpriv(struct dentry *dentry); | |
331 | int security_inode_killpriv(struct dentry *dentry); | |
332 | int security_inode_getsecurity(const struct inode *inode, const char *name, void **buffer, bool alloc); | |
333 | @@ -2105,9 +2107,10 @@ static inline void security_inode_delete | |
334 | static inline int security_inode_setxattr(struct dentry *dentry, | |
335 | struct vfsmount *mnt, | |
336 | const char *name, const void *value, | |
337 | - size_t size, int flags) | |
338 | + size_t size, int flags, | |
339 | + struct file *file) | |
340 | { | |
341 | - return cap_inode_setxattr(dentry, mnt, name, value, size, flags); | |
342 | + return cap_inode_setxattr(dentry, mnt, name, value, size, flags, file); | |
343 | } | |
344 | ||
345 | static inline void security_inode_post_setxattr(struct dentry *dentry, | |
346 | @@ -2119,22 +2122,25 @@ static inline void security_inode_post_s | |
347 | ||
348 | static inline int security_inode_getxattr(struct dentry *dentry, | |
349 | struct vfsmount *mnt, | |
350 | - const char *name) | |
351 | + const char *name, | |
352 | + struct file *file) | |
353 | { | |
354 | return 0; | |
355 | } | |
356 | ||
357 | static inline int security_inode_listxattr(struct dentry *dentry, | |
358 | - struct vfsmount *mnt) | |
359 | + struct vfsmount *mnt, | |
360 | + struct file *file) | |
361 | { | |
362 | return 0; | |
363 | } | |
364 | ||
365 | static inline int security_inode_removexattr(struct dentry *dentry, | |
366 | struct vfsmount *mnt, | |
367 | - const char *name) | |
368 | + const char *name, | |
369 | + struct file *file) | |
370 | { | |
371 | - return cap_inode_removexattr(dentry, mnt, name); | |
372 | + return cap_inode_removexattr(dentry, mnt, name, file); | |
373 | } | |
374 | ||
375 | static inline int security_inode_need_killpriv(struct dentry *dentry) | |
376 | --- a/include/linux/xattr.h | |
377 | +++ b/include/linux/xattr.h | |
378 | @@ -17,6 +17,7 @@ | |
379 | ||
380 | #include <linux/types.h> | |
381 | #include <linux/mount.h> | |
382 | +#include <linux/fs.h> | |
383 | ||
384 | /* Namespaces */ | |
385 | #define XATTR_OS2_PREFIX "os2." | |
386 | @@ -48,10 +49,10 @@ struct xattr_handler { | |
387 | }; | |
388 | ||
389 | ssize_t xattr_getsecurity(struct inode *, const char *, void *, size_t); | |
390 | -ssize_t vfs_getxattr(struct dentry *, struct vfsmount *, const char *, void *, size_t); | |
391 | -ssize_t vfs_listxattr(struct dentry *d, struct vfsmount *, char *list, size_t size); | |
392 | -int vfs_setxattr(struct dentry *, struct vfsmount *, const char *, const void *, size_t, int); | |
393 | -int vfs_removexattr(struct dentry *, struct vfsmount *mnt, const char *); | |
394 | +ssize_t vfs_getxattr(struct dentry *, struct vfsmount *, const char *, void *, size_t, struct file *file); | |
395 | +ssize_t vfs_listxattr(struct dentry *d, struct vfsmount *, char *list, size_t size, struct file *file); | |
396 | +int vfs_setxattr(struct dentry *, struct vfsmount *, const char *, const void *, size_t, int, struct file *file); | |
397 | +int vfs_removexattr(struct dentry *, struct vfsmount *mnt, const char *, struct file *file); | |
398 | ||
399 | ssize_t generic_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t size); | |
400 | ssize_t generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size); | |
401 | --- a/security/capability.c | |
402 | +++ b/security/capability.c | |
403 | @@ -242,12 +242,13 @@ static void cap_inode_post_setxattr(stru | |
404 | } | |
405 | ||
406 | static int cap_inode_getxattr(struct dentry *dentry, struct vfsmount *mnt, | |
407 | - const char *name) | |
408 | + const char *name, struct file *f) | |
409 | { | |
410 | return 0; | |
411 | } | |
412 | ||
413 | -static int cap_inode_listxattr(struct dentry *dentry, struct vfsmount *mnt) | |
414 | +static int cap_inode_listxattr(struct dentry *dentry, struct vfsmount *mnt, | |
415 | + struct file *f) | |
416 | { | |
417 | return 0; | |
418 | } | |
419 | --- a/security/commoncap.c | |
420 | +++ b/security/commoncap.c | |
421 | @@ -416,7 +416,7 @@ int cap_bprm_secureexec (struct linux_bi | |
422 | ||
423 | int cap_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt, | |
424 | const char *name, const void *value, size_t size, | |
425 | - int flags) | |
426 | + int flags, struct file *file) | |
427 | { | |
428 | if (!strcmp(name, XATTR_NAME_CAPS)) { | |
429 | if (!capable(CAP_SETFCAP)) | |
430 | @@ -430,7 +430,7 @@ int cap_inode_setxattr(struct dentry *de | |
431 | } | |
432 | ||
433 | int cap_inode_removexattr(struct dentry *dentry, struct vfsmount *mnt, | |
434 | - const char *name) | |
435 | + const char *name, struct file *file) | |
436 | { | |
437 | if (!strcmp(name, XATTR_NAME_CAPS)) { | |
438 | if (!capable(CAP_SETFCAP)) | |
439 | --- a/security/security.c | |
440 | +++ b/security/security.c | |
441 | @@ -473,12 +473,12 @@ void security_inode_delete(struct inode | |
442 | ||
443 | int security_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt, | |
444 | const char *name, const void *value, size_t size, | |
445 | - int flags) | |
446 | + int flags, struct file *file) | |
447 | { | |
448 | if (unlikely(IS_PRIVATE(dentry->d_inode))) | |
449 | return 0; | |
450 | return security_ops->inode_setxattr(dentry, mnt, name, value, size, | |
451 | - flags); | |
452 | + flags, file); | |
453 | } | |
454 | ||
455 | void security_inode_post_setxattr(struct dentry *dentry, struct vfsmount *mnt, | |
456 | @@ -492,26 +492,27 @@ void security_inode_post_setxattr(struct | |
457 | } | |
458 | ||
459 | int security_inode_getxattr(struct dentry *dentry, struct vfsmount *mnt, | |
460 | - const char *name) | |
461 | + const char *name, struct file *file) | |
462 | { | |
463 | if (unlikely(IS_PRIVATE(dentry->d_inode))) | |
464 | return 0; | |
465 | - return security_ops->inode_getxattr(dentry, mnt, name); | |
466 | + return security_ops->inode_getxattr(dentry, mnt, name, file); | |
467 | } | |
468 | ||
469 | -int security_inode_listxattr(struct dentry *dentry, struct vfsmount *mnt) | |
470 | +int security_inode_listxattr(struct dentry *dentry, struct vfsmount *mnt, | |
471 | + struct file *file) | |
472 | { | |
473 | if (unlikely(IS_PRIVATE(dentry->d_inode))) | |
474 | return 0; | |
475 | - return security_ops->inode_listxattr(dentry, mnt); | |
476 | + return security_ops->inode_listxattr(dentry, mnt, file); | |
477 | } | |
478 | ||
479 | int security_inode_removexattr(struct dentry *dentry, struct vfsmount *mnt, | |
480 | - const char *name) | |
481 | + const char *name, struct file *file) | |
482 | { | |
483 | if (unlikely(IS_PRIVATE(dentry->d_inode))) | |
484 | return 0; | |
485 | - return security_ops->inode_removexattr(dentry, mnt, name); | |
486 | + return security_ops->inode_removexattr(dentry, mnt, name, file); | |
487 | } | |
488 | ||
489 | int security_inode_need_killpriv(struct dentry *dentry) | |
490 | --- a/security/selinux/hooks.c | |
491 | +++ b/security/selinux/hooks.c | |
492 | @@ -2715,7 +2715,7 @@ static int selinux_inode_setotherxattr(s | |
493 | ||
494 | static int selinux_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt, | |
495 | const char *name, const void *value, | |
496 | - size_t size, int flags) | |
497 | + size_t size, int flags, struct file *file) | |
498 | { | |
499 | struct task_security_struct *tsec = current->security; | |
500 | struct inode *inode = dentry->d_inode; | |
501 | @@ -2797,18 +2797,20 @@ static void selinux_inode_post_setxattr( | |
502 | } | |
503 | ||
504 | static int selinux_inode_getxattr(struct dentry *dentry, struct vfsmount *mnt, | |
505 | - const char *name) | |
506 | + const char *name, struct file *file) | |
507 | { | |
508 | return dentry_has_perm(current, NULL, dentry, FILE__GETATTR); | |
509 | } | |
510 | ||
511 | -static int selinux_inode_listxattr(struct dentry *dentry, struct vfsmount *mnt) | |
512 | +static int selinux_inode_listxattr(struct dentry *dentry, struct vfsmount *mnt, | |
513 | + struct file *file) | |
514 | { | |
515 | return dentry_has_perm(current, NULL, dentry, FILE__GETATTR); | |
516 | } | |
517 | ||
518 | static int selinux_inode_removexattr(struct dentry *dentry, | |
519 | - struct vfsmount *mnt, const char *name) | |
520 | + struct vfsmount *mnt, const char *name, | |
521 | + struct file *file) | |
522 | { | |
523 | if (strcmp(name, XATTR_NAME_SELINUX)) | |
524 | return selinux_inode_setotherxattr(dentry, name); | |
525 | --- a/security/smack/smack_lsm.c | |
526 | +++ b/security/smack/smack_lsm.c | |
527 | @@ -600,6 +600,7 @@ static int smack_inode_getattr(struct vf | |
528 | * @value: unused | |
529 | * @size: unused | |
530 | * @flags: unused | |
531 | + * @file: unused | |
532 | * | |
533 | * This protects the Smack attribute explicitly. | |
534 | * | |
535 | @@ -607,7 +608,7 @@ static int smack_inode_getattr(struct vf | |
536 | */ | |
537 | static int smack_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt, | |
538 | const char *name, const void *value, | |
539 | - size_t size, int flags) | |
540 | + size_t size, int flags, struct file *file) | |
541 | { | |
542 | int rc = 0; | |
543 | ||
544 | @@ -619,7 +620,8 @@ static int smack_inode_setxattr(struct d | |
545 | if (size == 0) | |
546 | rc = -EINVAL; | |
547 | } else | |
548 | - rc = cap_inode_setxattr(dentry, mnt, name, value, size, flags); | |
549 | + rc = cap_inode_setxattr(dentry, mnt, name, value, size, flags, | |
550 | + file); | |
551 | ||
552 | if (rc == 0) | |
553 | rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE); | |
554 | @@ -675,11 +677,12 @@ static void smack_inode_post_setxattr(st | |
555 | * @dentry: the object | |
556 | * @mnt: unused | |
557 | * @name: unused | |
558 | + * @file: unused | |
559 | * | |
560 | * Returns 0 if access is permitted, an error code otherwise | |
561 | */ | |
562 | static int smack_inode_getxattr(struct dentry *dentry, struct vfsmount *mnt, | |
563 | - const char *name) | |
564 | + const char *name, struct file *file) | |
565 | { | |
566 | return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ); | |
567 | } | |
568 | @@ -689,13 +692,14 @@ static int smack_inode_getxattr(struct d | |
569 | * @dentry: the object | |
570 | * @mnt: unused | |
571 | * @name: name of the attribute | |
572 | + * @file: unused | |
573 | * | |
574 | * Removing the Smack attribute requires CAP_MAC_ADMIN | |
575 | * | |
576 | * Returns 0 if access is permitted, an error code otherwise | |
577 | */ | |
578 | static int smack_inode_removexattr(struct dentry *dentry, struct vfsmount *mnt, | |
579 | - const char *name) | |
580 | + const char *name, struct file *file) | |
581 | { | |
582 | int rc = 0; | |
583 | ||
584 | @@ -705,7 +709,7 @@ static int smack_inode_removexattr(struc | |
585 | if (!capable(CAP_MAC_ADMIN)) | |
586 | rc = -EPERM; | |
587 | } else | |
588 | - rc = cap_inode_removexattr(dentry, mnt, name); | |
589 | + rc = cap_inode_removexattr(dentry, mnt, name, file); | |
590 | ||
591 | if (rc == 0) | |
592 | rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE); |