diff options
Diffstat (limited to 'fs/compat.c')
-rw-r--r-- | fs/compat.c | 92 |
1 files changed, 31 insertions, 61 deletions
diff --git a/fs/compat.c b/fs/compat.c index 5216c3fd7517..2ce4456aad30 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
@@ -241,10 +241,10 @@ asmlinkage long compat_sys_statfs(const char __user *path, struct compat_statfs | |||
241 | error = user_path_walk(path, &nd); | 241 | error = user_path_walk(path, &nd); |
242 | if (!error) { | 242 | if (!error) { |
243 | struct kstatfs tmp; | 243 | struct kstatfs tmp; |
244 | error = vfs_statfs(nd.dentry, &tmp); | 244 | error = vfs_statfs(nd.path.dentry, &tmp); |
245 | if (!error) | 245 | if (!error) |
246 | error = put_compat_statfs(buf, &tmp); | 246 | error = put_compat_statfs(buf, &tmp); |
247 | path_release(&nd); | 247 | path_put(&nd.path); |
248 | } | 248 | } |
249 | return error; | 249 | return error; |
250 | } | 250 | } |
@@ -309,10 +309,10 @@ asmlinkage long compat_sys_statfs64(const char __user *path, compat_size_t sz, s | |||
309 | error = user_path_walk(path, &nd); | 309 | error = user_path_walk(path, &nd); |
310 | if (!error) { | 310 | if (!error) { |
311 | struct kstatfs tmp; | 311 | struct kstatfs tmp; |
312 | error = vfs_statfs(nd.dentry, &tmp); | 312 | error = vfs_statfs(nd.path.dentry, &tmp); |
313 | if (!error) | 313 | if (!error) |
314 | error = put_compat_statfs64(buf, &tmp); | 314 | error = put_compat_statfs64(buf, &tmp); |
315 | path_release(&nd); | 315 | path_put(&nd.path); |
316 | } | 316 | } |
317 | return error; | 317 | return error; |
318 | } | 318 | } |
@@ -702,9 +702,6 @@ static int do_nfs4_super_data_conv(void *raw_data) | |||
702 | real->flags = raw->flags; | 702 | real->flags = raw->flags; |
703 | real->version = raw->version; | 703 | real->version = raw->version; |
704 | } | 704 | } |
705 | else { | ||
706 | return -EINVAL; | ||
707 | } | ||
708 | 705 | ||
709 | return 0; | 706 | return 0; |
710 | } | 707 | } |
@@ -2083,51 +2080,6 @@ long asmlinkage compat_sys_nfsservctl(int cmd, void *notused, void *notused2) | |||
2083 | 2080 | ||
2084 | #ifdef CONFIG_EPOLL | 2081 | #ifdef CONFIG_EPOLL |
2085 | 2082 | ||
2086 | #ifdef CONFIG_HAS_COMPAT_EPOLL_EVENT | ||
2087 | asmlinkage long compat_sys_epoll_ctl(int epfd, int op, int fd, | ||
2088 | struct compat_epoll_event __user *event) | ||
2089 | { | ||
2090 | long err = 0; | ||
2091 | struct compat_epoll_event user; | ||
2092 | struct epoll_event __user *kernel = NULL; | ||
2093 | |||
2094 | if (event) { | ||
2095 | if (copy_from_user(&user, event, sizeof(user))) | ||
2096 | return -EFAULT; | ||
2097 | kernel = compat_alloc_user_space(sizeof(struct epoll_event)); | ||
2098 | err |= __put_user(user.events, &kernel->events); | ||
2099 | err |= __put_user(user.data, &kernel->data); | ||
2100 | } | ||
2101 | |||
2102 | return err ? err : sys_epoll_ctl(epfd, op, fd, kernel); | ||
2103 | } | ||
2104 | |||
2105 | |||
2106 | asmlinkage long compat_sys_epoll_wait(int epfd, | ||
2107 | struct compat_epoll_event __user *events, | ||
2108 | int maxevents, int timeout) | ||
2109 | { | ||
2110 | long i, ret, err = 0; | ||
2111 | struct epoll_event __user *kbuf; | ||
2112 | struct epoll_event ev; | ||
2113 | |||
2114 | if ((maxevents <= 0) || | ||
2115 | (maxevents > (INT_MAX / sizeof(struct epoll_event)))) | ||
2116 | return -EINVAL; | ||
2117 | kbuf = compat_alloc_user_space(sizeof(struct epoll_event) * maxevents); | ||
2118 | ret = sys_epoll_wait(epfd, kbuf, maxevents, timeout); | ||
2119 | for (i = 0; i < ret; i++) { | ||
2120 | err |= __get_user(ev.events, &kbuf[i].events); | ||
2121 | err |= __get_user(ev.data, &kbuf[i].data); | ||
2122 | err |= __put_user(ev.events, &events->events); | ||
2123 | err |= __put_user_unaligned(ev.data, &events->data); | ||
2124 | events++; | ||
2125 | } | ||
2126 | |||
2127 | return err ? -EFAULT: ret; | ||
2128 | } | ||
2129 | #endif /* CONFIG_HAS_COMPAT_EPOLL_EVENT */ | ||
2130 | |||
2131 | #ifdef TIF_RESTORE_SIGMASK | 2083 | #ifdef TIF_RESTORE_SIGMASK |
2132 | asmlinkage long compat_sys_epoll_pwait(int epfd, | 2084 | asmlinkage long compat_sys_epoll_pwait(int epfd, |
2133 | struct compat_epoll_event __user *events, | 2085 | struct compat_epoll_event __user *events, |
@@ -2153,11 +2105,7 @@ asmlinkage long compat_sys_epoll_pwait(int epfd, | |||
2153 | sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved); | 2105 | sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved); |
2154 | } | 2106 | } |
2155 | 2107 | ||
2156 | #ifdef CONFIG_HAS_COMPAT_EPOLL_EVENT | ||
2157 | err = compat_sys_epoll_wait(epfd, events, maxevents, timeout); | ||
2158 | #else | ||
2159 | err = sys_epoll_wait(epfd, events, maxevents, timeout); | 2108 | err = sys_epoll_wait(epfd, events, maxevents, timeout); |
2160 | #endif | ||
2161 | 2109 | ||
2162 | /* | 2110 | /* |
2163 | * If we changed the signal mask, we need to restore the original one. | 2111 | * If we changed the signal mask, we need to restore the original one. |
@@ -2206,19 +2154,41 @@ asmlinkage long compat_sys_signalfd(int ufd, | |||
2206 | 2154 | ||
2207 | #ifdef CONFIG_TIMERFD | 2155 | #ifdef CONFIG_TIMERFD |
2208 | 2156 | ||
2209 | asmlinkage long compat_sys_timerfd(int ufd, int clockid, int flags, | 2157 | asmlinkage long compat_sys_timerfd_settime(int ufd, int flags, |
2210 | const struct compat_itimerspec __user *utmr) | 2158 | const struct compat_itimerspec __user *utmr, |
2159 | struct compat_itimerspec __user *otmr) | ||
2211 | { | 2160 | { |
2161 | int error; | ||
2212 | struct itimerspec t; | 2162 | struct itimerspec t; |
2213 | struct itimerspec __user *ut; | 2163 | struct itimerspec __user *ut; |
2214 | 2164 | ||
2215 | if (get_compat_itimerspec(&t, utmr)) | 2165 | if (get_compat_itimerspec(&t, utmr)) |
2216 | return -EFAULT; | 2166 | return -EFAULT; |
2217 | ut = compat_alloc_user_space(sizeof(*ut)); | 2167 | ut = compat_alloc_user_space(2 * sizeof(struct itimerspec)); |
2218 | if (copy_to_user(ut, &t, sizeof(t))) | 2168 | if (copy_to_user(&ut[0], &t, sizeof(t))) |
2219 | return -EFAULT; | 2169 | return -EFAULT; |
2170 | error = sys_timerfd_settime(ufd, flags, &ut[0], &ut[1]); | ||
2171 | if (!error && otmr) | ||
2172 | error = (copy_from_user(&t, &ut[1], sizeof(struct itimerspec)) || | ||
2173 | put_compat_itimerspec(otmr, &t)) ? -EFAULT: 0; | ||
2220 | 2174 | ||
2221 | return sys_timerfd(ufd, clockid, flags, ut); | 2175 | return error; |
2176 | } | ||
2177 | |||
2178 | asmlinkage long compat_sys_timerfd_gettime(int ufd, | ||
2179 | struct compat_itimerspec __user *otmr) | ||
2180 | { | ||
2181 | int error; | ||
2182 | struct itimerspec t; | ||
2183 | struct itimerspec __user *ut; | ||
2184 | |||
2185 | ut = compat_alloc_user_space(sizeof(struct itimerspec)); | ||
2186 | error = sys_timerfd_gettime(ufd, ut); | ||
2187 | if (!error) | ||
2188 | error = (copy_from_user(&t, ut, sizeof(struct itimerspec)) || | ||
2189 | put_compat_itimerspec(otmr, &t)) ? -EFAULT: 0; | ||
2190 | |||
2191 | return error; | ||
2222 | } | 2192 | } |
2223 | 2193 | ||
2224 | #endif /* CONFIG_TIMERFD */ | 2194 | #endif /* CONFIG_TIMERFD */ |