diff options
author | Helge Deller | 2013-02-19 20:47:37 +0100 |
---|---|---|
committer | Helge Deller | 2013-02-20 22:56:50 +0100 |
commit | bf581e15a443fa3569d9def96b512315ba509d6f (patch) | |
tree | 248e7bce3b05c4867d33df9f96d844a78a03e654 | |
parent | fee707b459da56ba83fbb4ae89151571502ee724 (diff) |
parisc: convert msgrcv and msgsnd syscalls to use compat layer
Switch over to use the existing compat_* implementation for msgrcv() and
msgsnd(). Existing code was even partly buggy since it returned on some paths
different error codes than the standard.
Signed-off-by: Helge Deller <deller@gmx.de>
-rw-r--r-- | arch/parisc/Kconfig | 4 | ||||
-rw-r--r-- | arch/parisc/include/asm/compat.h | 61 | ||||
-rw-r--r-- | arch/parisc/kernel/sys_parisc32.c | 58 | ||||
-rw-r--r-- | arch/parisc/kernel/syscall_table.S | 4 |
4 files changed, 67 insertions, 60 deletions
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index 3df1c35a217a..af48d26ce287 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig @@ -272,6 +272,10 @@ config COMPAT def_bool y depends on 64BIT +config SYSVIPC_COMPAT + def_bool y + depends on COMPAT && SYSVIPC + config HPUX bool "Support for HP-UX binaries" depends on !64BIT diff --git a/arch/parisc/include/asm/compat.h b/arch/parisc/include/asm/compat.h index db7a662691a8..94710cfc1ce8 100644 --- a/arch/parisc/include/asm/compat.h +++ b/arch/parisc/include/asm/compat.h @@ -28,6 +28,7 @@ typedef u16 compat_nlink_t; typedef u16 compat_ipc_pid_t; typedef s32 compat_daddr_t; typedef u32 compat_caddr_t; +typedef s32 compat_key_t; typedef s32 compat_timer_t; typedef s32 compat_int_t; @@ -188,6 +189,66 @@ typedef struct compat_siginfo { #define COMPAT_OFF_T_MAX 0x7fffffff #define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL +struct compat_ipc64_perm { + compat_key_t key; + __compat_uid_t uid; + __compat_gid_t gid; + __compat_uid_t cuid; + __compat_gid_t cgid; + unsigned short int __pad1; + compat_mode_t mode; + unsigned short int __pad2; + unsigned short int seq; + unsigned int __pad3; + unsigned long __unused1; /* yes they really are 64bit pads */ + unsigned long __unused2; +}; + +struct compat_semid64_ds { + struct compat_ipc64_perm sem_perm; + compat_time_t sem_otime; + unsigned int __unused1; + compat_time_t sem_ctime; + unsigned int __unused2; + compat_ulong_t sem_nsems; + compat_ulong_t __unused3; + compat_ulong_t __unused4; +}; + +struct compat_msqid64_ds { + struct compat_ipc64_perm msg_perm; + unsigned int __unused1; + compat_time_t msg_stime; + unsigned int __unused2; + compat_time_t msg_rtime; + unsigned int __unused3; + compat_time_t msg_ctime; + compat_ulong_t msg_cbytes; + compat_ulong_t msg_qnum; + compat_ulong_t msg_qbytes; + compat_pid_t msg_lspid; + compat_pid_t msg_lrpid; + compat_ulong_t __unused4; + compat_ulong_t __unused5; +}; + +struct compat_shmid64_ds { + struct compat_ipc64_perm shm_perm; + unsigned int __unused1; + compat_time_t shm_atime; + unsigned int __unused2; + compat_time_t shm_dtime; + unsigned int __unused3; + compat_time_t shm_ctime; + unsigned int __unused4; + compat_size_t shm_segsz; + compat_pid_t shm_cpid; + compat_pid_t shm_lpid; + compat_ulong_t shm_nattch; + compat_ulong_t __unused5; + compat_ulong_t __unused6; +}; + /* * A pointer passed in from user mode. This should not * be used for syscall parameters, just declare them diff --git a/arch/parisc/kernel/sys_parisc32.c b/arch/parisc/kernel/sys_parisc32.c index 9cfdaa19ab63..cee60f77fc1f 100644 --- a/arch/parisc/kernel/sys_parisc32.c +++ b/arch/parisc/kernel/sys_parisc32.c @@ -21,7 +21,6 @@ #include <linux/time.h> #include <linux/smp.h> #include <linux/sem.h> -#include <linux/msg.h> #include <linux/shm.h> #include <linux/slab.h> #include <linux/uio.h> @@ -73,63 +72,6 @@ asmlinkage long sys32_sched_rr_get_interval(pid_t pid, return ret; } -struct msgbuf32 { - int mtype; - char mtext[1]; -}; - -asmlinkage long sys32_msgsnd(int msqid, - struct msgbuf32 __user *umsgp32, - size_t msgsz, int msgflg) -{ - struct msgbuf *mb; - struct msgbuf32 mb32; - int err; - - if ((mb = kmalloc(msgsz + sizeof *mb + 4, GFP_KERNEL)) == NULL) - return -ENOMEM; - - err = get_user(mb32.mtype, &umsgp32->mtype); - mb->mtype = mb32.mtype; - err |= copy_from_user(mb->mtext, &umsgp32->mtext, msgsz); - - if (err) - err = -EFAULT; - else - KERNEL_SYSCALL(err, sys_msgsnd, msqid, (struct msgbuf __user *)mb, msgsz, msgflg); - - kfree(mb); - return err; -} - -asmlinkage long sys32_msgrcv(int msqid, - struct msgbuf32 __user *umsgp32, - size_t msgsz, long msgtyp, int msgflg) -{ - struct msgbuf *mb; - struct msgbuf32 mb32; - int err, len; - - if ((mb = kmalloc(msgsz + sizeof *mb + 4, GFP_KERNEL)) == NULL) - return -ENOMEM; - - KERNEL_SYSCALL(err, sys_msgrcv, msqid, (struct msgbuf __user *)mb, msgsz, msgtyp, msgflg); - - if (err >= 0) { - len = err; - mb32.mtype = mb->mtype; - err = put_user(mb32.mtype, &umsgp32->mtype); - err |= copy_to_user(&umsgp32->mtext, mb->mtext, len); - if (err) - err = -EFAULT; - else - err = len; - } - - kfree(mb); - return err; -} - asmlinkage int sys32_sendfile(int out_fd, int in_fd, compat_off_t __user *offset, s32 count) { mm_segment_t old_fs = get_fs(); diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S index e5fcd4c605e2..773b4ee1e1d3 100644 --- a/arch/parisc/kernel/syscall_table.S +++ b/arch/parisc/kernel/syscall_table.S @@ -286,8 +286,8 @@ ENTRY_SAME(semop) /* 185 */ ENTRY_SAME(semget) ENTRY_DIFF(semctl) - ENTRY_DIFF(msgsnd) - ENTRY_DIFF(msgrcv) + ENTRY_COMP(msgsnd) + ENTRY_COMP(msgrcv) ENTRY_SAME(msgget) /* 190 */ ENTRY_SAME(msgctl) ENTRY_SAME(shmat) |