aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2014-03-04 10:07:52 -0500
committerHeiko Carstens <heiko.carstens@de.ibm.com>2014-03-06 10:30:44 -0500
commit932602e238329da99f8482c1b721549531fbfe7f (patch)
treee32b5562a688ad853783adc1c8c14475be00c681
parent5d70a59637911e84687b421afeb4c111a579fb2b (diff)
fs/compat: convert to COMPAT_SYSCALL_DEFINE with changing parameter types
Some fs compat system calls have unsigned long parameters instead of compat_ulong_t. In order to allow the COMPAT_SYSCALL_DEFINE macro generate code that performs proper zero and sign extension convert all 64 bit parameters their corresponding 32 bit counterparts. compat_sys_io_getevents() is a bit different: the non-compat version has signed parameters for the "min_nr" and "nr" parameters while the compat version has unsigned parameters. So change this as well. For all practical purposes this shouldn't make any difference (doesn't fix a real bug). Also introduce a generic compat_aio_context_t type which can be used everywhere. The access_ok() check within compat_sys_io_getevents() got also removed since the non-compat sys_io_getevents() should be able to handle everything anyway. Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
-rw-r--r--arch/s390/include/asm/compat.h1
-rw-r--r--fs/compat.c44
-rw-r--r--fs/compat_ioctl.c5
-rw-r--r--include/linux/compat.h18
4 files changed, 31 insertions, 37 deletions
diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h
index 1174ea2b5e7c..5d7e8cf83bd6 100644
--- a/arch/s390/include/asm/compat.h
+++ b/arch/s390/include/asm/compat.h
@@ -65,7 +65,6 @@ typedef u32 compat_caddr_t;
65typedef __kernel_fsid_t compat_fsid_t; 65typedef __kernel_fsid_t compat_fsid_t;
66typedef s32 compat_key_t; 66typedef s32 compat_key_t;
67typedef s32 compat_timer_t; 67typedef s32 compat_timer_t;
68typedef u32 compat_aio_context_t;
69 68
70typedef s32 compat_int_t; 69typedef s32 compat_int_t;
71typedef s32 compat_long_t; 70typedef s32 compat_long_t;
diff --git a/fs/compat.c b/fs/compat.c
index 6d8312b7a51d..19252b97f0cc 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -399,8 +399,8 @@ static int put_compat_flock64(struct flock *kfl, struct compat_flock64 __user *u
399} 399}
400#endif 400#endif
401 401
402asmlinkage long compat_sys_fcntl64(unsigned int fd, unsigned int cmd, 402COMPAT_SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd,
403 unsigned long arg) 403 compat_ulong_t, arg)
404{ 404{
405 mm_segment_t old_fs; 405 mm_segment_t old_fs;
406 struct flock f; 406 struct flock f;
@@ -468,8 +468,8 @@ asmlinkage long compat_sys_fcntl64(unsigned int fd, unsigned int cmd,
468 return ret; 468 return ret;
469} 469}
470 470
471asmlinkage long compat_sys_fcntl(unsigned int fd, unsigned int cmd, 471COMPAT_SYSCALL_DEFINE3(fcntl, unsigned int, fd, unsigned int, cmd,
472 unsigned long arg) 472 compat_ulong_t, arg)
473{ 473{
474 if ((cmd == F_GETLK64) || (cmd == F_SETLK64) || (cmd == F_SETLKW64)) 474 if ((cmd == F_GETLK64) || (cmd == F_SETLK64) || (cmd == F_SETLKW64))
475 return -EINVAL; 475 return -EINVAL;
@@ -495,32 +495,24 @@ COMPAT_SYSCALL_DEFINE2(io_setup, unsigned, nr_reqs, u32 __user *, ctx32p)
495 return ret; 495 return ret;
496} 496}
497 497
498asmlinkage long 498COMPAT_SYSCALL_DEFINE5(io_getevents, compat_aio_context_t, ctx_id,
499compat_sys_io_getevents(aio_context_t ctx_id, 499 compat_long_t, min_nr,
500 unsigned long min_nr, 500 compat_long_t, nr,
501 unsigned long nr, 501 struct io_event __user *, events,
502 struct io_event __user *events, 502 struct compat_timespec __user *, timeout)
503 struct compat_timespec __user *timeout)
504{ 503{
505 long ret;
506 struct timespec t; 504 struct timespec t;
507 struct timespec __user *ut = NULL; 505 struct timespec __user *ut = NULL;
508 506
509 ret = -EFAULT;
510 if (unlikely(!access_ok(VERIFY_WRITE, events,
511 nr * sizeof(struct io_event))))
512 goto out;
513 if (timeout) { 507 if (timeout) {
514 if (get_compat_timespec(&t, timeout)) 508 if (get_compat_timespec(&t, timeout))
515 goto out; 509 return -EFAULT;
516 510
517 ut = compat_alloc_user_space(sizeof(*ut)); 511 ut = compat_alloc_user_space(sizeof(*ut));
518 if (copy_to_user(ut, &t, sizeof(t)) ) 512 if (copy_to_user(ut, &t, sizeof(t)) )
519 goto out; 513 return -EFAULT;
520 } 514 }
521 ret = sys_io_getevents(ctx_id, min_nr, nr, events, ut); 515 return sys_io_getevents(ctx_id, min_nr, nr, events, ut);
522out:
523 return ret;
524} 516}
525 517
526/* A write operation does a read from user space and vice versa */ 518/* A write operation does a read from user space and vice versa */
@@ -616,8 +608,8 @@ copy_iocb(long nr, u32 __user *ptr32, struct iocb __user * __user *ptr64)
616 608
617#define MAX_AIO_SUBMITS (PAGE_SIZE/sizeof(struct iocb *)) 609#define MAX_AIO_SUBMITS (PAGE_SIZE/sizeof(struct iocb *))
618 610
619asmlinkage long 611COMPAT_SYSCALL_DEFINE3(io_submit, compat_aio_context_t, ctx_id,
620compat_sys_io_submit(aio_context_t ctx_id, int nr, u32 __user *iocb) 612 int, nr, u32 __user *, iocb)
621{ 613{
622 struct iocb __user * __user *iocb64; 614 struct iocb __user * __user *iocb64;
623 long ret; 615 long ret;
@@ -769,10 +761,10 @@ static int do_nfs4_super_data_conv(void *raw_data)
769#define NCPFS_NAME "ncpfs" 761#define NCPFS_NAME "ncpfs"
770#define NFS4_NAME "nfs4" 762#define NFS4_NAME "nfs4"
771 763
772asmlinkage long compat_sys_mount(const char __user * dev_name, 764COMPAT_SYSCALL_DEFINE5(mount, const char __user *, dev_name,
773 const char __user * dir_name, 765 const char __user *, dir_name,
774 const char __user * type, unsigned long flags, 766 const char __user *, type, compat_ulong_t, flags,
775 const void __user * data) 767 const void __user *, data)
776{ 768{
777 char *kernel_type; 769 char *kernel_type;
778 unsigned long data_page; 770 unsigned long data_page;
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index 3881610b6438..e82289047272 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -1538,9 +1538,10 @@ static int compat_ioctl_check_table(unsigned int xcmd)
1538 return ioctl_pointer[i] == xcmd; 1538 return ioctl_pointer[i] == xcmd;
1539} 1539}
1540 1540
1541asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd, 1541COMPAT_SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd,
1542 unsigned long arg) 1542 compat_ulong_t, arg32)
1543{ 1543{
1544 unsigned long arg = arg32;
1544 struct fd f = fdget(fd); 1545 struct fd f = fdget(fd);
1545 int error = -EBADF; 1546 int error = -EBADF;
1546 if (!f.file) 1547 if (!f.file)
diff --git a/include/linux/compat.h b/include/linux/compat.h
index 1c457428ec0a..fea8ee9afe22 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -71,6 +71,8 @@ typedef struct compat_sigaltstack {
71typedef __compat_uid32_t compat_uid_t; 71typedef __compat_uid32_t compat_uid_t;
72typedef __compat_gid32_t compat_gid_t; 72typedef __compat_gid32_t compat_gid_t;
73 73
74typedef compat_ulong_t compat_aio_context_t;
75
74struct compat_sel_arg_struct; 76struct compat_sel_arg_struct;
75struct rusage; 77struct rusage;
76 78
@@ -497,20 +499,20 @@ asmlinkage long compat_sys_statfs64(const char __user *pathname,
497asmlinkage long compat_sys_fstatfs64(unsigned int fd, compat_size_t sz, 499asmlinkage long compat_sys_fstatfs64(unsigned int fd, compat_size_t sz,
498 struct compat_statfs64 __user *buf); 500 struct compat_statfs64 __user *buf);
499asmlinkage long compat_sys_fcntl64(unsigned int fd, unsigned int cmd, 501asmlinkage long compat_sys_fcntl64(unsigned int fd, unsigned int cmd,
500 unsigned long arg); 502 compat_ulong_t arg);
501asmlinkage long compat_sys_fcntl(unsigned int fd, unsigned int cmd, 503asmlinkage long compat_sys_fcntl(unsigned int fd, unsigned int cmd,
502 unsigned long arg); 504 compat_ulong_t arg);
503asmlinkage long compat_sys_io_setup(unsigned nr_reqs, u32 __user *ctx32p); 505asmlinkage long compat_sys_io_setup(unsigned nr_reqs, u32 __user *ctx32p);
504asmlinkage long compat_sys_io_getevents(aio_context_t ctx_id, 506asmlinkage long compat_sys_io_getevents(compat_aio_context_t ctx_id,
505 unsigned long min_nr, 507 compat_long_t min_nr,
506 unsigned long nr, 508 compat_long_t nr,
507 struct io_event __user *events, 509 struct io_event __user *events,
508 struct compat_timespec __user *timeout); 510 struct compat_timespec __user *timeout);
509asmlinkage long compat_sys_io_submit(aio_context_t ctx_id, int nr, 511asmlinkage long compat_sys_io_submit(compat_aio_context_t ctx_id, int nr,
510 u32 __user *iocb); 512 u32 __user *iocb);
511asmlinkage long compat_sys_mount(const char __user *dev_name, 513asmlinkage long compat_sys_mount(const char __user *dev_name,
512 const char __user *dir_name, 514 const char __user *dir_name,
513 const char __user *type, unsigned long flags, 515 const char __user *type, compat_ulong_t flags,
514 const void __user *data); 516 const void __user *data);
515asmlinkage long compat_sys_old_readdir(unsigned int fd, 517asmlinkage long compat_sys_old_readdir(unsigned int fd,
516 struct compat_old_linux_dirent __user *, 518 struct compat_old_linux_dirent __user *,
@@ -633,7 +635,7 @@ asmlinkage long compat_sys_rt_sigqueueinfo(compat_pid_t pid, int sig,
633 struct compat_siginfo __user *uinfo); 635 struct compat_siginfo __user *uinfo);
634asmlinkage long compat_sys_sysinfo(struct compat_sysinfo __user *info); 636asmlinkage long compat_sys_sysinfo(struct compat_sysinfo __user *info);
635asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd, 637asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd,
636 unsigned long arg); 638 compat_ulong_t arg);
637asmlinkage long compat_sys_futex(u32 __user *uaddr, int op, u32 val, 639asmlinkage long compat_sys_futex(u32 __user *uaddr, int op, u32 val,
638 struct compat_timespec __user *utime, u32 __user *uaddr2, 640 struct compat_timespec __user *utime, u32 __user *uaddr2,
639 u32 val3); 641 u32 val3);