diff options
Diffstat (limited to 'fs/compat.c')
-rw-r--r-- | fs/compat.c | 47 |
1 files changed, 19 insertions, 28 deletions
diff --git a/fs/compat.c b/fs/compat.c index f2944ace7a7b..6161255fac45 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
@@ -144,8 +144,8 @@ static int cp_compat_stat(struct kstat *stat, struct compat_stat __user *ubuf) | |||
144 | tmp.st_nlink = stat->nlink; | 144 | tmp.st_nlink = stat->nlink; |
145 | if (tmp.st_nlink != stat->nlink) | 145 | if (tmp.st_nlink != stat->nlink) |
146 | return -EOVERFLOW; | 146 | return -EOVERFLOW; |
147 | SET_UID(tmp.st_uid, stat->uid); | 147 | SET_UID(tmp.st_uid, from_kuid_munged(current_user_ns(), stat->uid)); |
148 | SET_GID(tmp.st_gid, stat->gid); | 148 | SET_GID(tmp.st_gid, from_kgid_munged(current_user_ns(), stat->gid)); |
149 | tmp.st_rdev = old_encode_dev(stat->rdev); | 149 | tmp.st_rdev = old_encode_dev(stat->rdev); |
150 | if ((u64) stat->size > MAX_NON_LFS) | 150 | if ((u64) stat->size > MAX_NON_LFS) |
151 | return -EOVERFLOW; | 151 | return -EOVERFLOW; |
@@ -532,7 +532,7 @@ out: | |||
532 | ssize_t compat_rw_copy_check_uvector(int type, | 532 | ssize_t compat_rw_copy_check_uvector(int type, |
533 | const struct compat_iovec __user *uvector, unsigned long nr_segs, | 533 | const struct compat_iovec __user *uvector, unsigned long nr_segs, |
534 | unsigned long fast_segs, struct iovec *fast_pointer, | 534 | unsigned long fast_segs, struct iovec *fast_pointer, |
535 | struct iovec **ret_pointer, int check_access) | 535 | struct iovec **ret_pointer) |
536 | { | 536 | { |
537 | compat_ssize_t tot_len; | 537 | compat_ssize_t tot_len; |
538 | struct iovec *iov = *ret_pointer = fast_pointer; | 538 | struct iovec *iov = *ret_pointer = fast_pointer; |
@@ -579,7 +579,7 @@ ssize_t compat_rw_copy_check_uvector(int type, | |||
579 | } | 579 | } |
580 | if (len < 0) /* size_t not fitting in compat_ssize_t .. */ | 580 | if (len < 0) /* size_t not fitting in compat_ssize_t .. */ |
581 | goto out; | 581 | goto out; |
582 | if (check_access && | 582 | if (type >= 0 && |
583 | !access_ok(vrfy_dir(type), compat_ptr(buf), len)) { | 583 | !access_ok(vrfy_dir(type), compat_ptr(buf), len)) { |
584 | ret = -EFAULT; | 584 | ret = -EFAULT; |
585 | goto out; | 585 | goto out; |
@@ -871,12 +871,12 @@ asmlinkage long compat_sys_old_readdir(unsigned int fd, | |||
871 | { | 871 | { |
872 | int error; | 872 | int error; |
873 | struct file *file; | 873 | struct file *file; |
874 | int fput_needed; | ||
874 | struct compat_readdir_callback buf; | 875 | struct compat_readdir_callback buf; |
875 | 876 | ||
876 | error = -EBADF; | 877 | file = fget_light(fd, &fput_needed); |
877 | file = fget(fd); | ||
878 | if (!file) | 878 | if (!file) |
879 | goto out; | 879 | return -EBADF; |
880 | 880 | ||
881 | buf.result = 0; | 881 | buf.result = 0; |
882 | buf.dirent = dirent; | 882 | buf.dirent = dirent; |
@@ -885,8 +885,7 @@ asmlinkage long compat_sys_old_readdir(unsigned int fd, | |||
885 | if (buf.result) | 885 | if (buf.result) |
886 | error = buf.result; | 886 | error = buf.result; |
887 | 887 | ||
888 | fput(file); | 888 | fput_light(file, fput_needed); |
889 | out: | ||
890 | return error; | 889 | return error; |
891 | } | 890 | } |
892 | 891 | ||
@@ -953,16 +952,15 @@ asmlinkage long compat_sys_getdents(unsigned int fd, | |||
953 | struct file * file; | 952 | struct file * file; |
954 | struct compat_linux_dirent __user * lastdirent; | 953 | struct compat_linux_dirent __user * lastdirent; |
955 | struct compat_getdents_callback buf; | 954 | struct compat_getdents_callback buf; |
955 | int fput_needed; | ||
956 | int error; | 956 | int error; |
957 | 957 | ||
958 | error = -EFAULT; | ||
959 | if (!access_ok(VERIFY_WRITE, dirent, count)) | 958 | if (!access_ok(VERIFY_WRITE, dirent, count)) |
960 | goto out; | 959 | return -EFAULT; |
961 | 960 | ||
962 | error = -EBADF; | 961 | file = fget_light(fd, &fput_needed); |
963 | file = fget(fd); | ||
964 | if (!file) | 962 | if (!file) |
965 | goto out; | 963 | return -EBADF; |
966 | 964 | ||
967 | buf.current_dir = dirent; | 965 | buf.current_dir = dirent; |
968 | buf.previous = NULL; | 966 | buf.previous = NULL; |
@@ -979,8 +977,7 @@ asmlinkage long compat_sys_getdents(unsigned int fd, | |||
979 | else | 977 | else |
980 | error = count - buf.count; | 978 | error = count - buf.count; |
981 | } | 979 | } |
982 | fput(file); | 980 | fput_light(file, fput_needed); |
983 | out: | ||
984 | return error; | 981 | return error; |
985 | } | 982 | } |
986 | 983 | ||
@@ -1041,16 +1038,15 @@ asmlinkage long compat_sys_getdents64(unsigned int fd, | |||
1041 | struct file * file; | 1038 | struct file * file; |
1042 | struct linux_dirent64 __user * lastdirent; | 1039 | struct linux_dirent64 __user * lastdirent; |
1043 | struct compat_getdents_callback64 buf; | 1040 | struct compat_getdents_callback64 buf; |
1041 | int fput_needed; | ||
1044 | int error; | 1042 | int error; |
1045 | 1043 | ||
1046 | error = -EFAULT; | ||
1047 | if (!access_ok(VERIFY_WRITE, dirent, count)) | 1044 | if (!access_ok(VERIFY_WRITE, dirent, count)) |
1048 | goto out; | 1045 | return -EFAULT; |
1049 | 1046 | ||
1050 | error = -EBADF; | 1047 | file = fget_light(fd, &fput_needed); |
1051 | file = fget(fd); | ||
1052 | if (!file) | 1048 | if (!file) |
1053 | goto out; | 1049 | return -EBADF; |
1054 | 1050 | ||
1055 | buf.current_dir = dirent; | 1051 | buf.current_dir = dirent; |
1056 | buf.previous = NULL; | 1052 | buf.previous = NULL; |
@@ -1068,8 +1064,7 @@ asmlinkage long compat_sys_getdents64(unsigned int fd, | |||
1068 | else | 1064 | else |
1069 | error = count - buf.count; | 1065 | error = count - buf.count; |
1070 | } | 1066 | } |
1071 | fput(file); | 1067 | fput_light(file, fput_needed); |
1072 | out: | ||
1073 | return error; | 1068 | return error; |
1074 | } | 1069 | } |
1075 | #endif /* ! __ARCH_OMIT_COMPAT_SYS_GETDENTS64 */ | 1070 | #endif /* ! __ARCH_OMIT_COMPAT_SYS_GETDENTS64 */ |
@@ -1094,7 +1089,7 @@ static ssize_t compat_do_readv_writev(int type, struct file *file, | |||
1094 | goto out; | 1089 | goto out; |
1095 | 1090 | ||
1096 | tot_len = compat_rw_copy_check_uvector(type, uvector, nr_segs, | 1091 | tot_len = compat_rw_copy_check_uvector(type, uvector, nr_segs, |
1097 | UIO_FASTIOV, iovstack, &iov, 1); | 1092 | UIO_FASTIOV, iovstack, &iov); |
1098 | if (tot_len == 0) { | 1093 | if (tot_len == 0) { |
1099 | ret = 0; | 1094 | ret = 0; |
1100 | goto out; | 1095 | goto out; |
@@ -1547,7 +1542,6 @@ asmlinkage long compat_sys_old_select(struct compat_sel_arg_struct __user *arg) | |||
1547 | compat_ptr(a.exp), compat_ptr(a.tvp)); | 1542 | compat_ptr(a.exp), compat_ptr(a.tvp)); |
1548 | } | 1543 | } |
1549 | 1544 | ||
1550 | #ifdef HAVE_SET_RESTORE_SIGMASK | ||
1551 | static long do_compat_pselect(int n, compat_ulong_t __user *inp, | 1545 | static long do_compat_pselect(int n, compat_ulong_t __user *inp, |
1552 | compat_ulong_t __user *outp, compat_ulong_t __user *exp, | 1546 | compat_ulong_t __user *outp, compat_ulong_t __user *exp, |
1553 | struct compat_timespec __user *tsp, compat_sigset_t __user *sigmask, | 1547 | struct compat_timespec __user *tsp, compat_sigset_t __user *sigmask, |
@@ -1670,11 +1664,9 @@ asmlinkage long compat_sys_ppoll(struct pollfd __user *ufds, | |||
1670 | 1664 | ||
1671 | return ret; | 1665 | return ret; |
1672 | } | 1666 | } |
1673 | #endif /* HAVE_SET_RESTORE_SIGMASK */ | ||
1674 | 1667 | ||
1675 | #ifdef CONFIG_EPOLL | 1668 | #ifdef CONFIG_EPOLL |
1676 | 1669 | ||
1677 | #ifdef HAVE_SET_RESTORE_SIGMASK | ||
1678 | asmlinkage long compat_sys_epoll_pwait(int epfd, | 1670 | asmlinkage long compat_sys_epoll_pwait(int epfd, |
1679 | struct compat_epoll_event __user *events, | 1671 | struct compat_epoll_event __user *events, |
1680 | int maxevents, int timeout, | 1672 | int maxevents, int timeout, |
@@ -1718,7 +1710,6 @@ asmlinkage long compat_sys_epoll_pwait(int epfd, | |||
1718 | 1710 | ||
1719 | return err; | 1711 | return err; |
1720 | } | 1712 | } |
1721 | #endif /* HAVE_SET_RESTORE_SIGMASK */ | ||
1722 | 1713 | ||
1723 | #endif /* CONFIG_EPOLL */ | 1714 | #endif /* CONFIG_EPOLL */ |
1724 | 1715 | ||