diff options
Diffstat (limited to 'fs/xattr.c')
-rw-r--r-- | fs/xattr.c | 39 |
1 files changed, 31 insertions, 8 deletions
diff --git a/fs/xattr.c b/fs/xattr.c index 3acab1615460..89a942f07e1b 100644 --- a/fs/xattr.c +++ b/fs/xattr.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/slab.h> | 11 | #include <linux/slab.h> |
12 | #include <linux/file.h> | 12 | #include <linux/file.h> |
13 | #include <linux/xattr.h> | 13 | #include <linux/xattr.h> |
14 | #include <linux/mount.h> | ||
14 | #include <linux/namei.h> | 15 | #include <linux/namei.h> |
15 | #include <linux/security.h> | 16 | #include <linux/security.h> |
16 | #include <linux/syscalls.h> | 17 | #include <linux/syscalls.h> |
@@ -32,8 +33,6 @@ xattr_permission(struct inode *inode, const char *name, int mask) | |||
32 | * filesystem or on an immutable / append-only inode. | 33 | * filesystem or on an immutable / append-only inode. |
33 | */ | 34 | */ |
34 | if (mask & MAY_WRITE) { | 35 | if (mask & MAY_WRITE) { |
35 | if (IS_RDONLY(inode)) | ||
36 | return -EROFS; | ||
37 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) | 36 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) |
38 | return -EPERM; | 37 | return -EPERM; |
39 | } | 38 | } |
@@ -262,7 +261,11 @@ sys_setxattr(char __user *path, char __user *name, void __user *value, | |||
262 | error = user_path_walk(path, &nd); | 261 | error = user_path_walk(path, &nd); |
263 | if (error) | 262 | if (error) |
264 | return error; | 263 | return error; |
265 | error = setxattr(nd.path.dentry, name, value, size, flags); | 264 | error = mnt_want_write(nd.path.mnt); |
265 | if (!error) { | ||
266 | error = setxattr(nd.path.dentry, name, value, size, flags); | ||
267 | mnt_drop_write(nd.path.mnt); | ||
268 | } | ||
266 | path_put(&nd.path); | 269 | path_put(&nd.path); |
267 | return error; | 270 | return error; |
268 | } | 271 | } |
@@ -277,7 +280,11 @@ sys_lsetxattr(char __user *path, char __user *name, void __user *value, | |||
277 | error = user_path_walk_link(path, &nd); | 280 | error = user_path_walk_link(path, &nd); |
278 | if (error) | 281 | if (error) |
279 | return error; | 282 | return error; |
280 | error = setxattr(nd.path.dentry, name, value, size, flags); | 283 | error = mnt_want_write(nd.path.mnt); |
284 | if (!error) { | ||
285 | error = setxattr(nd.path.dentry, name, value, size, flags); | ||
286 | mnt_drop_write(nd.path.mnt); | ||
287 | } | ||
281 | path_put(&nd.path); | 288 | path_put(&nd.path); |
282 | return error; | 289 | return error; |
283 | } | 290 | } |
@@ -295,7 +302,11 @@ sys_fsetxattr(int fd, char __user *name, void __user *value, | |||
295 | return error; | 302 | return error; |
296 | dentry = f->f_path.dentry; | 303 | dentry = f->f_path.dentry; |
297 | audit_inode(NULL, dentry); | 304 | audit_inode(NULL, dentry); |
298 | error = setxattr(dentry, name, value, size, flags); | 305 | error = mnt_want_write(f->f_path.mnt); |
306 | if (!error) { | ||
307 | error = setxattr(dentry, name, value, size, flags); | ||
308 | mnt_drop_write(f->f_path.mnt); | ||
309 | } | ||
299 | fput(f); | 310 | fput(f); |
300 | return error; | 311 | return error; |
301 | } | 312 | } |
@@ -482,7 +493,11 @@ sys_removexattr(char __user *path, char __user *name) | |||
482 | error = user_path_walk(path, &nd); | 493 | error = user_path_walk(path, &nd); |
483 | if (error) | 494 | if (error) |
484 | return error; | 495 | return error; |
485 | error = removexattr(nd.path.dentry, name); | 496 | error = mnt_want_write(nd.path.mnt); |
497 | if (!error) { | ||
498 | error = removexattr(nd.path.dentry, name); | ||
499 | mnt_drop_write(nd.path.mnt); | ||
500 | } | ||
486 | path_put(&nd.path); | 501 | path_put(&nd.path); |
487 | return error; | 502 | return error; |
488 | } | 503 | } |
@@ -496,7 +511,11 @@ sys_lremovexattr(char __user *path, char __user *name) | |||
496 | error = user_path_walk_link(path, &nd); | 511 | error = user_path_walk_link(path, &nd); |
497 | if (error) | 512 | if (error) |
498 | return error; | 513 | return error; |
499 | error = removexattr(nd.path.dentry, name); | 514 | error = mnt_want_write(nd.path.mnt); |
515 | if (!error) { | ||
516 | error = removexattr(nd.path.dentry, name); | ||
517 | mnt_drop_write(nd.path.mnt); | ||
518 | } | ||
500 | path_put(&nd.path); | 519 | path_put(&nd.path); |
501 | return error; | 520 | return error; |
502 | } | 521 | } |
@@ -513,7 +532,11 @@ sys_fremovexattr(int fd, char __user *name) | |||
513 | return error; | 532 | return error; |
514 | dentry = f->f_path.dentry; | 533 | dentry = f->f_path.dentry; |
515 | audit_inode(NULL, dentry); | 534 | audit_inode(NULL, dentry); |
516 | error = removexattr(dentry, name); | 535 | error = mnt_want_write(f->f_path.mnt); |
536 | if (!error) { | ||
537 | error = removexattr(dentry, name); | ||
538 | mnt_drop_write(f->f_path.mnt); | ||
539 | } | ||
517 | fput(f); | 540 | fput(f); |
518 | return error; | 541 | return error; |
519 | } | 542 | } |