diff options
Diffstat (limited to 'fs/open.c')
-rw-r--r-- | fs/open.c | 64 |
1 files changed, 37 insertions, 27 deletions
@@ -386,15 +386,21 @@ asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode) | |||
386 | current->cap_effective = current->cap_permitted; | 386 | current->cap_effective = current->cap_permitted; |
387 | 387 | ||
388 | res = __user_walk_fd(dfd, filename, LOOKUP_FOLLOW|LOOKUP_ACCESS, &nd); | 388 | res = __user_walk_fd(dfd, filename, LOOKUP_FOLLOW|LOOKUP_ACCESS, &nd); |
389 | if (!res) { | 389 | if (res) |
390 | res = vfs_permission(&nd, mode); | 390 | goto out; |
391 | /* SuS v2 requires we report a read only fs too */ | 391 | |
392 | if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode) | 392 | res = vfs_permission(&nd, mode); |
393 | && !special_file(nd.dentry->d_inode->i_mode)) | 393 | /* SuS v2 requires we report a read only fs too */ |
394 | res = -EROFS; | 394 | if(res || !(mode & S_IWOTH) || |
395 | path_release(&nd); | 395 | special_file(nd.dentry->d_inode->i_mode)) |
396 | } | 396 | goto out_path_release; |
397 | |||
398 | if(IS_RDONLY(nd.dentry->d_inode)) | ||
399 | res = -EROFS; | ||
397 | 400 | ||
401 | out_path_release: | ||
402 | path_release(&nd); | ||
403 | out: | ||
398 | current->fsuid = old_fsuid; | 404 | current->fsuid = old_fsuid; |
399 | current->fsgid = old_fsgid; | 405 | current->fsgid = old_fsgid; |
400 | current->cap_effective = old_cap; | 406 | current->cap_effective = old_cap; |
@@ -603,10 +609,11 @@ asmlinkage long sys_chown(const char __user * filename, uid_t user, gid_t group) | |||
603 | int error; | 609 | int error; |
604 | 610 | ||
605 | error = user_path_walk(filename, &nd); | 611 | error = user_path_walk(filename, &nd); |
606 | if (!error) { | 612 | if (error) |
607 | error = chown_common(nd.dentry, user, group); | 613 | goto out; |
608 | path_release(&nd); | 614 | error = chown_common(nd.dentry, user, group); |
609 | } | 615 | path_release(&nd); |
616 | out: | ||
610 | return error; | 617 | return error; |
611 | } | 618 | } |
612 | 619 | ||
@@ -622,10 +629,10 @@ asmlinkage long sys_fchownat(int dfd, const char __user *filename, uid_t user, | |||
622 | 629 | ||
623 | follow = (flag & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW; | 630 | follow = (flag & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW; |
624 | error = __user_walk_fd(dfd, filename, follow, &nd); | 631 | error = __user_walk_fd(dfd, filename, follow, &nd); |
625 | if (!error) { | 632 | if (error) |
626 | error = chown_common(nd.dentry, user, group); | 633 | goto out; |
627 | path_release(&nd); | 634 | error = chown_common(nd.dentry, user, group); |
628 | } | 635 | path_release(&nd); |
629 | out: | 636 | out: |
630 | return error; | 637 | return error; |
631 | } | 638 | } |
@@ -636,10 +643,11 @@ asmlinkage long sys_lchown(const char __user * filename, uid_t user, gid_t group | |||
636 | int error; | 643 | int error; |
637 | 644 | ||
638 | error = user_path_walk_link(filename, &nd); | 645 | error = user_path_walk_link(filename, &nd); |
639 | if (!error) { | 646 | if (error) |
640 | error = chown_common(nd.dentry, user, group); | 647 | goto out; |
641 | path_release(&nd); | 648 | error = chown_common(nd.dentry, user, group); |
642 | } | 649 | path_release(&nd); |
650 | out: | ||
643 | return error; | 651 | return error; |
644 | } | 652 | } |
645 | 653 | ||
@@ -648,15 +656,17 @@ asmlinkage long sys_fchown(unsigned int fd, uid_t user, gid_t group) | |||
648 | { | 656 | { |
649 | struct file * file; | 657 | struct file * file; |
650 | int error = -EBADF; | 658 | int error = -EBADF; |
659 | struct dentry * dentry; | ||
651 | 660 | ||
652 | file = fget(fd); | 661 | file = fget(fd); |
653 | if (file) { | 662 | if (!file) |
654 | struct dentry * dentry; | 663 | goto out; |
655 | dentry = file->f_dentry; | 664 | |
656 | audit_inode(NULL, dentry->d_inode); | 665 | dentry = file->f_dentry; |
657 | error = chown_common(dentry, user, group); | 666 | audit_inode(NULL, dentry->d_inode); |
658 | fput(file); | 667 | error = chown_common(dentry, user, group); |
659 | } | 668 | fput(file); |
669 | out: | ||
660 | return error; | 670 | return error; |
661 | } | 671 | } |
662 | 672 | ||