• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
57 int compat_log = 1;
58 
compat_printk(const char * fmt,...)59 int 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  */
COMPAT_SYSCALL_DEFINE2(utime,const char __user *,filename,struct compat_utimbuf __user *,t)75 COMPAT_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 
COMPAT_SYSCALL_DEFINE4(utimensat,unsigned int,dfd,const char __user *,filename,struct compat_timespec __user *,t,int,flags)90 COMPAT_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 
COMPAT_SYSCALL_DEFINE3(futimesat,unsigned int,dfd,const char __user *,filename,struct compat_timeval __user *,t)105 COMPAT_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 
COMPAT_SYSCALL_DEFINE2(utimes,const char __user *,filename,struct compat_timeval __user *,t)124 COMPAT_SYSCALL_DEFINE2(utimes, const char __user *, filename, struct compat_timeval __user *, t)
125 {
126 	return compat_sys_futimesat(AT_FDCWD, filename, t);
127 }
128 
cp_compat_stat(struct kstat * stat,struct compat_stat __user * ubuf)129 static 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 
COMPAT_SYSCALL_DEFINE2(newstat,const char __user *,filename,struct compat_stat __user *,statbuf)162 COMPAT_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 
COMPAT_SYSCALL_DEFINE2(newlstat,const char __user *,filename,struct compat_stat __user *,statbuf)174 COMPAT_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
COMPAT_SYSCALL_DEFINE4(newfstatat,unsigned int,dfd,const char __user *,filename,struct compat_stat __user *,statbuf,int,flag)187 COMPAT_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 
COMPAT_SYSCALL_DEFINE2(newfstat,unsigned int,fd,struct compat_stat __user *,statbuf)201 COMPAT_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 
put_compat_statfs(struct compat_statfs __user * ubuf,struct kstatfs * kbuf)212 static 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  */
COMPAT_SYSCALL_DEFINE2(statfs,const char __user *,pathname,struct compat_statfs __user *,buf)250 COMPAT_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 
COMPAT_SYSCALL_DEFINE2(fstatfs,unsigned int,fd,struct compat_statfs __user *,buf)259 COMPAT_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 
put_compat_statfs64(struct compat_statfs64 __user * ubuf,struct kstatfs * kbuf)268 static 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 
COMPAT_SYSCALL_DEFINE3(statfs64,const char __user *,pathname,compat_size_t,sz,struct compat_statfs64 __user *,buf)301 COMPAT_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 
COMPAT_SYSCALL_DEFINE3(fstatfs64,unsigned int,fd,compat_size_t,sz,struct compat_statfs64 __user *,buf)315 COMPAT_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  */
COMPAT_SYSCALL_DEFINE2(ustat,unsigned,dev,struct compat_ustat __user *,u)334 COMPAT_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 
get_compat_flock(struct flock * kfl,struct compat_flock __user * ufl)350 static 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 
put_compat_flock(struct flock * kfl,struct compat_flock __user * ufl)362 static 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
get_compat_flock64(struct flock * kfl,struct compat_flock64 __user * ufl)375 static 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
put_compat_flock64(struct flock * kfl,struct compat_flock64 __user * ufl)389 static 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 
402 static unsigned int
convert_fcntl_cmd(unsigned int cmd)403 convert_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 
COMPAT_SYSCALL_DEFINE3(fcntl64,unsigned int,fd,unsigned int,cmd,compat_ulong_t,arg)417 COMPAT_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 
COMPAT_SYSCALL_DEFINE3(fcntl,unsigned int,fd,unsigned int,cmd,compat_ulong_t,arg)489 COMPAT_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 
COMPAT_SYSCALL_DEFINE2(io_setup,unsigned,nr_reqs,u32 __user *,ctx32p)504 COMPAT_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 
COMPAT_SYSCALL_DEFINE5(io_getevents,compat_aio_context_t,ctx_id,compat_long_t,min_nr,compat_long_t,nr,struct io_event __user *,events,struct compat_timespec __user *,timeout)523 COMPAT_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 
compat_rw_copy_check_uvector(int type,const struct compat_iovec __user * uvector,unsigned long nr_segs,unsigned long fast_segs,struct iovec * fast_pointer,struct iovec ** ret_pointer)546 ssize_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 
615 out:
616 	return ret;
617 }
618 
619 static inline long
copy_iocb(long nr,u32 __user * ptr32,struct iocb __user * __user * ptr64)620 copy_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 
COMPAT_SYSCALL_DEFINE3(io_submit,compat_aio_context_t,ctx_id,int,nr,u32 __user *,iocb)636 COMPAT_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 
655 struct 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 
670 struct 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 
do_ncp_super_data_conv(void * raw_data)684 static 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 
721 struct compat_nfs_string {
722 	compat_uint_t len;
723 	compat_uptr_t data;
724 };
725 
compat_nfs_string(struct nfs_string * dst,struct compat_nfs_string * src)726 static 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 
733 struct 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 
do_nfs4_super_data_conv(void * raw_data)754 static 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 
COMPAT_SYSCALL_DEFINE5(mount,const char __user *,dev_name,const char __user *,dir_name,const char __user *,type,compat_ulong_t,flags,const void __user *,data)789 COMPAT_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 
837 struct 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 
844 struct compat_readdir_callback {
845 	struct dir_context ctx;
846 	struct compat_old_linux_dirent __user *dirent;
847 	int result;
848 };
849 
compat_fillonedir(struct dir_context * ctx,const char * name,int namlen,loff_t offset,u64 ino,unsigned int d_type)850 static 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;
879 efault:
880 	buf->result = -EFAULT;
881 	return -EFAULT;
882 }
883 
COMPAT_SYSCALL_DEFINE3(old_readdir,unsigned int,fd,struct compat_old_linux_dirent __user *,dirent,unsigned int,count)884 COMPAT_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 
905 struct 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 
912 struct 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 
compat_filldir(struct dir_context * ctx,const char * name,int namlen,loff_t offset,u64 ino,unsigned int d_type)920 static 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;
959 efault:
960 	buf->error = -EFAULT;
961 	return -EFAULT;
962 }
963 
COMPAT_SYSCALL_DEFINE3(getdents,unsigned int,fd,struct compat_linux_dirent __user *,dirent,unsigned int,count)964 COMPAT_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 
999 struct 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 
compat_filldir64(struct dir_context * ctx,const char * name,int namlen,loff_t offset,u64 ino,unsigned int d_type)1007 static 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;
1046 efault:
1047 	buf->error = -EFAULT;
1048 	return -EFAULT;
1049 }
1050 
COMPAT_SYSCALL_DEFINE3(getdents64,unsigned int,fd,struct linux_dirent64 __user *,dirent,unsigned int,count)1051 COMPAT_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  */
COMPAT_SYSCALL_DEFINE3(open,const char __user *,filename,int,flags,umode_t,mode)1090 COMPAT_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  */
COMPAT_SYSCALL_DEFINE4(openat,int,dfd,const char __user *,filename,int,flags,umode_t,mode)1099 COMPAT_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 
poll_select_copy_remaining(struct timespec * end_time,void __user * p,int timeval,int ret)1106 static 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 
1151 sticky:
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  */
1161 static
compat_get_fd_set(unsigned long nr,compat_ulong_t __user * ufdset,unsigned long * fdset)1162 int 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 
1194 static
compat_set_fd_set(unsigned long nr,compat_ulong_t __user * ufdset,unsigned long * fdset)1195 int 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  */
compat_core_sys_select(int n,compat_ulong_t __user * inp,compat_ulong_t __user * outp,compat_ulong_t __user * exp,struct timespec * end_time)1234 int 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;
1298 out:
1299 	if (bits != stack_fds)
1300 		kfree(bits);
1301 out_nofds:
1302 	return ret;
1303 }
1304 
COMPAT_SYSCALL_DEFINE5(select,int,n,compat_ulong_t __user *,inp,compat_ulong_t __user *,outp,compat_ulong_t __user *,exp,struct compat_timeval __user *,tvp)1305 COMPAT_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 
1330 struct 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 
COMPAT_SYSCALL_DEFINE1(old_select,struct compat_sel_arg_struct __user *,arg)1338 COMPAT_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 
do_compat_pselect(int n,compat_ulong_t __user * inp,compat_ulong_t __user * outp,compat_ulong_t __user * exp,struct compat_timespec __user * tsp,compat_sigset_t __user * sigmask,compat_size_t sigsetsize)1348 static 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 
COMPAT_SYSCALL_DEFINE6(pselect6,int,n,compat_ulong_t __user *,inp,compat_ulong_t __user *,outp,compat_ulong_t __user *,exp,struct compat_timespec __user *,tsp,void __user *,sig)1399 COMPAT_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 
COMPAT_SYSCALL_DEFINE5(ppoll,struct pollfd __user *,ufds,unsigned int,nfds,struct compat_timespec __user *,tsp,const compat_sigset_t __user *,sigmask,compat_size_t,sigsetsize)1418 COMPAT_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  */
COMPAT_SYSCALL_DEFINE3(open_by_handle_at,int,mountdirfd,struct file_handle __user *,handle,int,flags)1476 COMPAT_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