fs/compat: convert to COMPAT_SYSCALL_DEFINE with changing parameter types
authorHeiko Carstens <heiko.carstens@de.ibm.com>
Tue, 4 Mar 2014 15:07:52 +0000 (16:07 +0100)
committerHeiko Carstens <heiko.carstens@de.ibm.com>
Thu, 6 Mar 2014 15:30:44 +0000 (16:30 +0100)
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>
arch/s390/include/asm/compat.h
fs/compat.c
fs/compat_ioctl.c
include/linux/compat.h

index 1174ea2b5e7c6bacb0fc849ad7ba3a6380e384c9..5d7e8cf83bd6c7d53b5f2a34fc2120add4cfa2d8 100644 (file)
@@ -65,7 +65,6 @@ typedef u32           compat_caddr_t;
 typedef __kernel_fsid_t        compat_fsid_t;
 typedef s32            compat_key_t;
 typedef s32            compat_timer_t;
-typedef u32            compat_aio_context_t;
 
 typedef s32            compat_int_t;
 typedef s32            compat_long_t;
index 6d8312b7a51dc8fd3793797260c340616def5406..19252b97f0cc9662940c2782c76e6782c7fa787a 100644 (file)
@@ -399,8 +399,8 @@ static int put_compat_flock64(struct flock *kfl, struct compat_flock64 __user *u
 }
 #endif
 
-asmlinkage long compat_sys_fcntl64(unsigned int fd, unsigned int cmd,
-               unsigned long arg)
+COMPAT_SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd,
+                      compat_ulong_t, arg)
 {
        mm_segment_t old_fs;
        struct flock f;
@@ -468,8 +468,8 @@ asmlinkage long compat_sys_fcntl64(unsigned int fd, unsigned int cmd,
        return ret;
 }
 
-asmlinkage long compat_sys_fcntl(unsigned int fd, unsigned int cmd,
-               unsigned long arg)
+COMPAT_SYSCALL_DEFINE3(fcntl, unsigned int, fd, unsigned int, cmd,
+                      compat_ulong_t, arg)
 {
        if ((cmd == F_GETLK64) || (cmd == F_SETLK64) || (cmd == F_SETLKW64))
                return -EINVAL;
@@ -495,32 +495,24 @@ COMPAT_SYSCALL_DEFINE2(io_setup, unsigned, nr_reqs, u32 __user *, ctx32p)
        return ret;
 }
 
-asmlinkage long
-compat_sys_io_getevents(aio_context_t ctx_id,
-                                unsigned long min_nr,
-                                unsigned long nr,
-                                struct io_event __user *events,
-                                struct compat_timespec __user *timeout)
+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)
 {
-       long ret;
        struct timespec t;
        struct timespec __user *ut = NULL;
 
-       ret = -EFAULT;
-       if (unlikely(!access_ok(VERIFY_WRITE, events, 
-                               nr * sizeof(struct io_event))))
-               goto out;
        if (timeout) {
                if (get_compat_timespec(&t, timeout))
-                       goto out;
+                       return -EFAULT;
 
                ut = compat_alloc_user_space(sizeof(*ut));
                if (copy_to_user(ut, &t, sizeof(t)) )
-                       goto out;
+                       return -EFAULT;
        } 
-       ret = sys_io_getevents(ctx_id, min_nr, nr, events, ut);
-out:
-       return ret;
+       return sys_io_getevents(ctx_id, min_nr, nr, events, ut);
 }
 
 /* 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)
 
 #define MAX_AIO_SUBMITS        (PAGE_SIZE/sizeof(struct iocb *))
 
-asmlinkage long
-compat_sys_io_submit(aio_context_t ctx_id, int nr, u32 __user *iocb)
+COMPAT_SYSCALL_DEFINE3(io_submit, compat_aio_context_t, ctx_id,
+                      int, nr, u32 __user *, iocb)
 {
        struct iocb __user * __user *iocb64; 
        long ret;
@@ -769,10 +761,10 @@ static int do_nfs4_super_data_conv(void *raw_data)
 #define NCPFS_NAME      "ncpfs"
 #define NFS4_NAME      "nfs4"
 
-asmlinkage long compat_sys_mount(const char __user * dev_name,
-                                const char __user * dir_name,
-                                const char __user * type, unsigned long flags,
-                                const void __user * data)
+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)
 {
        char *kernel_type;
        unsigned long data_page;
index 3881610b64384cee634367c3c35d237a4fa2f2aa..e82289047272d6e636583e20969f59450987da05 100644 (file)
@@ -1538,9 +1538,10 @@ static int compat_ioctl_check_table(unsigned int xcmd)
        return ioctl_pointer[i] == xcmd;
 }
 
-asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd,
-                               unsigned long arg)
+COMPAT_SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd,
+                      compat_ulong_t, arg32)
 {
+       unsigned long arg = arg32;
        struct fd f = fdget(fd);
        int error = -EBADF;
        if (!f.file)
index 1c457428ec0afe5865b2ea616c27fa1d8f2fded6..fea8ee9afe2220ba3b0044ead83a1e311ea87855 100644 (file)
@@ -71,6 +71,8 @@ typedef struct compat_sigaltstack {
 typedef __compat_uid32_t       compat_uid_t;
 typedef __compat_gid32_t       compat_gid_t;
 
+typedef        compat_ulong_t          compat_aio_context_t;
+
 struct compat_sel_arg_struct;
 struct rusage;
 
@@ -497,20 +499,20 @@ asmlinkage long compat_sys_statfs64(const char __user *pathname,
 asmlinkage long compat_sys_fstatfs64(unsigned int fd, compat_size_t sz,
                                     struct compat_statfs64 __user *buf);
 asmlinkage long compat_sys_fcntl64(unsigned int fd, unsigned int cmd,
-                                  unsigned long arg);
+                                  compat_ulong_t arg);
 asmlinkage long compat_sys_fcntl(unsigned int fd, unsigned int cmd,
-                                unsigned long arg);
+                                compat_ulong_t arg);
 asmlinkage long compat_sys_io_setup(unsigned nr_reqs, u32 __user *ctx32p);
-asmlinkage long compat_sys_io_getevents(aio_context_t ctx_id,
-                                       unsigned long min_nr,
-                                       unsigned long nr,
+asmlinkage long compat_sys_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);
-asmlinkage long compat_sys_io_submit(aio_context_t ctx_id, int nr,
+asmlinkage long compat_sys_io_submit(compat_aio_context_t ctx_id, int nr,
                                     u32 __user *iocb);
 asmlinkage long compat_sys_mount(const char __user *dev_name,
                                 const char __user *dir_name,
-                                const char __user *type, unsigned long flags,
+                                const char __user *type, compat_ulong_t flags,
                                 const void __user *data);
 asmlinkage long compat_sys_old_readdir(unsigned int fd,
                                       struct compat_old_linux_dirent __user *,
@@ -633,7 +635,7 @@ asmlinkage long compat_sys_rt_sigqueueinfo(compat_pid_t pid, int sig,
                                struct compat_siginfo __user *uinfo);
 asmlinkage long compat_sys_sysinfo(struct compat_sysinfo __user *info);
 asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd,
-                                unsigned long arg);
+                                compat_ulong_t arg);
 asmlinkage long compat_sys_futex(u32 __user *uaddr, int op, u32 val,
                struct compat_timespec __user *utime, u32 __user *uaddr2,
                u32 val3);