diff options
Diffstat (limited to 'fs/xattr.c')
| -rw-r--r-- | fs/xattr.c | 40 |
1 files changed, 32 insertions, 8 deletions
diff --git a/fs/xattr.c b/fs/xattr.c index 3acab1615460..f7062da505d4 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,12 @@ 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 | } | ||
| 310 | out_fput: | ||
| 299 | fput(f); | 311 | fput(f); |
| 300 | return error; | 312 | return error; |
| 301 | } | 313 | } |
| @@ -482,7 +494,11 @@ sys_removexattr(char __user *path, char __user *name) | |||
| 482 | error = user_path_walk(path, &nd); | 494 | error = user_path_walk(path, &nd); |
| 483 | if (error) | 495 | if (error) |
| 484 | return error; | 496 | return error; |
| 485 | error = removexattr(nd.path.dentry, name); | 497 | error = mnt_want_write(nd.path.mnt); |
| 498 | if (!error) { | ||
| 499 | error = removexattr(nd.path.dentry, name); | ||
| 500 | mnt_drop_write(nd.path.mnt); | ||
| 501 | } | ||
| 486 | path_put(&nd.path); | 502 | path_put(&nd.path); |
| 487 | return error; | 503 | return error; |
| 488 | } | 504 | } |
| @@ -496,7 +512,11 @@ sys_lremovexattr(char __user *path, char __user *name) | |||
| 496 | error = user_path_walk_link(path, &nd); | 512 | error = user_path_walk_link(path, &nd); |
| 497 | if (error) | 513 | if (error) |
| 498 | return error; | 514 | return error; |
| 499 | error = removexattr(nd.path.dentry, name); | 515 | error = mnt_want_write(nd.path.mnt); |
| 516 | if (!error) { | ||
| 517 | error = removexattr(nd.path.dentry, name); | ||
| 518 | mnt_drop_write(nd.path.mnt); | ||
| 519 | } | ||
| 500 | path_put(&nd.path); | 520 | path_put(&nd.path); |
| 501 | return error; | 521 | return error; |
| 502 | } | 522 | } |
| @@ -513,7 +533,11 @@ sys_fremovexattr(int fd, char __user *name) | |||
| 513 | return error; | 533 | return error; |
| 514 | dentry = f->f_path.dentry; | 534 | dentry = f->f_path.dentry; |
| 515 | audit_inode(NULL, dentry); | 535 | audit_inode(NULL, dentry); |
| 516 | error = removexattr(dentry, name); | 536 | error = mnt_want_write(f->f_path.mnt); |
| 537 | if (!error) { | ||
| 538 | error = removexattr(dentry, name); | ||
| 539 | mnt_drop_write(f->f_path.mnt); | ||
| 540 | } | ||
| 517 | fput(f); | 541 | fput(f); |
| 518 | return error; | 542 | return error; |
| 519 | } | 543 | } |
