aboutsummaryrefslogtreecommitdiffstats
path: root/fs/compat.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/compat.c')
-rw-r--r--fs/compat.c92
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
2087asmlinkage 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
2106asmlinkage 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
2132asmlinkage long compat_sys_epoll_pwait(int epfd, 2084asmlinkage 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
2209asmlinkage long compat_sys_timerfd(int ufd, int clockid, int flags, 2157asmlinkage 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
2178asmlinkage 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 */