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