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