1/*
2 *  linux/fs/compat.c
3 *
4 *  Kernel compatibililty routines for e.g. 32 bit syscall support
5 *  on 64 bit kernels.
6 *
7 *  Copyright (C) 2002       Stephen Rothwell, IBM Corporation
8 *  Copyright (C) 1997-2000  Jakub Jelinek  (jakub@redhat.com)
9 *  Copyright (C) 1998       Eddie C. Dost  (ecd@skynet.be)
10 *  Copyright (C) 2001,2002  Andi Kleen, SuSE Labs
11 *  Copyright (C) 2003       Pavel Machek (pavel@ucw.cz)
12 *
13 *  This program is free software; you can redistribute it and/or modify
14 *  it under the terms of the GNU General Public License version 2 as
15 *  published by the Free Software Foundation.
16 */
17
18#include <linux/stddef.h>
19#include <linux/kernel.h>
20#include <linux/linkage.h>
21#include <linux/compat.h>
22#include <linux/errno.h>
23#include <linux/time.h>
24#include <linux/fs.h>
25#include <linux/fcntl.h>
26#include <linux/namei.h>
27#include <linux/file.h>
28#include <linux/fdtable.h>
29#include <linux/vfs.h>
30#include <linux/ioctl.h>
31#include <linux/init.h>
32#include <linux/ncp_mount.h>
33#include <linux/nfs4_mount.h>
34#include <linux/syscalls.h>
35#include <linux/ctype.h>
36#include <linux/dirent.h>
37#include <linux/fsnotify.h>
38#include <linux/highuid.h>
39#include <linux/personality.h>
40#include <linux/rwsem.h>
41#include <linux/tsacct_kern.h>
42#include <linux/security.h>
43#include <linux/highmem.h>
44#include <linux/signal.h>
45#include <linux/poll.h>
46#include <linux/mm.h>
47#include <linux/fs_struct.h>
48#include <linux/slab.h>
49#include <linux/pagemap.h>
50#include <linux/aio.h>
51
52#include <asm/uaccess.h>
53#include <asm/mmu_context.h>
54#include <asm/ioctls.h>
55#include "internal.h"
56
57int compat_log = 1;
58
59int compat_printk(const char *fmt, ...)
60{
61	va_list ap;
62	int ret;
63	if (!compat_log)
64		return 0;
65	va_start(ap, fmt);
66	ret = vprintk(fmt, ap);
67	va_end(ap);
68	return ret;
69}
70
71/*
72 * Not all architectures have sys_utime, so implement this in terms
73 * of sys_utimes.
74 */
75COMPAT_SYSCALL_DEFINE2(utime, const char __user *, filename,
76		       struct compat_utimbuf __user *, t)
77{
78	struct timespec tv[2];
79
80	if (t) {
81		if (get_user(tv[0].tv_sec, &t->actime) ||
82		    get_user(tv[1].tv_sec, &t->modtime))
83			return -EFAULT;
84		tv[0].tv_nsec = 0;
85		tv[1].tv_nsec = 0;
86	}
87	return do_utimes(AT_FDCWD, filename, t ? tv : NULL, 0);
88}
89
90COMPAT_SYSCALL_DEFINE4(utimensat, unsigned int, dfd, const char __user *, filename, struct compat_timespec __user *, t, int, flags)
91{
92	struct timespec tv[2];
93
94	if  (t) {
95		if (compat_get_timespec(&tv[0], &t[0]) ||
96		    compat_get_timespec(&tv[1], &t[1]))
97			return -EFAULT;
98
99		if (tv[0].tv_nsec == UTIME_OMIT && tv[1].tv_nsec == UTIME_OMIT)
100			return 0;
101	}
102	return do_utimes(dfd, filename, t ? tv : NULL, flags);
103}
104
105COMPAT_SYSCALL_DEFINE3(futimesat, unsigned int, dfd, const char __user *, filename, struct compat_timeval __user *, t)
106{
107	struct timespec tv[2];
108
109	if (t) {
110		if (get_user(tv[0].tv_sec, &t[0].tv_sec) ||
111		    get_user(tv[0].tv_nsec, &t[0].tv_usec) ||
112		    get_user(tv[1].tv_sec, &t[1].tv_sec) ||
113		    get_user(tv[1].tv_nsec, &t[1].tv_usec))
114			return -EFAULT;
115		if (tv[0].tv_nsec >= 1000000 || tv[0].tv_nsec < 0 ||
116		    tv[1].tv_nsec >= 1000000 || tv[1].tv_nsec < 0)
117			return -EINVAL;
118		tv[0].tv_nsec *= 1000;
119		tv[1].tv_nsec *= 1000;
120	}
121	return do_utimes(dfd, filename, t ? tv : NULL, 0);
122}
123
124COMPAT_SYSCALL_DEFINE2(utimes, const char __user *, filename, struct compat_timeval __user *, t)
125{
126	return compat_sys_futimesat(AT_FDCWD, filename, t);
127}
128
129static int cp_compat_stat(struct kstat *stat, struct compat_stat __user *ubuf)
130{
131	struct compat_stat tmp;
132
133	if (!old_valid_dev(stat->dev) || !old_valid_dev(stat->rdev))
134		return -EOVERFLOW;
135
136	memset(&tmp, 0, sizeof(tmp));
137	tmp.st_dev = old_encode_dev(stat->dev);
138	tmp.st_ino = stat->ino;
139	if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino)
140		return -EOVERFLOW;
141	tmp.st_mode = stat->mode;
142	tmp.st_nlink = stat->nlink;
143	if (tmp.st_nlink != stat->nlink)
144		return -EOVERFLOW;
145	SET_UID(tmp.st_uid, from_kuid_munged(current_user_ns(), stat->uid));
146	SET_GID(tmp.st_gid, from_kgid_munged(current_user_ns(), stat->gid));
147	tmp.st_rdev = old_encode_dev(stat->rdev);
148	if ((u64) stat->size > MAX_NON_LFS)
149		return -EOVERFLOW;
150	tmp.st_size = stat->size;
151	tmp.st_atime = stat->atime.tv_sec;
152	tmp.st_atime_nsec = stat->atime.tv_nsec;
153	tmp.st_mtime = stat->mtime.tv_sec;
154	tmp.st_mtime_nsec = stat->mtime.tv_nsec;
155	tmp.st_ctime = stat->ctime.tv_sec;
156	tmp.st_ctime_nsec = stat->ctime.tv_nsec;
157	tmp.st_blocks = stat->blocks;
158	tmp.st_blksize = stat->blksize;
159	return copy_to_user(ubuf, &tmp, sizeof(tmp)) ? -EFAULT : 0;
160}
161
162COMPAT_SYSCALL_DEFINE2(newstat, const char __user *, filename,
163		       struct compat_stat __user *, statbuf)
164{
165	struct kstat stat;
166	int error;
167
168	error = vfs_stat(filename, &stat);
169	if (error)
170		return error;
171	return cp_compat_stat(&stat, statbuf);
172}
173
174COMPAT_SYSCALL_DEFINE2(newlstat, const char __user *, filename,
175		       struct compat_stat __user *, statbuf)
176{
177	struct kstat stat;
178	int error;
179
180	error = vfs_lstat(filename, &stat);
181	if (error)
182		return error;
183	return cp_compat_stat(&stat, statbuf);
184}
185
186#ifndef __ARCH_WANT_STAT64
187COMPAT_SYSCALL_DEFINE4(newfstatat, unsigned int, dfd,
188		       const char __user *, filename,
189		       struct compat_stat __user *, statbuf, int, flag)
190{
191	struct kstat stat;
192	int error;
193
194	error = vfs_fstatat(dfd, filename, &stat, flag);
195	if (error)
196		return error;
197	return cp_compat_stat(&stat, statbuf);
198}
199#endif
200
201COMPAT_SYSCALL_DEFINE2(newfstat, unsigned int, fd,
202		       struct compat_stat __user *, statbuf)
203{
204	struct kstat stat;
205	int error = vfs_fstat(fd, &stat);
206
207	if (!error)
208		error = cp_compat_stat(&stat, statbuf);
209	return error;
210}
211
212static int put_compat_statfs(struct compat_statfs __user *ubuf, struct kstatfs *kbuf)
213{
214
215	if (sizeof ubuf->f_blocks == 4) {
216		if ((kbuf->f_blocks | kbuf->f_bfree | kbuf->f_bavail |
217		     kbuf->f_bsize | kbuf->f_frsize) & 0xffffffff00000000ULL)
218			return -EOVERFLOW;
219		/* f_files and f_ffree may be -1; it's okay
220		 * to stuff that into 32 bits */
221		if (kbuf->f_files != 0xffffffffffffffffULL
222		 && (kbuf->f_files & 0xffffffff00000000ULL))
223			return -EOVERFLOW;
224		if (kbuf->f_ffree != 0xffffffffffffffffULL
225		 && (kbuf->f_ffree & 0xffffffff00000000ULL))
226			return -EOVERFLOW;
227	}
228	if (!access_ok(VERIFY_WRITE, ubuf, sizeof(*ubuf)) ||
229	    __put_user(kbuf->f_type, &ubuf->f_type) ||
230	    __put_user(kbuf->f_bsize, &ubuf->f_bsize) ||
231	    __put_user(kbuf->f_blocks, &ubuf->f_blocks) ||
232	    __put_user(kbuf->f_bfree, &ubuf->f_bfree) ||
233	    __put_user(kbuf->f_bavail, &ubuf->f_bavail) ||
234	    __put_user(kbuf->f_files, &ubuf->f_files) ||
235	    __put_user(kbuf->f_ffree, &ubuf->f_ffree) ||
236	    __put_user(kbuf->f_namelen, &ubuf->f_namelen) ||
237	    __put_user(kbuf->f_fsid.val[0], &ubuf->f_fsid.val[0]) ||
238	    __put_user(kbuf->f_fsid.val[1], &ubuf->f_fsid.val[1]) ||
239	    __put_user(kbuf->f_frsize, &ubuf->f_frsize) ||
240	    __put_user(kbuf->f_flags, &ubuf->f_flags) ||
241	    __clear_user(ubuf->f_spare, sizeof(ubuf->f_spare)))
242		return -EFAULT;
243	return 0;
244}
245
246/*
247 * The following statfs calls are copies of code from fs/statfs.c and
248 * should be checked against those from time to time
249 */
250COMPAT_SYSCALL_DEFINE2(statfs, const char __user *, pathname, struct compat_statfs __user *, buf)
251{
252	struct kstatfs tmp;
253	int error = user_statfs(pathname, &tmp);
254	if (!error)
255		error = put_compat_statfs(buf, &tmp);
256	return error;
257}
258
259COMPAT_SYSCALL_DEFINE2(fstatfs, unsigned int, fd, struct compat_statfs __user *, buf)
260{
261	struct kstatfs tmp;
262	int error = fd_statfs(fd, &tmp);
263	if (!error)
264		error = put_compat_statfs(buf, &tmp);
265	return error;
266}
267
268static int put_compat_statfs64(struct compat_statfs64 __user *ubuf, struct kstatfs *kbuf)
269{
270	if (sizeof ubuf->f_blocks == 4) {
271		if ((kbuf->f_blocks | kbuf->f_bfree | kbuf->f_bavail |
272		     kbuf->f_bsize | kbuf->f_frsize) & 0xffffffff00000000ULL)
273			return -EOVERFLOW;
274		/* f_files and f_ffree may be -1; it's okay
275		 * to stuff that into 32 bits */
276		if (kbuf->f_files != 0xffffffffffffffffULL
277		 && (kbuf->f_files & 0xffffffff00000000ULL))
278			return -EOVERFLOW;
279		if (kbuf->f_ffree != 0xffffffffffffffffULL
280		 && (kbuf->f_ffree & 0xffffffff00000000ULL))
281			return -EOVERFLOW;
282	}
283	if (!access_ok(VERIFY_WRITE, ubuf, sizeof(*ubuf)) ||
284	    __put_user(kbuf->f_type, &ubuf->f_type) ||
285	    __put_user(kbuf->f_bsize, &ubuf->f_bsize) ||
286	    __put_user(kbuf->f_blocks, &ubuf->f_blocks) ||
287	    __put_user(kbuf->f_bfree, &ubuf->f_bfree) ||
288	    __put_user(kbuf->f_bavail, &ubuf->f_bavail) ||
289	    __put_user(kbuf->f_files, &ubuf->f_files) ||
290	    __put_user(kbuf->f_ffree, &ubuf->f_ffree) ||
291	    __put_user(kbuf->f_namelen, &ubuf->f_namelen) ||
292	    __put_user(kbuf->f_fsid.val[0], &ubuf->f_fsid.val[0]) ||
293	    __put_user(kbuf->f_fsid.val[1], &ubuf->f_fsid.val[1]) ||
294	    __put_user(kbuf->f_frsize, &ubuf->f_frsize) ||
295	    __put_user(kbuf->f_flags, &ubuf->f_flags) ||
296	    __clear_user(ubuf->f_spare, sizeof(ubuf->f_spare)))
297		return -EFAULT;
298	return 0;
299}
300
301COMPAT_SYSCALL_DEFINE3(statfs64, const char __user *, pathname, compat_size_t, sz, struct compat_statfs64 __user *, buf)
302{
303	struct kstatfs tmp;
304	int error;
305
306	if (sz != sizeof(*buf))
307		return -EINVAL;
308
309	error = user_statfs(pathname, &tmp);
310	if (!error)
311		error = put_compat_statfs64(buf, &tmp);
312	return error;
313}
314
315COMPAT_SYSCALL_DEFINE3(fstatfs64, unsigned int, fd, compat_size_t, sz, struct compat_statfs64 __user *, buf)
316{
317	struct kstatfs tmp;
318	int error;
319
320	if (sz != sizeof(*buf))
321		return -EINVAL;
322
323	error = fd_statfs(fd, &tmp);
324	if (!error)
325		error = put_compat_statfs64(buf, &tmp);
326	return error;
327}
328
329/*
330 * This is a copy of sys_ustat, just dealing with a structure layout.
331 * Given how simple this syscall is that apporach is more maintainable
332 * than the various conversion hacks.
333 */
334COMPAT_SYSCALL_DEFINE2(ustat, unsigned, dev, struct compat_ustat __user *, u)
335{
336	struct compat_ustat tmp;
337	struct kstatfs sbuf;
338	int err = vfs_ustat(new_decode_dev(dev), &sbuf);
339	if (err)
340		return err;
341
342	memset(&tmp, 0, sizeof(struct compat_ustat));
343	tmp.f_tfree = sbuf.f_bfree;
344	tmp.f_tinode = sbuf.f_ffree;
345	if (copy_to_user(u, &tmp, sizeof(struct compat_ustat)))
346		return -EFAULT;
347	return 0;
348}
349
350static int get_compat_flock(struct flock *kfl, struct compat_flock __user *ufl)
351{
352	if (!access_ok(VERIFY_READ, ufl, sizeof(*ufl)) ||
353	    __get_user(kfl->l_type, &ufl->l_type) ||
354	    __get_user(kfl->l_whence, &ufl->l_whence) ||
355	    __get_user(kfl->l_start, &ufl->l_start) ||
356	    __get_user(kfl->l_len, &ufl->l_len) ||
357	    __get_user(kfl->l_pid, &ufl->l_pid))
358		return -EFAULT;
359	return 0;
360}
361
362static int put_compat_flock(struct flock *kfl, struct compat_flock __user *ufl)
363{
364	if (!access_ok(VERIFY_WRITE, ufl, sizeof(*ufl)) ||
365	    __put_user(kfl->l_type, &ufl->l_type) ||
366	    __put_user(kfl->l_whence, &ufl->l_whence) ||
367	    __put_user(kfl->l_start, &ufl->l_start) ||
368	    __put_user(kfl->l_len, &ufl->l_len) ||
369	    __put_user(kfl->l_pid, &ufl->l_pid))
370		return -EFAULT;
371	return 0;
372}
373
374#ifndef HAVE_ARCH_GET_COMPAT_FLOCK64
375static int get_compat_flock64(struct flock *kfl, struct compat_flock64 __user *ufl)
376{
377	if (!access_ok(VERIFY_READ, ufl, sizeof(*ufl)) ||
378	    __get_user(kfl->l_type, &ufl->l_type) ||
379	    __get_user(kfl->l_whence, &ufl->l_whence) ||
380	    __get_user(kfl->l_start, &ufl->l_start) ||
381	    __get_user(kfl->l_len, &ufl->l_len) ||
382	    __get_user(kfl->l_pid, &ufl->l_pid))
383		return -EFAULT;
384	return 0;
385}
386#endif
387
388#ifndef HAVE_ARCH_PUT_COMPAT_FLOCK64
389static int put_compat_flock64(struct flock *kfl, struct compat_flock64 __user *ufl)
390{
391	if (!access_ok(VERIFY_WRITE, ufl, sizeof(*ufl)) ||
392	    __put_user(kfl->l_type, &ufl->l_type) ||
393	    __put_user(kfl->l_whence, &ufl->l_whence) ||
394	    __put_user(kfl->l_start, &ufl->l_start) ||
395	    __put_user(kfl->l_len, &ufl->l_len) ||
396	    __put_user(kfl->l_pid, &ufl->l_pid))
397		return -EFAULT;
398	return 0;
399}
400#endif
401
402static unsigned int
403convert_fcntl_cmd(unsigned int cmd)
404{
405	switch (cmd) {
406	case F_GETLK64:
407		return F_GETLK;
408	case F_SETLK64:
409		return F_SETLK;
410	case F_SETLKW64:
411		return F_SETLKW;
412	}
413
414	return cmd;
415}
416
417COMPAT_SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd,
418		       compat_ulong_t, arg)
419{
420	mm_segment_t old_fs;
421	struct flock f;
422	long ret;
423	unsigned int conv_cmd;
424
425	switch (cmd) {
426	case F_GETLK:
427	case F_SETLK:
428	case F_SETLKW:
429		ret = get_compat_flock(&f, compat_ptr(arg));
430		if (ret != 0)
431			break;
432		old_fs = get_fs();
433		set_fs(KERNEL_DS);
434		ret = sys_fcntl(fd, cmd, (unsigned long)&f);
435		set_fs(old_fs);
436		if (cmd == F_GETLK && ret == 0) {
437			/* GETLK was successful and we need to return the data...
438			 * but it needs to fit in the compat structure.
439			 * l_start shouldn't be too big, unless the original
440			 * start + end is greater than COMPAT_OFF_T_MAX, in which
441			 * case the app was asking for trouble, so we return
442			 * -EOVERFLOW in that case.
443			 * l_len could be too big, in which case we just truncate it,
444			 * and only allow the app to see that part of the conflicting
445			 * lock that might make sense to it anyway
446			 */
447
448			if (f.l_start > COMPAT_OFF_T_MAX)
449				ret = -EOVERFLOW;
450			if (f.l_len > COMPAT_OFF_T_MAX)
451				f.l_len = COMPAT_OFF_T_MAX;
452			if (ret == 0)
453				ret = put_compat_flock(&f, compat_ptr(arg));
454		}
455		break;
456
457	case F_GETLK64:
458	case F_SETLK64:
459	case F_SETLKW64:
460	case F_OFD_GETLK:
461	case F_OFD_SETLK:
462	case F_OFD_SETLKW:
463		ret = get_compat_flock64(&f, compat_ptr(arg));
464		if (ret != 0)
465			break;
466		old_fs = get_fs();
467		set_fs(KERNEL_DS);
468		conv_cmd = convert_fcntl_cmd(cmd);
469		ret = sys_fcntl(fd, conv_cmd, (unsigned long)&f);
470		set_fs(old_fs);
471		if ((conv_cmd == F_GETLK || conv_cmd == F_OFD_GETLK) && ret == 0) {
472			/* need to return lock information - see above for commentary */
473			if (f.l_start > COMPAT_LOFF_T_MAX)
474				ret = -EOVERFLOW;
475			if (f.l_len > COMPAT_LOFF_T_MAX)
476				f.l_len = COMPAT_LOFF_T_MAX;
477			if (ret == 0)
478				ret = put_compat_flock64(&f, compat_ptr(arg));
479		}
480		break;
481
482	default:
483		ret = sys_fcntl(fd, cmd, arg);
484		break;
485	}
486	return ret;
487}
488
489COMPAT_SYSCALL_DEFINE3(fcntl, unsigned int, fd, unsigned int, cmd,
490		       compat_ulong_t, arg)
491{
492	switch (cmd) {
493	case F_GETLK64:
494	case F_SETLK64:
495	case F_SETLKW64:
496	case F_OFD_GETLK:
497	case F_OFD_SETLK:
498	case F_OFD_SETLKW:
499		return -EINVAL;
500	}
501	return compat_sys_fcntl64(fd, cmd, arg);
502}
503
504COMPAT_SYSCALL_DEFINE2(io_setup, unsigned, nr_reqs, u32 __user *, ctx32p)
505{
506	long ret;
507	aio_context_t ctx64;
508
509	mm_segment_t oldfs = get_fs();
510	if (unlikely(get_user(ctx64, ctx32p)))
511		return -EFAULT;
512
513	set_fs(KERNEL_DS);
514	/* The __user pointer cast is valid because of the set_fs() */
515	ret = sys_io_setup(nr_reqs, (aio_context_t __user *) &ctx64);
516	set_fs(oldfs);
517	/* truncating is ok because it's a user address */
518	if (!ret)
519		ret = put_user((u32) ctx64, ctx32p);
520	return ret;
521}
522
523COMPAT_SYSCALL_DEFINE5(io_getevents, compat_aio_context_t, ctx_id,
524		       compat_long_t, min_nr,
525		       compat_long_t, nr,
526		       struct io_event __user *, events,
527		       struct compat_timespec __user *, timeout)
528{
529	struct timespec t;
530	struct timespec __user *ut = NULL;
531
532	if (timeout) {
533		if (compat_get_timespec(&t, timeout))
534			return -EFAULT;
535
536		ut = compat_alloc_user_space(sizeof(*ut));
537		if (copy_to_user(ut, &t, sizeof(t)) )
538			return -EFAULT;
539	}
540	return sys_io_getevents(ctx_id, min_nr, nr, events, ut);
541}
542
543/* A write operation does a read from user space and vice versa */
544#define vrfy_dir(type) ((type) == READ ? VERIFY_WRITE : VERIFY_READ)
545
546ssize_t compat_rw_copy_check_uvector(int type,
547		const struct compat_iovec __user *uvector, unsigned long nr_segs,
548		unsigned long fast_segs, struct iovec *fast_pointer,
549		struct iovec **ret_pointer)
550{
551	compat_ssize_t tot_len;
552	struct iovec *iov = *ret_pointer = fast_pointer;
553	ssize_t ret = 0;
554	int seg;
555
556	/*
557	 * SuS says "The readv() function *may* fail if the iovcnt argument
558	 * was less than or equal to 0, or greater than {IOV_MAX}.  Linux has
559	 * traditionally returned zero for zero segments, so...
560	 */
561	if (nr_segs == 0)
562		goto out;
563
564	ret = -EINVAL;
565	if (nr_segs > UIO_MAXIOV || nr_segs < 0)
566		goto out;
567	if (nr_segs > fast_segs) {
568		ret = -ENOMEM;
569		iov = kmalloc(nr_segs*sizeof(struct iovec), GFP_KERNEL);
570		if (iov == NULL)
571			goto out;
572	}
573	*ret_pointer = iov;
574
575	ret = -EFAULT;
576	if (!access_ok(VERIFY_READ, uvector, nr_segs*sizeof(*uvector)))
577		goto out;
578
579	/*
580	 * Single unix specification:
581	 * We should -EINVAL if an element length is not >= 0 and fitting an
582	 * ssize_t.
583	 *
584	 * In Linux, the total length is limited to MAX_RW_COUNT, there is
585	 * no overflow possibility.
586	 */
587	tot_len = 0;
588	ret = -EINVAL;
589	for (seg = 0; seg < nr_segs; seg++) {
590		compat_uptr_t buf;
591		compat_ssize_t len;
592
593		if (__get_user(len, &uvector->iov_len) ||
594		   __get_user(buf, &uvector->iov_base)) {
595			ret = -EFAULT;
596			goto out;
597		}
598		if (len < 0)	/* size_t not fitting in compat_ssize_t .. */
599			goto out;
600		if (type >= 0 &&
601		    !access_ok(vrfy_dir(type), compat_ptr(buf), len)) {
602			ret = -EFAULT;
603			goto out;
604		}
605		if (len > MAX_RW_COUNT - tot_len)
606			len = MAX_RW_COUNT - tot_len;
607		tot_len += len;
608		iov->iov_base = compat_ptr(buf);
609		iov->iov_len = (compat_size_t) len;
610		uvector++;
611		iov++;
612	}
613	ret = tot_len;
614
615out:
616	return ret;
617}
618
619static inline long
620copy_iocb(long nr, u32 __user *ptr32, struct iocb __user * __user *ptr64)
621{
622	compat_uptr_t uptr;
623	int i;
624
625	for (i = 0; i < nr; ++i) {
626		if (get_user(uptr, ptr32 + i))
627			return -EFAULT;
628		if (put_user(compat_ptr(uptr), ptr64 + i))
629			return -EFAULT;
630	}
631	return 0;
632}
633
634#define MAX_AIO_SUBMITS 	(PAGE_SIZE/sizeof(struct iocb *))
635
636COMPAT_SYSCALL_DEFINE3(io_submit, compat_aio_context_t, ctx_id,
637		       int, nr, u32 __user *, iocb)
638{
639	struct iocb __user * __user *iocb64;
640	long ret;
641
642	if (unlikely(nr < 0))
643		return -EINVAL;
644
645	if (nr > MAX_AIO_SUBMITS)
646		nr = MAX_AIO_SUBMITS;
647
648	iocb64 = compat_alloc_user_space(nr * sizeof(*iocb64));
649	ret = copy_iocb(nr, iocb, iocb64);
650	if (!ret)
651		ret = do_io_submit(ctx_id, nr, iocb64, 1);
652	return ret;
653}
654
655struct compat_ncp_mount_data {
656	compat_int_t version;
657	compat_uint_t ncp_fd;
658	__compat_uid_t mounted_uid;
659	compat_pid_t wdog_pid;
660	unsigned char mounted_vol[NCP_VOLNAME_LEN + 1];
661	compat_uint_t time_out;
662	compat_uint_t retry_count;
663	compat_uint_t flags;
664	__compat_uid_t uid;
665	__compat_gid_t gid;
666	compat_mode_t file_mode;
667	compat_mode_t dir_mode;
668};
669
670struct compat_ncp_mount_data_v4 {
671	compat_int_t version;
672	compat_ulong_t flags;
673	compat_ulong_t mounted_uid;
674	compat_long_t wdog_pid;
675	compat_uint_t ncp_fd;
676	compat_uint_t time_out;
677	compat_uint_t retry_count;
678	compat_ulong_t uid;
679	compat_ulong_t gid;
680	compat_ulong_t file_mode;
681	compat_ulong_t dir_mode;
682};
683
684static void *do_ncp_super_data_conv(void *raw_data)
685{
686	int version = *(unsigned int *)raw_data;
687
688	if (version == 3) {
689		struct compat_ncp_mount_data *c_n = raw_data;
690		struct ncp_mount_data *n = raw_data;
691
692		n->dir_mode = c_n->dir_mode;
693		n->file_mode = c_n->file_mode;
694		n->gid = c_n->gid;
695		n->uid = c_n->uid;
696		memmove (n->mounted_vol, c_n->mounted_vol, (sizeof (c_n->mounted_vol) + 3 * sizeof (unsigned int)));
697		n->wdog_pid = c_n->wdog_pid;
698		n->mounted_uid = c_n->mounted_uid;
699	} else if (version == 4) {
700		struct compat_ncp_mount_data_v4 *c_n = raw_data;
701		struct ncp_mount_data_v4 *n = raw_data;
702
703		n->dir_mode = c_n->dir_mode;
704		n->file_mode = c_n->file_mode;
705		n->gid = c_n->gid;
706		n->uid = c_n->uid;
707		n->retry_count = c_n->retry_count;
708		n->time_out = c_n->time_out;
709		n->ncp_fd = c_n->ncp_fd;
710		n->wdog_pid = c_n->wdog_pid;
711		n->mounted_uid = c_n->mounted_uid;
712		n->flags = c_n->flags;
713	} else if (version != 5) {
714		return NULL;
715	}
716
717	return raw_data;
718}
719
720
721struct compat_nfs_string {
722	compat_uint_t len;
723	compat_uptr_t data;
724};
725
726static inline void compat_nfs_string(struct nfs_string *dst,
727				     struct compat_nfs_string *src)
728{
729	dst->data = compat_ptr(src->data);
730	dst->len = src->len;
731}
732
733struct compat_nfs4_mount_data_v1 {
734	compat_int_t version;
735	compat_int_t flags;
736	compat_int_t rsize;
737	compat_int_t wsize;
738	compat_int_t timeo;
739	compat_int_t retrans;
740	compat_int_t acregmin;
741	compat_int_t acregmax;
742	compat_int_t acdirmin;
743	compat_int_t acdirmax;
744	struct compat_nfs_string client_addr;
745	struct compat_nfs_string mnt_path;
746	struct compat_nfs_string hostname;
747	compat_uint_t host_addrlen;
748	compat_uptr_t host_addr;
749	compat_int_t proto;
750	compat_int_t auth_flavourlen;
751	compat_uptr_t auth_flavours;
752};
753
754static int do_nfs4_super_data_conv(void *raw_data)
755{
756	int version = *(compat_uint_t *) raw_data;
757
758	if (version == 1) {
759		struct compat_nfs4_mount_data_v1 *raw = raw_data;
760		struct nfs4_mount_data *real = raw_data;
761
762		/* copy the fields backwards */
763		real->auth_flavours = compat_ptr(raw->auth_flavours);
764		real->auth_flavourlen = raw->auth_flavourlen;
765		real->proto = raw->proto;
766		real->host_addr = compat_ptr(raw->host_addr);
767		real->host_addrlen = raw->host_addrlen;
768		compat_nfs_string(&real->hostname, &raw->hostname);
769		compat_nfs_string(&real->mnt_path, &raw->mnt_path);
770		compat_nfs_string(&real->client_addr, &raw->client_addr);
771		real->acdirmax = raw->acdirmax;
772		real->acdirmin = raw->acdirmin;
773		real->acregmax = raw->acregmax;
774		real->acregmin = raw->acregmin;
775		real->retrans = raw->retrans;
776		real->timeo = raw->timeo;
777		real->wsize = raw->wsize;
778		real->rsize = raw->rsize;
779		real->flags = raw->flags;
780		real->version = raw->version;
781	}
782
783	return 0;
784}
785
786#define NCPFS_NAME      "ncpfs"
787#define NFS4_NAME	"nfs4"
788
789COMPAT_SYSCALL_DEFINE5(mount, const char __user *, dev_name,
790		       const char __user *, dir_name,
791		       const char __user *, type, compat_ulong_t, flags,
792		       const void __user *, data)
793{
794	char *kernel_type;
795	unsigned long data_page;
796	char *kernel_dev;
797	int retval;
798
799	kernel_type = copy_mount_string(type);
800	retval = PTR_ERR(kernel_type);
801	if (IS_ERR(kernel_type))
802		goto out;
803
804	kernel_dev = copy_mount_string(dev_name);
805	retval = PTR_ERR(kernel_dev);
806	if (IS_ERR(kernel_dev))
807		goto out1;
808
809	retval = copy_mount_options(data, &data_page);
810	if (retval < 0)
811		goto out2;
812
813	retval = -EINVAL;
814
815	if (kernel_type && data_page) {
816		if (!strcmp(kernel_type, NCPFS_NAME)) {
817			do_ncp_super_data_conv((void *)data_page);
818		} else if (!strcmp(kernel_type, NFS4_NAME)) {
819			if (do_nfs4_super_data_conv((void *) data_page))
820				goto out3;
821		}
822	}
823
824	retval = do_mount(kernel_dev, dir_name, kernel_type,
825			flags, (void*)data_page);
826
827 out3:
828	free_page(data_page);
829 out2:
830	kfree(kernel_dev);
831 out1:
832	kfree(kernel_type);
833 out:
834	return retval;
835}
836
837struct compat_old_linux_dirent {
838	compat_ulong_t	d_ino;
839	compat_ulong_t	d_offset;
840	unsigned short	d_namlen;
841	char		d_name[1];
842};
843
844struct compat_readdir_callback {
845	struct dir_context ctx;
846	struct compat_old_linux_dirent __user *dirent;
847	int result;
848};
849
850static int compat_fillonedir(struct dir_context *ctx, const char *name,
851			     int namlen, loff_t offset, u64 ino,
852			     unsigned int d_type)
853{
854	struct compat_readdir_callback *buf =
855		container_of(ctx, struct compat_readdir_callback, ctx);
856	struct compat_old_linux_dirent __user *dirent;
857	compat_ulong_t d_ino;
858
859	if (buf->result)
860		return -EINVAL;
861	d_ino = ino;
862	if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) {
863		buf->result = -EOVERFLOW;
864		return -EOVERFLOW;
865	}
866	buf->result++;
867	dirent = buf->dirent;
868	if (!access_ok(VERIFY_WRITE, dirent,
869			(unsigned long)(dirent->d_name + namlen + 1) -
870				(unsigned long)dirent))
871		goto efault;
872	if (	__put_user(d_ino, &dirent->d_ino) ||
873		__put_user(offset, &dirent->d_offset) ||
874		__put_user(namlen, &dirent->d_namlen) ||
875		__copy_to_user(dirent->d_name, name, namlen) ||
876		__put_user(0, dirent->d_name + namlen))
877		goto efault;
878	return 0;
879efault:
880	buf->result = -EFAULT;
881	return -EFAULT;
882}
883
884COMPAT_SYSCALL_DEFINE3(old_readdir, unsigned int, fd,
885		struct compat_old_linux_dirent __user *, dirent, unsigned int, count)
886{
887	int error;
888	struct fd f = fdget(fd);
889	struct compat_readdir_callback buf = {
890		.ctx.actor = compat_fillonedir,
891		.dirent = dirent
892	};
893
894	if (!f.file)
895		return -EBADF;
896
897	error = iterate_dir(f.file, &buf.ctx);
898	if (buf.result)
899		error = buf.result;
900
901	fdput(f);
902	return error;
903}
904
905struct compat_linux_dirent {
906	compat_ulong_t	d_ino;
907	compat_ulong_t	d_off;
908	unsigned short	d_reclen;
909	char		d_name[1];
910};
911
912struct compat_getdents_callback {
913	struct dir_context ctx;
914	struct compat_linux_dirent __user *current_dir;
915	struct compat_linux_dirent __user *previous;
916	int count;
917	int error;
918};
919
920static int compat_filldir(struct dir_context *ctx, const char *name, int namlen,
921		loff_t offset, u64 ino, unsigned int d_type)
922{
923	struct compat_linux_dirent __user * dirent;
924	struct compat_getdents_callback *buf =
925		container_of(ctx, struct compat_getdents_callback, ctx);
926	compat_ulong_t d_ino;
927	int reclen = ALIGN(offsetof(struct compat_linux_dirent, d_name) +
928		namlen + 2, sizeof(compat_long_t));
929
930	buf->error = -EINVAL;	/* only used if we fail.. */
931	if (reclen > buf->count)
932		return -EINVAL;
933	d_ino = ino;
934	if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) {
935		buf->error = -EOVERFLOW;
936		return -EOVERFLOW;
937	}
938	dirent = buf->previous;
939	if (dirent) {
940		if (__put_user(offset, &dirent->d_off))
941			goto efault;
942	}
943	dirent = buf->current_dir;
944	if (__put_user(d_ino, &dirent->d_ino))
945		goto efault;
946	if (__put_user(reclen, &dirent->d_reclen))
947		goto efault;
948	if (copy_to_user(dirent->d_name, name, namlen))
949		goto efault;
950	if (__put_user(0, dirent->d_name + namlen))
951		goto efault;
952	if (__put_user(d_type, (char  __user *) dirent + reclen - 1))
953		goto efault;
954	buf->previous = dirent;
955	dirent = (void __user *)dirent + reclen;
956	buf->current_dir = dirent;
957	buf->count -= reclen;
958	return 0;
959efault:
960	buf->error = -EFAULT;
961	return -EFAULT;
962}
963
964COMPAT_SYSCALL_DEFINE3(getdents, unsigned int, fd,
965		struct compat_linux_dirent __user *, dirent, unsigned int, count)
966{
967	struct fd f;
968	struct compat_linux_dirent __user * lastdirent;
969	struct compat_getdents_callback buf = {
970		.ctx.actor = compat_filldir,
971		.current_dir = dirent,
972		.count = count
973	};
974	int error;
975
976	if (!access_ok(VERIFY_WRITE, dirent, count))
977		return -EFAULT;
978
979	f = fdget(fd);
980	if (!f.file)
981		return -EBADF;
982
983	error = iterate_dir(f.file, &buf.ctx);
984	if (error >= 0)
985		error = buf.error;
986	lastdirent = buf.previous;
987	if (lastdirent) {
988		if (put_user(buf.ctx.pos, &lastdirent->d_off))
989			error = -EFAULT;
990		else
991			error = count - buf.count;
992	}
993	fdput(f);
994	return error;
995}
996
997#ifdef __ARCH_WANT_COMPAT_SYS_GETDENTS64
998
999struct compat_getdents_callback64 {
1000	struct dir_context ctx;
1001	struct linux_dirent64 __user *current_dir;
1002	struct linux_dirent64 __user *previous;
1003	int count;
1004	int error;
1005};
1006
1007static int compat_filldir64(struct dir_context *ctx, const char *name,
1008			    int namlen, loff_t offset, u64 ino,
1009			    unsigned int d_type)
1010{
1011	struct linux_dirent64 __user *dirent;
1012	struct compat_getdents_callback64 *buf =
1013		container_of(ctx, struct compat_getdents_callback64, ctx);
1014	int reclen = ALIGN(offsetof(struct linux_dirent64, d_name) + namlen + 1,
1015		sizeof(u64));
1016	u64 off;
1017
1018	buf->error = -EINVAL;	/* only used if we fail.. */
1019	if (reclen > buf->count)
1020		return -EINVAL;
1021	dirent = buf->previous;
1022
1023	if (dirent) {
1024		if (__put_user_unaligned(offset, &dirent->d_off))
1025			goto efault;
1026	}
1027	dirent = buf->current_dir;
1028	if (__put_user_unaligned(ino, &dirent->d_ino))
1029		goto efault;
1030	off = 0;
1031	if (__put_user_unaligned(off, &dirent->d_off))
1032		goto efault;
1033	if (__put_user(reclen, &dirent->d_reclen))
1034		goto efault;
1035	if (__put_user(d_type, &dirent->d_type))
1036		goto efault;
1037	if (copy_to_user(dirent->d_name, name, namlen))
1038		goto efault;
1039	if (__put_user(0, dirent->d_name + namlen))
1040		goto efault;
1041	buf->previous = dirent;
1042	dirent = (void __user *)dirent + reclen;
1043	buf->current_dir = dirent;
1044	buf->count -= reclen;
1045	return 0;
1046efault:
1047	buf->error = -EFAULT;
1048	return -EFAULT;
1049}
1050
1051COMPAT_SYSCALL_DEFINE3(getdents64, unsigned int, fd,
1052		struct linux_dirent64 __user *, dirent, unsigned int, count)
1053{
1054	struct fd f;
1055	struct linux_dirent64 __user * lastdirent;
1056	struct compat_getdents_callback64 buf = {
1057		.ctx.actor = compat_filldir64,
1058		.current_dir = dirent,
1059		.count = count
1060	};
1061	int error;
1062
1063	if (!access_ok(VERIFY_WRITE, dirent, count))
1064		return -EFAULT;
1065
1066	f = fdget(fd);
1067	if (!f.file)
1068		return -EBADF;
1069
1070	error = iterate_dir(f.file, &buf.ctx);
1071	if (error >= 0)
1072		error = buf.error;
1073	lastdirent = buf.previous;
1074	if (lastdirent) {
1075		typeof(lastdirent->d_off) d_off = buf.ctx.pos;
1076		if (__put_user_unaligned(d_off, &lastdirent->d_off))
1077			error = -EFAULT;
1078		else
1079			error = count - buf.count;
1080	}
1081	fdput(f);
1082	return error;
1083}
1084#endif /* __ARCH_WANT_COMPAT_SYS_GETDENTS64 */
1085
1086/*
1087 * Exactly like fs/open.c:sys_open(), except that it doesn't set the
1088 * O_LARGEFILE flag.
1089 */
1090COMPAT_SYSCALL_DEFINE3(open, const char __user *, filename, int, flags, umode_t, mode)
1091{
1092	return do_sys_open(AT_FDCWD, filename, flags, mode);
1093}
1094
1095/*
1096 * Exactly like fs/open.c:sys_openat(), except that it doesn't set the
1097 * O_LARGEFILE flag.
1098 */
1099COMPAT_SYSCALL_DEFINE4(openat, int, dfd, const char __user *, filename, int, flags, umode_t, mode)
1100{
1101	return do_sys_open(dfd, filename, flags, mode);
1102}
1103
1104#define __COMPAT_NFDBITS       (8 * sizeof(compat_ulong_t))
1105
1106static int poll_select_copy_remaining(struct timespec *end_time, void __user *p,
1107				      int timeval, int ret)
1108{
1109	struct timespec ts;
1110
1111	if (!p)
1112		return ret;
1113
1114	if (current->personality & STICKY_TIMEOUTS)
1115		goto sticky;
1116
1117	/* No update for zero timeout */
1118	if (!end_time->tv_sec && !end_time->tv_nsec)
1119		return ret;
1120
1121	ktime_get_ts(&ts);
1122	ts = timespec_sub(*end_time, ts);
1123	if (ts.tv_sec < 0)
1124		ts.tv_sec = ts.tv_nsec = 0;
1125
1126	if (timeval) {
1127		struct compat_timeval rtv;
1128
1129		rtv.tv_sec = ts.tv_sec;
1130		rtv.tv_usec = ts.tv_nsec / NSEC_PER_USEC;
1131
1132		if (!copy_to_user(p, &rtv, sizeof(rtv)))
1133			return ret;
1134	} else {
1135		struct compat_timespec rts;
1136
1137		rts.tv_sec = ts.tv_sec;
1138		rts.tv_nsec = ts.tv_nsec;
1139
1140		if (!copy_to_user(p, &rts, sizeof(rts)))
1141			return ret;
1142	}
1143	/*
1144	 * If an application puts its timeval in read-only memory, we
1145	 * don't want the Linux-specific update to the timeval to
1146	 * cause a fault after the select has completed
1147	 * successfully. However, because we're not updating the
1148	 * timeval, we can't restart the system call.
1149	 */
1150
1151sticky:
1152	if (ret == -ERESTARTNOHAND)
1153		ret = -EINTR;
1154	return ret;
1155}
1156
1157/*
1158 * Ooo, nasty.  We need here to frob 32-bit unsigned longs to
1159 * 64-bit unsigned longs.
1160 */
1161static
1162int compat_get_fd_set(unsigned long nr, compat_ulong_t __user *ufdset,
1163			unsigned long *fdset)
1164{
1165	nr = DIV_ROUND_UP(nr, __COMPAT_NFDBITS);
1166	if (ufdset) {
1167		unsigned long odd;
1168
1169		if (!access_ok(VERIFY_WRITE, ufdset, nr*sizeof(compat_ulong_t)))
1170			return -EFAULT;
1171
1172		odd = nr & 1UL;
1173		nr &= ~1UL;
1174		while (nr) {
1175			unsigned long h, l;
1176			if (__get_user(l, ufdset) || __get_user(h, ufdset+1))
1177				return -EFAULT;
1178			ufdset += 2;
1179			*fdset++ = h << 32 | l;
1180			nr -= 2;
1181		}
1182		if (odd && __get_user(*fdset, ufdset))
1183			return -EFAULT;
1184	} else {
1185		/* Tricky, must clear full unsigned long in the
1186		 * kernel fdset at the end, this makes sure that
1187		 * actually happens.
1188		 */
1189		memset(fdset, 0, ((nr + 1) & ~1)*sizeof(compat_ulong_t));
1190	}
1191	return 0;
1192}
1193
1194static
1195int compat_set_fd_set(unsigned long nr, compat_ulong_t __user *ufdset,
1196		      unsigned long *fdset)
1197{
1198	unsigned long odd;
1199	nr = DIV_ROUND_UP(nr, __COMPAT_NFDBITS);
1200
1201	if (!ufdset)
1202		return 0;
1203
1204	odd = nr & 1UL;
1205	nr &= ~1UL;
1206	while (nr) {
1207		unsigned long h, l;
1208		l = *fdset++;
1209		h = l >> 32;
1210		if (__put_user(l, ufdset) || __put_user(h, ufdset+1))
1211			return -EFAULT;
1212		ufdset += 2;
1213		nr -= 2;
1214	}
1215	if (odd && __put_user(*fdset, ufdset))
1216		return -EFAULT;
1217	return 0;
1218}
1219
1220
1221/*
1222 * This is a virtual copy of sys_select from fs/select.c and probably
1223 * should be compared to it from time to time
1224 */
1225
1226/*
1227 * We can actually return ERESTARTSYS instead of EINTR, but I'd
1228 * like to be certain this leads to no problems. So I return
1229 * EINTR just for safety.
1230 *
1231 * Update: ERESTARTSYS breaks at least the xview clock binary, so
1232 * I'm trying ERESTARTNOHAND which restart only when you want to.
1233 */
1234int compat_core_sys_select(int n, compat_ulong_t __user *inp,
1235	compat_ulong_t __user *outp, compat_ulong_t __user *exp,
1236	struct timespec *end_time)
1237{
1238	fd_set_bits fds;
1239	void *bits;
1240	int size, max_fds, ret = -EINVAL;
1241	struct fdtable *fdt;
1242	long stack_fds[SELECT_STACK_ALLOC/sizeof(long)];
1243
1244	if (n < 0)
1245		goto out_nofds;
1246
1247	/* max_fds can increase, so grab it once to avoid race */
1248	rcu_read_lock();
1249	fdt = files_fdtable(current->files);
1250	max_fds = fdt->max_fds;
1251	rcu_read_unlock();
1252	if (n > max_fds)
1253		n = max_fds;
1254
1255	/*
1256	 * We need 6 bitmaps (in/out/ex for both incoming and outgoing),
1257	 * since we used fdset we need to allocate memory in units of
1258	 * long-words.
1259	 */
1260	size = FDS_BYTES(n);
1261	bits = stack_fds;
1262	if (size > sizeof(stack_fds) / 6) {
1263		bits = kmalloc(6 * size, GFP_KERNEL);
1264		ret = -ENOMEM;
1265		if (!bits)
1266			goto out_nofds;
1267	}
1268	fds.in      = (unsigned long *)  bits;
1269	fds.out     = (unsigned long *) (bits +   size);
1270	fds.ex      = (unsigned long *) (bits + 2*size);
1271	fds.res_in  = (unsigned long *) (bits + 3*size);
1272	fds.res_out = (unsigned long *) (bits + 4*size);
1273	fds.res_ex  = (unsigned long *) (bits + 5*size);
1274
1275	if ((ret = compat_get_fd_set(n, inp, fds.in)) ||
1276	    (ret = compat_get_fd_set(n, outp, fds.out)) ||
1277	    (ret = compat_get_fd_set(n, exp, fds.ex)))
1278		goto out;
1279	zero_fd_set(n, fds.res_in);
1280	zero_fd_set(n, fds.res_out);
1281	zero_fd_set(n, fds.res_ex);
1282
1283	ret = do_select(n, &fds, end_time);
1284
1285	if (ret < 0)
1286		goto out;
1287	if (!ret) {
1288		ret = -ERESTARTNOHAND;
1289		if (signal_pending(current))
1290			goto out;
1291		ret = 0;
1292	}
1293
1294	if (compat_set_fd_set(n, inp, fds.res_in) ||
1295	    compat_set_fd_set(n, outp, fds.res_out) ||
1296	    compat_set_fd_set(n, exp, fds.res_ex))
1297		ret = -EFAULT;
1298out:
1299	if (bits != stack_fds)
1300		kfree(bits);
1301out_nofds:
1302	return ret;
1303}
1304
1305COMPAT_SYSCALL_DEFINE5(select, int, n, compat_ulong_t __user *, inp,
1306	compat_ulong_t __user *, outp, compat_ulong_t __user *, exp,
1307	struct compat_timeval __user *, tvp)
1308{
1309	struct timespec end_time, *to = NULL;
1310	struct compat_timeval tv;
1311	int ret;
1312
1313	if (tvp) {
1314		if (copy_from_user(&tv, tvp, sizeof(tv)))
1315			return -EFAULT;
1316
1317		to = &end_time;
1318		if (poll_select_set_timeout(to,
1319				tv.tv_sec + (tv.tv_usec / USEC_PER_SEC),
1320				(tv.tv_usec % USEC_PER_SEC) * NSEC_PER_USEC))
1321			return -EINVAL;
1322	}
1323
1324	ret = compat_core_sys_select(n, inp, outp, exp, to);
1325	ret = poll_select_copy_remaining(&end_time, tvp, 1, ret);
1326
1327	return ret;
1328}
1329
1330struct compat_sel_arg_struct {
1331	compat_ulong_t n;
1332	compat_uptr_t inp;
1333	compat_uptr_t outp;
1334	compat_uptr_t exp;
1335	compat_uptr_t tvp;
1336};
1337
1338COMPAT_SYSCALL_DEFINE1(old_select, struct compat_sel_arg_struct __user *, arg)
1339{
1340	struct compat_sel_arg_struct a;
1341
1342	if (copy_from_user(&a, arg, sizeof(a)))
1343		return -EFAULT;
1344	return compat_sys_select(a.n, compat_ptr(a.inp), compat_ptr(a.outp),
1345				 compat_ptr(a.exp), compat_ptr(a.tvp));
1346}
1347
1348static long do_compat_pselect(int n, compat_ulong_t __user *inp,
1349	compat_ulong_t __user *outp, compat_ulong_t __user *exp,
1350	struct compat_timespec __user *tsp, compat_sigset_t __user *sigmask,
1351	compat_size_t sigsetsize)
1352{
1353	compat_sigset_t ss32;
1354	sigset_t ksigmask, sigsaved;
1355	struct compat_timespec ts;
1356	struct timespec end_time, *to = NULL;
1357	int ret;
1358
1359	if (tsp) {
1360		if (copy_from_user(&ts, tsp, sizeof(ts)))
1361			return -EFAULT;
1362
1363		to = &end_time;
1364		if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec))
1365			return -EINVAL;
1366	}
1367
1368	if (sigmask) {
1369		if (sigsetsize != sizeof(compat_sigset_t))
1370			return -EINVAL;
1371		if (copy_from_user(&ss32, sigmask, sizeof(ss32)))
1372			return -EFAULT;
1373		sigset_from_compat(&ksigmask, &ss32);
1374
1375		sigdelsetmask(&ksigmask, sigmask(SIGKILL)|sigmask(SIGSTOP));
1376		sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
1377	}
1378
1379	ret = compat_core_sys_select(n, inp, outp, exp, to);
1380	ret = poll_select_copy_remaining(&end_time, tsp, 0, ret);
1381
1382	if (ret == -ERESTARTNOHAND) {
1383		/*
1384		 * Don't restore the signal mask yet. Let do_signal() deliver
1385		 * the signal on the way back to userspace, before the signal
1386		 * mask is restored.
1387		 */
1388		if (sigmask) {
1389			memcpy(&current->saved_sigmask, &sigsaved,
1390					sizeof(sigsaved));
1391			set_restore_sigmask();
1392		}
1393	} else if (sigmask)
1394		sigprocmask(SIG_SETMASK, &sigsaved, NULL);
1395
1396	return ret;
1397}
1398
1399COMPAT_SYSCALL_DEFINE6(pselect6, int, n, compat_ulong_t __user *, inp,
1400	compat_ulong_t __user *, outp, compat_ulong_t __user *, exp,
1401	struct compat_timespec __user *, tsp, void __user *, sig)
1402{
1403	compat_size_t sigsetsize = 0;
1404	compat_uptr_t up = 0;
1405
1406	if (sig) {
1407		if (!access_ok(VERIFY_READ, sig,
1408				sizeof(compat_uptr_t)+sizeof(compat_size_t)) ||
1409		    	__get_user(up, (compat_uptr_t __user *)sig) ||
1410		    	__get_user(sigsetsize,
1411				(compat_size_t __user *)(sig+sizeof(up))))
1412			return -EFAULT;
1413	}
1414	return do_compat_pselect(n, inp, outp, exp, tsp, compat_ptr(up),
1415				 sigsetsize);
1416}
1417
1418COMPAT_SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds,
1419	unsigned int,  nfds, struct compat_timespec __user *, tsp,
1420	const compat_sigset_t __user *, sigmask, compat_size_t, sigsetsize)
1421{
1422	compat_sigset_t ss32;
1423	sigset_t ksigmask, sigsaved;
1424	struct compat_timespec ts;
1425	struct timespec end_time, *to = NULL;
1426	int ret;
1427
1428	if (tsp) {
1429		if (copy_from_user(&ts, tsp, sizeof(ts)))
1430			return -EFAULT;
1431
1432		to = &end_time;
1433		if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec))
1434			return -EINVAL;
1435	}
1436
1437	if (sigmask) {
1438		if (sigsetsize != sizeof(compat_sigset_t))
1439			return -EINVAL;
1440		if (copy_from_user(&ss32, sigmask, sizeof(ss32)))
1441			return -EFAULT;
1442		sigset_from_compat(&ksigmask, &ss32);
1443
1444		sigdelsetmask(&ksigmask, sigmask(SIGKILL)|sigmask(SIGSTOP));
1445		sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
1446	}
1447
1448	ret = do_sys_poll(ufds, nfds, to);
1449
1450	/* We can restart this syscall, usually */
1451	if (ret == -EINTR) {
1452		/*
1453		 * Don't restore the signal mask yet. Let do_signal() deliver
1454		 * the signal on the way back to userspace, before the signal
1455		 * mask is restored.
1456		 */
1457		if (sigmask) {
1458			memcpy(&current->saved_sigmask, &sigsaved,
1459				sizeof(sigsaved));
1460			set_restore_sigmask();
1461		}
1462		ret = -ERESTARTNOHAND;
1463	} else if (sigmask)
1464		sigprocmask(SIG_SETMASK, &sigsaved, NULL);
1465
1466	ret = poll_select_copy_remaining(&end_time, tsp, 0, ret);
1467
1468	return ret;
1469}
1470
1471#ifdef CONFIG_FHANDLE
1472/*
1473 * Exactly like fs/open.c:sys_open_by_handle_at(), except that it
1474 * doesn't set the O_LARGEFILE flag.
1475 */
1476COMPAT_SYSCALL_DEFINE3(open_by_handle_at, int, mountdirfd,
1477			     struct file_handle __user *, handle, int, flags)
1478{
1479	return do_handle_open(mountdirfd, handle, flags);
1480}
1481#endif
1482