From 4294a8eedb17bbc45e1e7447c2a4d05332943248 Mon Sep 17 00:00:00 2001 From: André Goddard Rosa Date: Tue, 23 Feb 2010 04:04:28 -0300 Subject: mqueue: fix mq_open() file descriptor leak on user-space processes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We leak fd on lookup_one_len() failure Signed-off-by: André Goddard Rosa Signed-off-by: Al Viro --- ipc/mqueue.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'ipc') diff --git a/ipc/mqueue.c b/ipc/mqueue.c index c79bd57353e7..04985a7256c2 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c @@ -705,7 +705,7 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, mode_t, mode, dentry = lookup_one_len(name, ipc_ns->mq_mnt->mnt_root, strlen(name)); if (IS_ERR(dentry)) { error = PTR_ERR(dentry); - goto out_err; + goto out_putfd; } mntget(ipc_ns->mq_mnt); @@ -742,7 +742,6 @@ out: mntput(ipc_ns->mq_mnt); out_putfd: put_unused_fd(fd); -out_err: fd = error; out_upsem: mutex_unlock(&ipc_ns->mq_mnt->mnt_root->d_inode->i_mutex); -- cgit v1.2.3 From c8308b1c91056b09e96d40dbde4880ea685c377e Mon Sep 17 00:00:00 2001 From: André Goddard Rosa Date: Tue, 23 Feb 2010 04:04:23 -0300 Subject: mqueue: remove unneeded info->messages initialization MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ... and abort earlier if we couldn't allocate the message pointers array, avoiding the u->mq_bytes accounting logic. It reduces code size: text data bss dec hex filename 9949 72 16 10037 2735 ipc/mqueue-BEFORE.o 9941 72 16 10029 272d ipc/mqueue-AFTER.o Signed-off-by: André Goddard Rosa Signed-off-by: Al Viro --- ipc/mqueue.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'ipc') diff --git a/ipc/mqueue.c b/ipc/mqueue.c index 04985a7256c2..3660c334ee6b 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c @@ -134,7 +134,6 @@ static struct inode *mqueue_get_inode(struct super_block *sb, init_waitqueue_head(&info->wait_q); INIT_LIST_HEAD(&info->e_wait_q[0].list); INIT_LIST_HEAD(&info->e_wait_q[1].list); - info->messages = NULL; info->notify_owner = NULL; info->qsize = 0; info->user = NULL; /* set when all is ok */ @@ -146,6 +145,10 @@ static struct inode *mqueue_get_inode(struct super_block *sb, info->attr.mq_msgsize = attr->mq_msgsize; } mq_msg_tblsz = info->attr.mq_maxmsg * sizeof(struct msg_msg *); + info->messages = kmalloc(mq_msg_tblsz, GFP_KERNEL); + if (!info->messages) + goto out_inode; + mq_bytes = (mq_msg_tblsz + (info->attr.mq_maxmsg * info->attr.mq_msgsize)); @@ -154,18 +157,12 @@ static struct inode *mqueue_get_inode(struct super_block *sb, u->mq_bytes + mq_bytes > p->signal->rlim[RLIMIT_MSGQUEUE].rlim_cur) { spin_unlock(&mq_lock); + kfree(info->messages); goto out_inode; } u->mq_bytes += mq_bytes; spin_unlock(&mq_lock); - info->messages = kmalloc(mq_msg_tblsz, GFP_KERNEL); - if (!info->messages) { - spin_lock(&mq_lock); - u->mq_bytes -= mq_bytes; - spin_unlock(&mq_lock); - goto out_inode; - } /* all is ok */ info->user = get_uid(u); } else if (S_ISDIR(mode)) { -- cgit v1.2.3 From 8834cf796a4320be2d3a70b1e4f9aba732a0f4ee Mon Sep 17 00:00:00 2001 From: André Goddard Rosa Date: Tue, 23 Feb 2010 04:04:24 -0300 Subject: mqueue: apply mathematics distributivity on mq_bytes calculation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Code size reduction: text data bss dec hex filename 9941 72 16 10029 272d ipc/mqueue-BEFORE.o 9925 72 16 10013 271d ipc/mqueue-AFTER.o Signed-off-by: André Goddard Rosa Signed-off-by: Al Viro --- ipc/mqueue.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'ipc') diff --git a/ipc/mqueue.c b/ipc/mqueue.c index 3660c334ee6b..15eabf9d51fd 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c @@ -261,8 +261,9 @@ static void mqueue_delete_inode(struct inode *inode) clear_inode(inode); - mq_bytes = (info->attr.mq_maxmsg * sizeof(struct msg_msg *) + - (info->attr.mq_maxmsg * info->attr.mq_msgsize)); + /* Total amount of bytes accounted for the mqueue */ + mq_bytes = info->attr.mq_maxmsg * (sizeof(struct msg_msg *) + + info->attr.mq_msgsize); user = info->user; if (user) { spin_lock(&mq_lock); @@ -601,8 +602,8 @@ static int mq_attr_ok(struct ipc_namespace *ipc_ns, struct mq_attr *attr) /* check for overflow */ if (attr->mq_msgsize > ULONG_MAX/attr->mq_maxmsg) return 0; - if ((unsigned long)(attr->mq_maxmsg * attr->mq_msgsize) + - (attr->mq_maxmsg * sizeof (struct msg_msg *)) < + if ((unsigned long)(attr->mq_maxmsg * (attr->mq_msgsize + + sizeof (struct msg_msg *))) < (unsigned long)(attr->mq_maxmsg * attr->mq_msgsize)) return 0; return 1; -- cgit v1.2.3 From 04db0dde0ee1c29110642dff57fba9e438eb805c Mon Sep 17 00:00:00 2001 From: André Goddard Rosa Date: Tue, 23 Feb 2010 04:04:25 -0300 Subject: mqueue: simplify do_open() error handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It reduces code size: text data bss dec hex filename 9925 72 16 10013 271d ipc/mqueue-BEFORE.o 9885 72 16 9973 26f5 ipc/mqueue-AFTER.o Signed-off-by: André Goddard Rosa Signed-off-by: Al Viro --- ipc/mqueue.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'ipc') diff --git a/ipc/mqueue.c b/ipc/mqueue.c index 15eabf9d51fd..3853116a2ef8 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c @@ -657,24 +657,28 @@ out: static struct file *do_open(struct ipc_namespace *ipc_ns, struct dentry *dentry, int oflag) { + int ret; const struct cred *cred = current_cred(); static const int oflag2acc[O_ACCMODE] = { MAY_READ, MAY_WRITE, MAY_READ | MAY_WRITE }; if ((oflag & O_ACCMODE) == (O_RDWR | O_WRONLY)) { - dput(dentry); - mntput(ipc_ns->mq_mnt); - return ERR_PTR(-EINVAL); + ret = -EINVAL; + goto err; } if (inode_permission(dentry->d_inode, oflag2acc[oflag & O_ACCMODE])) { - dput(dentry); - mntput(ipc_ns->mq_mnt); - return ERR_PTR(-EACCES); + ret = -EACCES; + goto err; } return dentry_open(dentry, ipc_ns->mq_mnt, oflag, cred); + +err: + dput(dentry); + mntput(ipc_ns->mq_mnt); + return ERR_PTR(ret); } SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, mode_t, mode, -- cgit v1.2.3 From 8d8ffefaaf63f0468f17fbd1270165e739cf335e Mon Sep 17 00:00:00 2001 From: André Goddard Rosa Date: Tue, 23 Feb 2010 04:04:26 -0300 Subject: mqueue: only set error codes if they are really necessary MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ... postponing assignments until they're needed. Doesn't change code size. Signed-off-by: André Goddard Rosa Signed-off-by: Al Viro --- ipc/mqueue.c | 77 +++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 50 insertions(+), 27 deletions(-) (limited to 'ipc') diff --git a/ipc/mqueue.c b/ipc/mqueue.c index 3853116a2ef8..547d9c8631f5 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c @@ -184,7 +184,7 @@ static int mqueue_fill_super(struct super_block *sb, void *data, int silent) { struct inode *inode; struct ipc_namespace *ns = data; - int error = 0; + int error; sb->s_blocksize = PAGE_CACHE_SIZE; sb->s_blocksize_bits = PAGE_CACHE_SHIFT; @@ -202,7 +202,9 @@ static int mqueue_fill_super(struct super_block *sb, void *data, int silent) if (!sb->s_root) { iput(inode); error = -ENOMEM; + goto out; } + error = 0; out: return error; @@ -621,9 +623,10 @@ static struct file *do_create(struct ipc_namespace *ipc_ns, struct dentry *dir, int ret; if (attr) { - ret = -EINVAL; - if (!mq_attr_ok(ipc_ns, attr)) + if (!mq_attr_ok(ipc_ns, attr)) { + ret = -EINVAL; goto out; + } /* store for use during create */ dentry->d_fsdata = attr; } @@ -714,9 +717,10 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, mode_t, mode, if (oflag & O_CREAT) { if (dentry->d_inode) { /* entry already exists */ audit_inode(name, dentry); - error = -EEXIST; - if (oflag & O_EXCL) + if (oflag & O_EXCL) { + error = -EEXIST; goto out; + } filp = do_open(ipc_ns, dentry, oflag); } else { filp = do_create(ipc_ns, ipc_ns->mq_mnt->mnt_root, @@ -724,9 +728,10 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, mode_t, mode, u_attr ? &attr : NULL); } } else { - error = -ENOENT; - if (!dentry->d_inode) + if (!dentry->d_inode) { + error = -ENOENT; goto out; + } audit_inode(name, dentry); filp = do_open(ipc_ns, dentry, oflag); } @@ -873,19 +878,24 @@ SYSCALL_DEFINE5(mq_timedsend, mqd_t, mqdes, const char __user *, u_msg_ptr, audit_mq_sendrecv(mqdes, msg_len, msg_prio, p); timeout = prepare_timeout(p); - ret = -EBADF; filp = fget(mqdes); - if (unlikely(!filp)) + if (unlikely(!filp)) { + ret = -EBADF; goto out; + } inode = filp->f_path.dentry->d_inode; - if (unlikely(filp->f_op != &mqueue_file_operations)) + if (unlikely(filp->f_op != &mqueue_file_operations)) { + ret = -EBADF; goto out_fput; + } info = MQUEUE_I(inode); audit_inode(NULL, filp->f_path.dentry); - if (unlikely(!(filp->f_mode & FMODE_WRITE))) + if (unlikely(!(filp->f_mode & FMODE_WRITE))) { + ret = -EBADF; goto out_fput; + } if (unlikely(msg_len > info->attr.mq_msgsize)) { ret = -EMSGSIZE; @@ -962,19 +972,24 @@ SYSCALL_DEFINE5(mq_timedreceive, mqd_t, mqdes, char __user *, u_msg_ptr, audit_mq_sendrecv(mqdes, msg_len, 0, p); timeout = prepare_timeout(p); - ret = -EBADF; filp = fget(mqdes); - if (unlikely(!filp)) + if (unlikely(!filp)) { + ret = -EBADF; goto out; + } inode = filp->f_path.dentry->d_inode; - if (unlikely(filp->f_op != &mqueue_file_operations)) + if (unlikely(filp->f_op != &mqueue_file_operations)) { + ret = -EBADF; goto out_fput; + } info = MQUEUE_I(inode); audit_inode(NULL, filp->f_path.dentry); - if (unlikely(!(filp->f_mode & FMODE_READ))) + if (unlikely(!(filp->f_mode & FMODE_READ))) { + ret = -EBADF; goto out_fput; + } /* checks if buffer is big enough */ if (unlikely(msg_len < info->attr.mq_msgsize)) { @@ -1064,13 +1079,14 @@ SYSCALL_DEFINE2(mq_notify, mqd_t, mqdes, /* create the notify skb */ nc = alloc_skb(NOTIFY_COOKIE_LEN, GFP_KERNEL); - ret = -ENOMEM; - if (!nc) + if (!nc) { + ret = -ENOMEM; goto out; - ret = -EFAULT; + } if (copy_from_user(nc->data, notification.sigev_value.sival_ptr, NOTIFY_COOKIE_LEN)) { + ret = -EFAULT; goto out; } @@ -1079,9 +1095,10 @@ SYSCALL_DEFINE2(mq_notify, mqd_t, mqdes, /* and attach it to the socket */ retry: filp = fget(notification.sigev_signo); - ret = -EBADF; - if (!filp) + if (!filp) { + ret = -EBADF; goto out; + } sock = netlink_getsockbyfilp(filp); fput(filp); if (IS_ERR(sock)) { @@ -1093,7 +1110,7 @@ retry: timeo = MAX_SCHEDULE_TIMEOUT; ret = netlink_attachskb(sock, nc, &timeo, NULL); if (ret == 1) - goto retry; + goto retry; if (ret) { sock = NULL; nc = NULL; @@ -1102,14 +1119,17 @@ retry: } } - ret = -EBADF; filp = fget(mqdes); - if (!filp) + if (!filp) { + ret = -EBADF; goto out; + } inode = filp->f_path.dentry->d_inode; - if (unlikely(filp->f_op != &mqueue_file_operations)) + if (unlikely(filp->f_op != &mqueue_file_operations)) { + ret = -EBADF; goto out_fput; + } info = MQUEUE_I(inode); ret = 0; @@ -1172,14 +1192,17 @@ SYSCALL_DEFINE3(mq_getsetattr, mqd_t, mqdes, return -EINVAL; } - ret = -EBADF; filp = fget(mqdes); - if (!filp) + if (!filp) { + ret = -EBADF; goto out; + } inode = filp->f_path.dentry->d_inode; - if (unlikely(filp->f_op != &mqueue_file_operations)) + if (unlikely(filp->f_op != &mqueue_file_operations)) { + ret = -EBADF; goto out_fput; + } info = MQUEUE_I(inode); spin_lock(&info->lock); -- cgit v1.2.3 From 2329e392accdb1b277927e8d9cbf568ba3f3856d Mon Sep 17 00:00:00 2001 From: André Goddard Rosa Date: Tue, 23 Feb 2010 04:04:27 -0300 Subject: mqueue: fix typo "failues" -> "failures" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: André Goddard Rosa Signed-off-by: Al Viro --- ipc/mqueue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ipc') diff --git a/ipc/mqueue.c b/ipc/mqueue.c index 547d9c8631f5..b6cb06451f4b 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c @@ -1296,7 +1296,7 @@ static int __init init_mqueue_fs(void) if (mqueue_inode_cachep == NULL) return -ENOMEM; - /* ignore failues - they are not fatal */ + /* ignore failures - they are not fatal */ mq_sysctl_table = mq_register_sysctl_table(); error = register_filesystem(&mqueue_fs_type); -- cgit v1.2.3 From baed7fc9b580bd3fb8252ff1d9b36eaf1f86b670 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 10 Mar 2010 15:21:18 -0800 Subject: Add generic sys_ipc wrapper Add a generic implementation of the ipc demultiplexer syscall. Except for s390 and sparc64 all implementations of the sys_ipc are nearly identical. There are slight differences in the types of the parameters, where mips and powerpc as the only 64-bit architectures with sys_ipc use unsigned long for the "third" argument as it gets casted to a pointer later, while it traditionally is an "int" like most other paramters. frv goes even further and uses unsigned long for all parameters execept for "ptr" which is a pointer type everywhere. The change from int to unsigned long for "third" and back to "int" for the others on frv should be fine due to the in-register calling conventions for syscalls (we already had a similar issue with the generic sys_ptrace), but I'd prefer to have the arch maintainers looks over this in details. Except for that h8300, m68k and m68knommu lack an impplementation of the semtimedop sub call which this patch adds, and various architectures have gets used - at least on i386 it seems superflous as the compat code on x86-64 and ia64 doesn't even bother to implement it. [akpm@linux-foundation.org: add sys_ipc to sys_ni.c] Signed-off-by: Christoph Hellwig Cc: Ralf Baechle Cc: Benjamin Herrenschmidt Cc: Paul Mundt Cc: Jeff Dike Cc: Hirokazu Takata Cc: Thomas Gleixner Cc: Ingo Molnar Reviewed-by: H. Peter Anvin Cc: Al Viro Cc: Arnd Bergmann Cc: Heiko Carstens Cc: Martin Schwidefsky Cc: "Luck, Tony" Cc: James Morris Cc: Andreas Schwab Acked-by: Jesper Nilsson Acked-by: Russell King Acked-by: David Howells Acked-by: Kyle McMartin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/arm/include/asm/unistd.h | 1 + arch/arm/kernel/sys_arm.c | 82 -------------------------- arch/arm/kernel/sys_oabi-compat.c | 3 - arch/cris/include/asm/unistd.h | 1 + arch/cris/kernel/sys_cris.c | 78 ------------------------- arch/frv/include/asm/unistd.h | 1 + arch/frv/kernel/sys_frv.c | 89 ---------------------------- arch/h8300/include/asm/unistd.h | 1 + arch/h8300/kernel/sys_h8300.c | 88 ---------------------------- arch/m32r/include/asm/unistd.h | 1 + arch/m32r/kernel/sys_m32r.c | 81 -------------------------- arch/m68k/include/asm/unistd.h | 1 + arch/m68k/kernel/sys_m68k.c | 81 -------------------------- arch/m68knommu/kernel/sys_m68k.c | 86 --------------------------- arch/mips/include/asm/unistd.h | 1 + arch/mips/kernel/syscall.c | 88 ---------------------------- arch/mn10300/include/asm/unistd.h | 1 + arch/mn10300/kernel/sys_mn10300.c | 88 ---------------------------- arch/powerpc/include/asm/syscalls.h | 2 - arch/powerpc/include/asm/unistd.h | 1 + arch/powerpc/kernel/syscalls.c | 94 ------------------------------ arch/s390/kernel/entry.h | 2 +- arch/s390/kernel/sys_s390.c | 2 +- arch/s390/kernel/syscalls.S | 2 +- arch/sh/include/asm/syscalls.h | 2 - arch/sh/include/asm/unistd_32.h | 1 + arch/sh/include/asm/unistd_64.h | 1 + arch/sh/kernel/sys_sh.c | 104 --------------------------------- arch/sparc/include/asm/unistd.h | 4 +- arch/sparc/kernel/sys_sparc_32.c | 113 ------------------------------------ arch/sparc/kernel/sys_sparc_64.c | 2 +- arch/sparc/kernel/systbls.h | 2 +- arch/sparc/kernel/systbls_64.S | 2 +- arch/um/sys-i386/syscalls.c | 86 --------------------------- arch/x86/include/asm/syscalls.h | 1 - arch/x86/include/asm/unistd_32.h | 1 + arch/x86/kernel/sys_i386_32.c | 85 --------------------------- include/linux/syscalls.h | 2 + ipc/Makefile | 2 +- ipc/syscall.c | 99 +++++++++++++++++++++++++++++++ kernel/sys_ni.c | 1 + 41 files changed, 124 insertions(+), 1259 deletions(-) create mode 100644 ipc/syscall.c (limited to 'ipc') diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h index e6eeb2d29953..dd2bf53000fe 100644 --- a/arch/arm/include/asm/unistd.h +++ b/arch/arm/include/asm/unistd.h @@ -448,6 +448,7 @@ #if !defined(CONFIG_AEABI) || defined(CONFIG_OABI_COMPAT) #define __ARCH_WANT_SYS_TIME +#define __ARCH_WANT_SYS_IPC #define __ARCH_WANT_SYS_OLDUMOUNT #define __ARCH_WANT_SYS_ALARM #define __ARCH_WANT_SYS_UTIME diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c index a2e0e6f2ea7f..4350f75e578c 100644 --- a/arch/arm/kernel/sys_arm.c +++ b/arch/arm/kernel/sys_arm.c @@ -28,88 +28,6 @@ #include #include -#if !defined(CONFIG_AEABI) || defined(CONFIG_OABI_COMPAT) -/* - * sys_ipc() is the de-multiplexer for the SysV IPC calls.. - * - * This is really horribly ugly. - */ -asmlinkage int sys_ipc(uint call, int first, int second, int third, - void __user *ptr, long fifth) -{ - int version, ret; - - version = call >> 16; /* hack for backward compatibility */ - call &= 0xffff; - - switch (call) { - case SEMOP: - return sys_semtimedop (first, (struct sembuf __user *)ptr, second, NULL); - case SEMTIMEDOP: - return sys_semtimedop(first, (struct sembuf __user *)ptr, second, - (const struct timespec __user *)fifth); - - case SEMGET: - return sys_semget (first, second, third); - case SEMCTL: { - union semun fourth; - if (!ptr) - return -EINVAL; - if (get_user(fourth.__pad, (void __user * __user *) ptr)) - return -EFAULT; - return sys_semctl (first, second, third, fourth); - } - - case MSGSND: - return sys_msgsnd(first, (struct msgbuf __user *) ptr, - second, third); - case MSGRCV: - switch (version) { - case 0: { - struct ipc_kludge tmp; - if (!ptr) - return -EINVAL; - if (copy_from_user(&tmp,(struct ipc_kludge __user *)ptr, - sizeof (tmp))) - return -EFAULT; - return sys_msgrcv (first, tmp.msgp, second, - tmp.msgtyp, third); - } - default: - return sys_msgrcv (first, - (struct msgbuf __user *) ptr, - second, fifth, third); - } - case MSGGET: - return sys_msgget ((key_t) first, second); - case MSGCTL: - return sys_msgctl(first, second, (struct msqid_ds __user *)ptr); - - case SHMAT: - switch (version) { - default: { - ulong raddr; - ret = do_shmat(first, (char __user *)ptr, second, &raddr); - if (ret) - return ret; - return put_user(raddr, (ulong __user *)third); - } - case 1: /* Of course, we don't support iBCS2! */ - return -EINVAL; - } - case SHMDT: - return sys_shmdt ((char __user *)ptr); - case SHMGET: - return sys_shmget (first, second, third); - case SHMCTL: - return sys_shmctl (first, second, - (struct shmid_ds __user *) ptr); - default: - return -ENOSYS; - } -} -#endif - /* Fork a new task - this creates a new program thread. * This is called indirectly via a small wrapper */ diff --git a/arch/arm/kernel/sys_oabi-compat.c b/arch/arm/kernel/sys_oabi-compat.c index d59a0cd537f0..33ff678e32f2 100644 --- a/arch/arm/kernel/sys_oabi-compat.c +++ b/arch/arm/kernel/sys_oabi-compat.c @@ -346,9 +346,6 @@ asmlinkage long sys_oabi_semop(int semid, struct oabi_sembuf __user *tsops, return sys_oabi_semtimedop(semid, tsops, nsops, NULL); } -extern asmlinkage int sys_ipc(uint call, int first, int second, int third, - void __user *ptr, long fifth); - asmlinkage int sys_oabi_ipc(uint call, int first, int second, int third, void __user *ptr, long fifth) { diff --git a/arch/cris/include/asm/unistd.h b/arch/cris/include/asm/unistd.h index 8cffd22623fd..f6fad83b3a8c 100644 --- a/arch/cris/include/asm/unistd.h +++ b/arch/cris/include/asm/unistd.h @@ -352,6 +352,7 @@ #define __ARCH_WANT_STAT64 #define __ARCH_WANT_SYS_ALARM #define __ARCH_WANT_SYS_GETHOSTNAME +#define __ARCH_WANT_SYS_IPC #define __ARCH_WANT_SYS_PAUSE #define __ARCH_WANT_SYS_SGETMASK #define __ARCH_WANT_SYS_SIGNAL diff --git a/arch/cris/kernel/sys_cris.c b/arch/cris/kernel/sys_cris.c index 22f9d6cd947f..7aa036ec78ff 100644 --- a/arch/cris/kernel/sys_cris.c +++ b/arch/cris/kernel/sys_cris.c @@ -33,81 +33,3 @@ sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot, /* bug(?): 8Kb pages here */ return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff); } - -/* - * sys_ipc() is the de-multiplexer for the SysV IPC calls.. - * - * This is really horribly ugly. (same as arch/i386) - */ - -asmlinkage int sys_ipc (uint call, int first, int second, - int third, void __user *ptr, long fifth) -{ - int version, ret; - - version = call >> 16; /* hack for backward compatibility */ - call &= 0xffff; - - switch (call) { - case SEMOP: - return sys_semtimedop (first, (struct sembuf __user *)ptr, second, NULL); - case SEMTIMEDOP: - return sys_semtimedop(first, (struct sembuf __user *)ptr, second, - (const struct timespec __user *)fifth); - - case SEMGET: - return sys_semget (first, second, third); - case SEMCTL: { - union semun fourth; - if (!ptr) - return -EINVAL; - if (get_user(fourth.__pad, (void * __user *) ptr)) - return -EFAULT; - return sys_semctl (first, second, third, fourth); - } - - case MSGSND: - return sys_msgsnd (first, (struct msgbuf __user *) ptr, - second, third); - case MSGRCV: - switch (version) { - case 0: { - struct ipc_kludge tmp; - if (!ptr) - return -EINVAL; - - if (copy_from_user(&tmp, - (struct ipc_kludge __user *) ptr, - sizeof (tmp))) - return -EFAULT; - return sys_msgrcv (first, tmp.msgp, second, - tmp.msgtyp, third); - } - default: - return sys_msgrcv (first, - (struct msgbuf __user *) ptr, - second, fifth, third); - } - case MSGGET: - return sys_msgget ((key_t) first, second); - case MSGCTL: - return sys_msgctl (first, second, (struct msqid_ds __user *) ptr); - - case SHMAT: { - ulong raddr; - ret = do_shmat (first, (char __user *) ptr, second, &raddr); - if (ret) - return ret; - return put_user (raddr, (ulong __user *) third); - } - case SHMDT: - return sys_shmdt ((char __user *)ptr); - case SHMGET: - return sys_shmget (first, second, third); - case SHMCTL: - return sys_shmctl (first, second, - (struct shmid_ds __user *) ptr); - default: - return -ENOSYS; - } -} diff --git a/arch/frv/include/asm/unistd.h b/arch/frv/include/asm/unistd.h index be6ef0f5cd42..b28da499e22a 100644 --- a/arch/frv/include/asm/unistd.h +++ b/arch/frv/include/asm/unistd.h @@ -354,6 +354,7 @@ #define __ARCH_WANT_STAT64 #define __ARCH_WANT_SYS_ALARM /* #define __ARCH_WANT_SYS_GETHOSTNAME */ +#define __ARCH_WANT_SYS_IPC #define __ARCH_WANT_SYS_PAUSE /* #define __ARCH_WANT_SYS_SGETMASK */ /* #define __ARCH_WANT_SYS_SIGNAL */ diff --git a/arch/frv/kernel/sys_frv.c b/arch/frv/kernel/sys_frv.c index 1d3d4c9e2521..9c4980825bbb 100644 --- a/arch/frv/kernel/sys_frv.c +++ b/arch/frv/kernel/sys_frv.c @@ -42,92 +42,3 @@ asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff >> (PAGE_SHIFT - 12)); } - -/* - * sys_ipc() is the de-multiplexer for the SysV IPC calls.. - * - * This is really horribly ugly. - */ -asmlinkage long sys_ipc(unsigned long call, - unsigned long first, - unsigned long second, - unsigned long third, - void __user *ptr, - unsigned long fifth) -{ - int version, ret; - - version = call >> 16; /* hack for backward compatibility */ - call &= 0xffff; - - switch (call) { - case SEMOP: - return sys_semtimedop(first, (struct sembuf __user *)ptr, second, NULL); - case SEMTIMEDOP: - return sys_semtimedop(first, (struct sembuf __user *)ptr, second, - (const struct timespec __user *)fifth); - - case SEMGET: - return sys_semget (first, second, third); - case SEMCTL: { - union semun fourth; - if (!ptr) - return -EINVAL; - if (get_user(fourth.__pad, (void * __user *) ptr)) - return -EFAULT; - return sys_semctl (first, second, third, fourth); - } - - case MSGSND: - return sys_msgsnd (first, (struct msgbuf __user *) ptr, - second, third); - case MSGRCV: - switch (version) { - case 0: { - struct ipc_kludge tmp; - if (!ptr) - return -EINVAL; - - if (copy_from_user(&tmp, - (struct ipc_kludge __user *) ptr, - sizeof (tmp))) - return -EFAULT; - return sys_msgrcv (first, tmp.msgp, second, - tmp.msgtyp, third); - } - default: - return sys_msgrcv (first, - (struct msgbuf __user *) ptr, - second, fifth, third); - } - case MSGGET: - return sys_msgget ((key_t) first, second); - case MSGCTL: - return sys_msgctl (first, second, (struct msqid_ds __user *) ptr); - - case SHMAT: - switch (version) { - default: { - ulong raddr; - ret = do_shmat (first, (char __user *) ptr, second, &raddr); - if (ret) - return ret; - return put_user (raddr, (ulong __user *) third); - } - case 1: /* iBCS2 emulator entry point */ - if (!segment_eq(get_fs(), get_ds())) - return -EINVAL; - /* The "(ulong *) third" is valid _only_ because of the kernel segment thing */ - return do_shmat (first, (char __user *) ptr, second, (ulong *) third); - } - case SHMDT: - return sys_shmdt ((char __user *)ptr); - case SHMGET: - return sys_shmget (first, second, third); - case SHMCTL: - return sys_shmctl (first, second, - (struct shmid_ds __user *) ptr); - default: - return -ENOSYS; - } -} diff --git a/arch/h8300/include/asm/unistd.h b/arch/h8300/include/asm/unistd.h index 54dab4726954..50f2c5a36591 100644 --- a/arch/h8300/include/asm/unistd.h +++ b/arch/h8300/include/asm/unistd.h @@ -336,6 +336,7 @@ #define __ARCH_WANT_STAT64 #define __ARCH_WANT_SYS_ALARM #define __ARCH_WANT_SYS_GETHOSTNAME +#define __ARCH_WANT_SYS_IPC #define __ARCH_WANT_SYS_PAUSE #define __ARCH_WANT_SYS_SGETMASK #define __ARCH_WANT_SYS_SIGNAL diff --git a/arch/h8300/kernel/sys_h8300.c b/arch/h8300/kernel/sys_h8300.c index 1f13fd6e5309..f9b3f44da69f 100644 --- a/arch/h8300/kernel/sys_h8300.c +++ b/arch/h8300/kernel/sys_h8300.c @@ -26,94 +26,6 @@ #include #include -/* - * sys_ipc() is the de-multiplexer for the SysV IPC calls.. - * - * This is really horribly ugly. - */ -asmlinkage int sys_ipc (uint call, int first, int second, - int third, void *ptr, long fifth) -{ - int version, ret; - - version = call >> 16; /* hack for backward compatibility */ - call &= 0xffff; - - if (call <= SEMCTL) - switch (call) { - case SEMOP: - return sys_semop (first, (struct sembuf *)ptr, second); - case SEMGET: - return sys_semget (first, second, third); - case SEMCTL: { - union semun fourth; - if (!ptr) - return -EINVAL; - if (get_user(fourth.__pad, (void **) ptr)) - return -EFAULT; - return sys_semctl (first, second, third, fourth); - } - default: - return -EINVAL; - } - if (call <= MSGCTL) - switch (call) { - case MSGSND: - return sys_msgsnd (first, (struct msgbuf *) ptr, - second, third); - case MSGRCV: - switch (version) { - case 0: { - struct ipc_kludge tmp; - if (!ptr) - return -EINVAL; - if (copy_from_user (&tmp, - (struct ipc_kludge *)ptr, - sizeof (tmp))) - return -EFAULT; - return sys_msgrcv (first, tmp.msgp, second, - tmp.msgtyp, third); - } - default: - return sys_msgrcv (first, - (struct msgbuf *) ptr, - second, fifth, third); - } - case MSGGET: - return sys_msgget ((key_t) first, second); - case MSGCTL: - return sys_msgctl (first, second, - (struct msqid_ds *) ptr); - default: - return -EINVAL; - } - if (call <= SHMCTL) - switch (call) { - case SHMAT: - switch (version) { - default: { - ulong raddr; - ret = do_shmat (first, (char *) ptr, - second, &raddr); - if (ret) - return ret; - return put_user (raddr, (ulong *) third); - } - } - case SHMDT: - return sys_shmdt ((char *)ptr); - case SHMGET: - return sys_shmget (first, second, third); - case SHMCTL: - return sys_shmctl (first, second, - (struct shmid_ds *) ptr); - default: - return -EINVAL; - } - - return -EINVAL; -} - /* sys_cacheflush -- no support. */ asmlinkage int sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len) diff --git a/arch/m32r/include/asm/unistd.h b/arch/m32r/include/asm/unistd.h index cf701c933249..76125777483c 100644 --- a/arch/m32r/include/asm/unistd.h +++ b/arch/m32r/include/asm/unistd.h @@ -339,6 +339,7 @@ #define __ARCH_WANT_STAT64 #define __ARCH_WANT_SYS_ALARM #define __ARCH_WANT_SYS_GETHOSTNAME +#define __ARCH_WANT_SYS_IPC #define __ARCH_WANT_SYS_PAUSE #define __ARCH_WANT_SYS_TIME #define __ARCH_WANT_SYS_UTIME diff --git a/arch/m32r/kernel/sys_m32r.c b/arch/m32r/kernel/sys_m32r.c index d3c865c5a6ba..cf2e7279ce9b 100644 --- a/arch/m32r/kernel/sys_m32r.c +++ b/arch/m32r/kernel/sys_m32r.c @@ -76,87 +76,6 @@ asmlinkage int sys_tas(int __user *addr) return oldval; } -/* - * sys_ipc() is the de-multiplexer for the SysV IPC calls.. - * - * This is really horribly ugly. - */ -asmlinkage int sys_ipc(uint call, int first, int second, - int third, void __user *ptr, long fifth) -{ - int version, ret; - - version = call >> 16; /* hack for backward compatibility */ - call &= 0xffff; - - switch (call) { - case SEMOP: - return sys_semtimedop(first, (struct sembuf __user *)ptr, - second, NULL); - case SEMTIMEDOP: - return sys_semtimedop(first, (struct sembuf __user *)ptr, - second, (const struct timespec __user *)fifth); - case SEMGET: - return sys_semget (first, second, third); - case SEMCTL: { - union semun fourth; - if (!ptr) - return -EINVAL; - if (get_user(fourth.__pad, (void __user * __user *) ptr)) - return -EFAULT; - return sys_semctl (first, second, third, fourth); - } - - case MSGSND: - return sys_msgsnd (first, (struct msgbuf __user *) ptr, - second, third); - case MSGRCV: - switch (version) { - case 0: { - struct ipc_kludge tmp; - if (!ptr) - return -EINVAL; - - if (copy_from_user(&tmp, - (struct ipc_kludge __user *) ptr, - sizeof (tmp))) - return -EFAULT; - return sys_msgrcv (first, tmp.msgp, second, - tmp.msgtyp, third); - } - default: - return sys_msgrcv (first, - (struct msgbuf __user *) ptr, - second, fifth, third); - } - case MSGGET: - return sys_msgget ((key_t) first, second); - case MSGCTL: - return sys_msgctl (first, second, - (struct msqid_ds __user *) ptr); - case SHMAT: { - ulong raddr; - - if (!access_ok(VERIFY_WRITE, (ulong __user *) third, - sizeof(ulong))) - return -EFAULT; - ret = do_shmat (first, (char __user *) ptr, second, &raddr); - if (ret) - return ret; - return put_user (raddr, (ulong __user *) third); - } - case SHMDT: - return sys_shmdt ((char __user *)ptr); - case SHMGET: - return sys_shmget (first, second, third); - case SHMCTL: - return sys_shmctl (first, second, - (struct shmid_ds __user *) ptr); - default: - return -ENOSYS; - } -} - asmlinkage int sys_uname(struct old_utsname __user * name) { int err; diff --git a/arch/m68k/include/asm/unistd.h b/arch/m68k/include/asm/unistd.h index d801154310ea..60b15d0aa072 100644 --- a/arch/m68k/include/asm/unistd.h +++ b/arch/m68k/include/asm/unistd.h @@ -351,6 +351,7 @@ #define __ARCH_WANT_STAT64 #define __ARCH_WANT_SYS_ALARM #define __ARCH_WANT_SYS_GETHOSTNAME +#define __ARCH_WANT_SYS_IPC #define __ARCH_WANT_SYS_PAUSE #define __ARCH_WANT_SYS_SGETMASK #define __ARCH_WANT_SYS_SIGNAL diff --git a/arch/m68k/kernel/sys_m68k.c b/arch/m68k/kernel/sys_m68k.c index 7b309e7b6cef..77896692eb0a 100644 --- a/arch/m68k/kernel/sys_m68k.c +++ b/arch/m68k/kernel/sys_m68k.c @@ -46,87 +46,6 @@ asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff); } -/* - * sys_ipc() is the de-multiplexer for the SysV IPC calls.. - * - * This is really horribly ugly. - */ -asmlinkage int sys_ipc (uint call, int first, int second, - int third, void __user *ptr, long fifth) -{ - int version, ret; - - version = call >> 16; /* hack for backward compatibility */ - call &= 0xffff; - - if (call <= SEMCTL) - switch (call) { - case SEMOP: - return sys_semop (first, ptr, second); - case SEMGET: - return sys_semget (first, second, third); - case SEMCTL: { - union semun fourth; - if (!ptr) - return -EINVAL; - if (get_user(fourth.__pad, (void __user *__user *) ptr)) - return -EFAULT; - return sys_semctl (first, second, third, fourth); - } - default: - return -ENOSYS; - } - if (call <= MSGCTL) - switch (call) { - case MSGSND: - return sys_msgsnd (first, ptr, second, third); - case MSGRCV: - switch (version) { - case 0: { - struct ipc_kludge tmp; - if (!ptr) - return -EINVAL; - if (copy_from_user (&tmp, ptr, sizeof (tmp))) - return -EFAULT; - return sys_msgrcv (first, tmp.msgp, second, - tmp.msgtyp, third); - } - default: - return sys_msgrcv (first, ptr, - second, fifth, third); - } - case MSGGET: - return sys_msgget ((key_t) first, second); - case MSGCTL: - return sys_msgctl (first, second, ptr); - default: - return -ENOSYS; - } - if (call <= SHMCTL) - switch (call) { - case SHMAT: - switch (version) { - default: { - ulong raddr; - ret = do_shmat (first, ptr, second, &raddr); - if (ret) - return ret; - return put_user (raddr, (ulong __user *) third); - } - } - case SHMDT: - return sys_shmdt (ptr); - case SHMGET: - return sys_shmget (first, second, third); - case SHMCTL: - return sys_shmctl (first, second, ptr); - default: - return -ENOSYS; - } - - return -EINVAL; -} - /* Convert virtual (user) address VADDR to physical address PADDR */ #define virt_to_phys_040(vaddr) \ ({ \ diff --git a/arch/m68knommu/kernel/sys_m68k.c b/arch/m68knommu/kernel/sys_m68k.c index 3e371cc9fd91..d65e9c4c930c 100644 --- a/arch/m68knommu/kernel/sys_m68k.c +++ b/arch/m68knommu/kernel/sys_m68k.c @@ -27,92 +27,6 @@ #include #include -/* - * sys_ipc() is the de-multiplexer for the SysV IPC calls.. - * - * This is really horribly ugly. - */ -asmlinkage int sys_ipc (uint call, int first, int second, - int third, void *ptr, long fifth) -{ - int version, ret; - - version = call >> 16; /* hack for backward compatibility */ - call &= 0xffff; - - if (call <= SEMCTL) - switch (call) { - case SEMOP: - return sys_semop (first, (struct sembuf *)ptr, second); - case SEMGET: - return sys_semget (first, second, third); - case SEMCTL: { - union semun fourth; - if (!ptr) - return -EINVAL; - if (get_user(fourth.__pad, (void **) ptr)) - return -EFAULT; - return sys_semctl (first, second, third, fourth); - } - default: - return -EINVAL; - } - if (call <= MSGCTL) - switch (call) { - case MSGSND: - return sys_msgsnd (first, (struct msgbuf *) ptr, - second, third); - case MSGRCV: - switch (version) { - case 0: { - struct ipc_kludge tmp; - if (!ptr) - return -EINVAL; - if (copy_from_user (&tmp, - (struct ipc_kludge *)ptr, - sizeof (tmp))) - return -EFAULT; - return sys_msgrcv (first, tmp.msgp, second, - tmp.msgtyp, third); - } - default: - return sys_msgrcv (first, - (struct msgbuf *) ptr, - second, fifth, third); - } - case MSGGET: - return sys_msgget ((key_t) first, second); - case MSGCTL: - return sys_msgctl (first, second, - (struct msqid_ds *) ptr); - default: - return -EINVAL; - } - if (call <= SHMCTL) - switch (call) { - case SHMAT: - switch (version) { - default: { - ulong raddr; - ret = do_shmat (first, ptr, second, &raddr); - if (ret) - return ret; - return put_user (raddr, (ulong __user *) third); - } - } - case SHMDT: - return sys_shmdt (ptr); - case SHMGET: - return sys_shmget (first, second, third); - case SHMCTL: - return sys_shmctl (first, second, ptr); - default: - return -ENOSYS; - } - - return -EINVAL; -} - /* sys_cacheflush -- flush (part of) the processor cache. */ asmlinkage int sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len) diff --git a/arch/mips/include/asm/unistd.h b/arch/mips/include/asm/unistd.h index 65c679ecbe6b..97fe472095f2 100644 --- a/arch/mips/include/asm/unistd.h +++ b/arch/mips/include/asm/unistd.h @@ -1004,6 +1004,7 @@ #define __ARCH_WANT_OLD_READDIR #define __ARCH_WANT_SYS_ALARM #define __ARCH_WANT_SYS_GETHOSTNAME +#define __ARCH_WANT_SYS_IPC #define __ARCH_WANT_SYS_PAUSE #define __ARCH_WANT_SYS_SGETMASK #define __ARCH_WANT_SYS_UTIME diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c index 3f7f466190b4..257bf0141775 100644 --- a/arch/mips/kernel/syscall.c +++ b/arch/mips/kernel/syscall.c @@ -406,94 +406,6 @@ _sys_sysmips(nabi_no_regargs struct pt_regs regs) return -EINVAL; } -/* - * sys_ipc() is the de-multiplexer for the SysV IPC calls.. - * - * This is really horribly ugly. - */ -SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, int, second, - unsigned long, third, void __user *, ptr, long, fifth) -{ - int version, ret; - - version = call >> 16; /* hack for backward compatibility */ - call &= 0xffff; - - switch (call) { - case SEMOP: - return sys_semtimedop(first, (struct sembuf __user *)ptr, - second, NULL); - case SEMTIMEDOP: - return sys_semtimedop(first, (struct sembuf __user *)ptr, - second, - (const struct timespec __user *)fifth); - case SEMGET: - return sys_semget(first, second, third); - case SEMCTL: { - union semun fourth; - if (!ptr) - return -EINVAL; - if (get_user(fourth.__pad, (void __user *__user *) ptr)) - return -EFAULT; - return sys_semctl(first, second, third, fourth); - } - - case MSGSND: - return sys_msgsnd(first, (struct msgbuf __user *) ptr, - second, third); - case MSGRCV: - switch (version) { - case 0: { - struct ipc_kludge tmp; - if (!ptr) - return -EINVAL; - - if (copy_from_user(&tmp, - (struct ipc_kludge __user *) ptr, - sizeof(tmp))) - return -EFAULT; - return sys_msgrcv(first, tmp.msgp, second, - tmp.msgtyp, third); - } - default: - return sys_msgrcv(first, - (struct msgbuf __user *) ptr, - second, fifth, third); - } - case MSGGET: - return sys_msgget((key_t) first, second); - case MSGCTL: - return sys_msgctl(first, second, - (struct msqid_ds __user *) ptr); - - case SHMAT: - switch (version) { - default: { - unsigned long raddr; - ret = do_shmat(first, (char __user *) ptr, second, - &raddr); - if (ret) - return ret; - return put_user(raddr, (unsigned long __user *) third); - } - case 1: /* iBCS2 emulator entry point */ - if (!segment_eq(get_fs(), get_ds())) - return -EINVAL; - return do_shmat(first, (char __user *) ptr, second, - (unsigned long *) third); - } - case SHMDT: - return sys_shmdt((char __user *)ptr); - case SHMGET: - return sys_shmget(first, second, third); - case SHMCTL: - return sys_shmctl(first, second, - (struct shmid_ds __user *) ptr); - default: - return -ENOSYS; - } -} - /* * No implemented yet ... */ diff --git a/arch/mn10300/include/asm/unistd.h b/arch/mn10300/include/asm/unistd.h index d13a56e99bad..9d056f515929 100644 --- a/arch/mn10300/include/asm/unistd.h +++ b/arch/mn10300/include/asm/unistd.h @@ -363,6 +363,7 @@ #define __ARCH_WANT_STAT64 #define __ARCH_WANT_SYS_ALARM #define __ARCH_WANT_SYS_GETHOSTNAME +#define __ARCH_WANT_SYS_IPC #define __ARCH_WANT_SYS_PAUSE #define __ARCH_WANT_SYS_SGETMASK #define __ARCH_WANT_SYS_SIGNAL diff --git a/arch/mn10300/kernel/sys_mn10300.c b/arch/mn10300/kernel/sys_mn10300.c index bef69d6daf15..815f1355fad4 100644 --- a/arch/mn10300/kernel/sys_mn10300.c +++ b/arch/mn10300/kernel/sys_mn10300.c @@ -31,91 +31,3 @@ asmlinkage long old_mmap(unsigned long addr, unsigned long len, return -EINVAL; return sys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT); } - -/* - * sys_ipc() is the de-multiplexer for the SysV IPC calls.. - * - * This is really horribly ugly. - */ -asmlinkage long sys_ipc(uint call, int first, int second, - int third, void __user *ptr, long fifth) -{ - int version, ret; - - version = call >> 16; /* hack for backward compatibility */ - call &= 0xffff; - - switch (call) { - case SEMOP: - return sys_semtimedop(first, (struct sembuf __user *)ptr, - second, NULL); - case SEMTIMEDOP: - return sys_semtimedop(first, (struct sembuf __user *)ptr, - second, - (const struct timespec __user *)fifth); - case SEMGET: - return sys_semget(first, second, third); - case SEMCTL: { - union semun fourth; - if (!ptr) - return -EINVAL; - if (get_user(fourth.__pad, (void __user * __user *) ptr)) - return -EFAULT; - return sys_semctl(first, second, third, fourth); - } - - case MSGSND: - return sys_msgsnd(first, (struct msgbuf __user *) ptr, - second, third); - case MSGRCV: - switch (version) { - case 0: { - struct ipc_kludge tmp; - if (!ptr) - return -EINVAL; - - if (copy_from_user(&tmp, - (struct ipc_kludge __user *) ptr, - sizeof(tmp))) - return -EFAULT; - return sys_msgrcv(first, tmp.msgp, second, - tmp.msgtyp, third); - } - default: - return sys_msgrcv(first, - (struct msgbuf __user *) ptr, - second, fifth, third); - } - case MSGGET: - return sys_msgget((key_t) first, second); - case MSGCTL: - return sys_msgctl(first, second, - (struct msqid_ds __user *) ptr); - - case SHMAT: - switch (version) { - default: { - ulong raddr; - ret = do_shmat(first, (char __user *) ptr, second, - &raddr); - if (ret) - return ret; - return put_user(raddr, (ulong *) third); - } - case 1: /* iBCS2 emulator entry point */ - if (!segment_eq(get_fs(), get_ds())) - return -EINVAL; - return do_shmat(first, (char __user *) ptr, second, - (ulong *) third); - } - case SHMDT: - return sys_shmdt((char __user *)ptr); - case SHMGET: - return sys_shmget(first, second, third); - case SHMCTL: - return sys_shmctl(first, second, - (struct shmid_ds __user *) ptr); - default: - return -EINVAL; - } -} diff --git a/arch/powerpc/include/asm/syscalls.h b/arch/powerpc/include/asm/syscalls.h index eb8eb400c664..23bb74e7f946 100644 --- a/arch/powerpc/include/asm/syscalls.h +++ b/arch/powerpc/include/asm/syscalls.h @@ -35,8 +35,6 @@ asmlinkage long sys_pipe2(int __user *fildes, int flags); asmlinkage long sys_rt_sigaction(int sig, const struct sigaction __user *act, struct sigaction __user *oact, size_t sigsetsize); -asmlinkage int sys_ipc(uint call, int first, unsigned long second, - long third, void __user *ptr, long fifth); asmlinkage long ppc64_personality(unsigned long personality); asmlinkage int ppc_rtas(struct rtas_args __user *uargs); asmlinkage time_t sys64_time(time_t __user * tloc); diff --git a/arch/powerpc/include/asm/unistd.h b/arch/powerpc/include/asm/unistd.h index f6ca76176766..c13821fe8741 100644 --- a/arch/powerpc/include/asm/unistd.h +++ b/arch/powerpc/include/asm/unistd.h @@ -364,6 +364,7 @@ #define __ARCH_WANT_STAT64 #define __ARCH_WANT_SYS_ALARM #define __ARCH_WANT_SYS_GETHOSTNAME +#define __ARCH_WANT_SYS_IPC #define __ARCH_WANT_SYS_PAUSE #define __ARCH_WANT_SYS_SGETMASK #define __ARCH_WANT_SYS_SIGNAL diff --git a/arch/powerpc/kernel/syscalls.c b/arch/powerpc/kernel/syscalls.c index 3370e62e43d4..5251221e7a5a 100644 --- a/arch/powerpc/kernel/syscalls.c +++ b/arch/powerpc/kernel/syscalls.c @@ -42,100 +42,6 @@ #include #include -/* - * sys_ipc() is the de-multiplexer for the SysV IPC calls.. - * - * This is really horribly ugly. - */ -int sys_ipc(uint call, int first, unsigned long second, long third, - void __user *ptr, long fifth) -{ - int version, ret; - - version = call >> 16; /* hack for backward compatibility */ - call &= 0xffff; - - ret = -ENOSYS; - switch (call) { - case SEMOP: - ret = sys_semtimedop(first, (struct sembuf __user *)ptr, - (unsigned)second, NULL); - break; - case SEMTIMEDOP: - ret = sys_semtimedop(first, (struct sembuf __user *)ptr, - (unsigned)second, - (const struct timespec __user *) fifth); - break; - case SEMGET: - ret = sys_semget (first, (int)second, third); - break; - case SEMCTL: { - union semun fourth; - - ret = -EINVAL; - if (!ptr) - break; - if ((ret = get_user(fourth.__pad, (void __user * __user *)ptr))) - break; - ret = sys_semctl(first, (int)second, third, fourth); - break; - } - case MSGSND: - ret = sys_msgsnd(first, (struct msgbuf __user *)ptr, - (size_t)second, third); - break; - case MSGRCV: - switch (version) { - case 0: { - struct ipc_kludge tmp; - - ret = -EINVAL; - if (!ptr) - break; - if ((ret = copy_from_user(&tmp, - (struct ipc_kludge __user *) ptr, - sizeof (tmp)) ? -EFAULT : 0)) - break; - ret = sys_msgrcv(first, tmp.msgp, (size_t) second, - tmp.msgtyp, third); - break; - } - default: - ret = sys_msgrcv (first, (struct msgbuf __user *) ptr, - (size_t)second, fifth, third); - break; - } - break; - case MSGGET: - ret = sys_msgget((key_t)first, (int)second); - break; - case MSGCTL: - ret = sys_msgctl(first, (int)second, - (struct msqid_ds __user *)ptr); - break; - case SHMAT: { - ulong raddr; - ret = do_shmat(first, (char __user *)ptr, (int)second, &raddr); - if (ret) - break; - ret = put_user(raddr, (ulong __user *) third); - break; - } - case SHMDT: - ret = sys_shmdt((char __user *)ptr); - break; - case SHMGET: - ret = sys_shmget(first, (size_t)second, third); - break; - case SHMCTL: - ret = sys_shmctl(first, (int)second, - (struct shmid_ds __user *)ptr); - break; - } - - return ret; -} - static inline unsigned long do_mmap2(unsigned long addr, size_t len, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long off, int shift) diff --git a/arch/s390/kernel/entry.h b/arch/s390/kernel/entry.h index 5de54d2af0b2..15fd68b196c0 100644 --- a/arch/s390/kernel/entry.h +++ b/arch/s390/kernel/entry.h @@ -30,7 +30,7 @@ struct fadvise64_64_args; struct old_sigaction; long sys_mmap2(struct s390_mmap_arg_struct __user *arg); -long sys_ipc(uint call, int first, unsigned long second, +long sys_s390_ipc(uint call, int first, unsigned long second, unsigned long third, void __user *ptr); long sys_s390_newuname(struct new_utsname __user *name); long sys_s390_personality(unsigned long personality); diff --git a/arch/s390/kernel/sys_s390.c b/arch/s390/kernel/sys_s390.c index b2563509b5a9..b8b78092ab7c 100644 --- a/arch/s390/kernel/sys_s390.c +++ b/arch/s390/kernel/sys_s390.c @@ -64,7 +64,7 @@ out: * * This is really horribly ugly. */ -SYSCALL_DEFINE5(ipc, uint, call, int, first, unsigned long, second, +SYSCALL_DEFINE5(s390_ipc, uint, call, int, first, unsigned long, second, unsigned long, third, void __user *, ptr) { struct ipc_kludge tmp; diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index 2a24766567af..990ac8b321c8 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S @@ -125,7 +125,7 @@ NI_SYSCALL /* vm86old for i386 */ SYSCALL(sys_wait4,sys_wait4,compat_sys_wait4_wrapper) SYSCALL(sys_swapoff,sys_swapoff,sys32_swapoff_wrapper) /* 115 */ SYSCALL(sys_sysinfo,sys_sysinfo,compat_sys_sysinfo_wrapper) -SYSCALL(sys_ipc,sys_ipc,sys32_ipc_wrapper) +SYSCALL(sys_s390_ipc,sys_s390_ipc,sys32_ipc_wrapper) SYSCALL(sys_fsync,sys_fsync,sys32_fsync_wrapper) SYSCALL(sys_sigreturn,sys_sigreturn,sys32_sigreturn) SYSCALL(sys_clone,sys_clone,sys_clone_wrapper) /* 120 */ diff --git a/arch/sh/include/asm/syscalls.h b/arch/sh/include/asm/syscalls.h index c1e2b8deb837..c1ce2862f7be 100644 --- a/arch/sh/include/asm/syscalls.h +++ b/arch/sh/include/asm/syscalls.h @@ -11,8 +11,6 @@ asmlinkage int old_mmap(unsigned long addr, unsigned long len, asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long pgoff); -asmlinkage int sys_ipc(uint call, int first, int second, - int third, void __user *ptr, long fifth); asmlinkage int sys_uname(struct old_utsname __user *name); #ifdef CONFIG_SUPERH32 diff --git a/arch/sh/include/asm/unistd_32.h b/arch/sh/include/asm/unistd_32.h index 365744b05269..a48f65e2e429 100644 --- a/arch/sh/include/asm/unistd_32.h +++ b/arch/sh/include/asm/unistd_32.h @@ -358,6 +358,7 @@ #define __ARCH_WANT_STAT64 #define __ARCH_WANT_SYS_ALARM #define __ARCH_WANT_SYS_GETHOSTNAME +#define __ARCH_WANT_SYS_IPC #define __ARCH_WANT_SYS_PAUSE #define __ARCH_WANT_SYS_SGETMASK #define __ARCH_WANT_SYS_SIGNAL diff --git a/arch/sh/include/asm/unistd_64.h b/arch/sh/include/asm/unistd_64.h index 25de158aac3a..7709b2b8f752 100644 --- a/arch/sh/include/asm/unistd_64.h +++ b/arch/sh/include/asm/unistd_64.h @@ -398,6 +398,7 @@ #define __ARCH_WANT_STAT64 #define __ARCH_WANT_SYS_ALARM #define __ARCH_WANT_SYS_GETHOSTNAME +#define __ARCH_WANT_SYS_IPC #define __ARCH_WANT_SYS_PAUSE #define __ARCH_WANT_SYS_SGETMASK #define __ARCH_WANT_SYS_SIGNAL diff --git a/arch/sh/kernel/sys_sh.c b/arch/sh/kernel/sys_sh.c index 71399cde03b5..c18cfaa67fdd 100644 --- a/arch/sh/kernel/sys_sh.c +++ b/arch/sh/kernel/sys_sh.c @@ -53,110 +53,6 @@ asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff); } -/* - * sys_ipc() is the de-multiplexer for the SysV IPC calls.. - * - * This is really horribly ugly. - */ -asmlinkage int sys_ipc(uint call, int first, int second, - int third, void __user *ptr, long fifth) -{ - int version, ret; - - version = call >> 16; /* hack for backward compatibility */ - call &= 0xffff; - - if (call <= SEMTIMEDOP) - switch (call) { - case SEMOP: - return sys_semtimedop(first, - (struct sembuf __user *)ptr, - second, NULL); - case SEMTIMEDOP: - return sys_semtimedop(first, - (struct sembuf __user *)ptr, second, - (const struct timespec __user *)fifth); - case SEMGET: - return sys_semget (first, second, third); - case SEMCTL: { - union semun fourth; - if (!ptr) - return -EINVAL; - if (get_user(fourth.__pad, (void __user * __user *) ptr)) - return -EFAULT; - return sys_semctl (first, second, third, fourth); - } - default: - return -EINVAL; - } - - if (call <= MSGCTL) - switch (call) { - case MSGSND: - return sys_msgsnd (first, (struct msgbuf __user *) ptr, - second, third); - case MSGRCV: - switch (version) { - case 0: - { - struct ipc_kludge tmp; - - if (!ptr) - return -EINVAL; - - if (copy_from_user(&tmp, - (struct ipc_kludge __user *) ptr, - sizeof (tmp))) - return -EFAULT; - - return sys_msgrcv (first, tmp.msgp, second, - tmp.msgtyp, third); - } - default: - return sys_msgrcv (first, - (struct msgbuf __user *) ptr, - second, fifth, third); - } - case MSGGET: - return sys_msgget ((key_t) first, second); - case MSGCTL: - return sys_msgctl (first, second, - (struct msqid_ds __user *) ptr); - default: - return -EINVAL; - } - if (call <= SHMCTL) - switch (call) { - case SHMAT: - switch (version) { - default: { - ulong raddr; - ret = do_shmat (first, (char __user *) ptr, - second, &raddr); - if (ret) - return ret; - return put_user (raddr, (ulong __user *) third); - } - case 1: /* iBCS2 emulator entry point */ - if (!segment_eq(get_fs(), get_ds())) - return -EINVAL; - return do_shmat (first, (char __user *) ptr, - second, (ulong *) third); - } - case SHMDT: - return sys_shmdt ((char __user *)ptr); - case SHMGET: - return sys_shmget (first, second, third); - case SHMCTL: - return sys_shmctl (first, second, - (struct shmid_ds __user *) ptr); - default: - return -EINVAL; - } - - return -EINVAL; -} - /* sys_cacheflush -- flush (part of) the processor cache. */ asmlinkage int sys_cacheflush(unsigned long addr, unsigned long len, int op) { diff --git a/arch/sparc/include/asm/unistd.h b/arch/sparc/include/asm/unistd.h index cb4b9bfd0d87..d0b3b01ac9d4 100644 --- a/arch/sparc/include/asm/unistd.h +++ b/arch/sparc/include/asm/unistd.h @@ -432,7 +432,9 @@ #define __ARCH_WANT_SYS_SIGPENDING #define __ARCH_WANT_SYS_SIGPROCMASK #define __ARCH_WANT_SYS_RT_SIGSUSPEND -#ifndef __32bit_syscall_numbers__ +#ifdef __32bit_syscall_numbers__ +#define __ARCH_WANT_SYS_IPC +#else #define __ARCH_WANT_COMPAT_SYS_TIME #define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND #endif diff --git a/arch/sparc/kernel/sys_sparc_32.c b/arch/sparc/kernel/sys_sparc_32.c index 3a82e65d8db2..ee995b7dae7e 100644 --- a/arch/sparc/kernel/sys_sparc_32.c +++ b/arch/sparc/kernel/sys_sparc_32.c @@ -98,119 +98,6 @@ out: return error; } -/* - * sys_ipc() is the de-multiplexer for the SysV IPC calls.. - * - * This is really horribly ugly. - */ - -asmlinkage int sys_ipc (uint call, int first, int second, int third, void __user *ptr, long fifth) -{ - int version, err; - - version = call >> 16; /* hack for backward compatibility */ - call &= 0xffff; - - if (call <= SEMCTL) - switch (call) { - case SEMOP: - err = sys_semtimedop (first, (struct sembuf __user *)ptr, second, NULL); - goto out; - case SEMTIMEDOP: - err = sys_semtimedop (first, (struct sembuf __user *)ptr, second, (const struct timespec __user *) fifth); - goto out; - case SEMGET: - err = sys_semget (first, second, third); - goto out; - case SEMCTL: { - union semun fourth; - err = -EINVAL; - if (!ptr) - goto out; - err = -EFAULT; - if (get_user(fourth.__pad, - (void __user * __user *)ptr)) - goto out; - err = sys_semctl (first, second, third, fourth); - goto out; - } - default: - err = -ENOSYS; - goto out; - } - if (call <= MSGCTL) - switch (call) { - case MSGSND: - err = sys_msgsnd (first, (struct msgbuf __user *) ptr, - second, third); - goto out; - case MSGRCV: - switch (version) { - case 0: { - struct ipc_kludge tmp; - err = -EINVAL; - if (!ptr) - goto out; - err = -EFAULT; - if (copy_from_user(&tmp, (struct ipc_kludge __user *) ptr, sizeof (tmp))) - goto out; - err = sys_msgrcv (first, tmp.msgp, second, tmp.msgtyp, third); - goto out; - } - case 1: default: - err = sys_msgrcv (first, - (struct msgbuf __user *) ptr, - second, fifth, third); - goto out; - } - case MSGGET: - err = sys_msgget ((key_t) first, second); - goto out; - case MSGCTL: - err = sys_msgctl (first, second, (struct msqid_ds __user *) ptr); - goto out; - default: - err = -ENOSYS; - goto out; - } - if (call <= SHMCTL) - switch (call) { - case SHMAT: - switch (version) { - case 0: default: { - ulong raddr; - err = do_shmat (first, (char __user *) ptr, second, &raddr); - if (err) - goto out; - err = -EFAULT; - if (put_user (raddr, (ulong __user *) third)) - goto out; - err = 0; - goto out; - } - case 1: /* iBCS2 emulator entry point */ - err = -EINVAL; - goto out; - } - case SHMDT: - err = sys_shmdt ((char __user *)ptr); - goto out; - case SHMGET: - err = sys_shmget (first, second, third); - goto out; - case SHMCTL: - err = sys_shmctl (first, second, (struct shmid_ds __user *) ptr); - goto out; - default: - err = -ENOSYS; - goto out; - } - else - err = -ENOSYS; -out: - return err; -} - int sparc_mmap_check(unsigned long addr, unsigned long len) { if (ARCH_SUN4C && diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c index cb1bef6f14b7..45410e939628 100644 --- a/arch/sparc/kernel/sys_sparc_64.c +++ b/arch/sparc/kernel/sys_sparc_64.c @@ -426,7 +426,7 @@ out: * This is really horribly ugly. */ -SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, unsigned long, second, +SYSCALL_DEFINE6(sparc_ipc, unsigned int, call, int, first, unsigned long, second, unsigned long, third, void __user *, ptr, long, fifth) { long err; diff --git a/arch/sparc/kernel/systbls.h b/arch/sparc/kernel/systbls.h index 68312fe8da74..2c331c37e748 100644 --- a/arch/sparc/kernel/systbls.h +++ b/arch/sparc/kernel/systbls.h @@ -10,7 +10,7 @@ struct new_utsname; extern asmlinkage unsigned long sys_getpagesize(void); extern asmlinkage long sparc_pipe(struct pt_regs *regs); -extern asmlinkage long sys_ipc(unsigned int call, int first, +extern asmlinkage long sys_sparc_ipc(unsigned int call, int first, unsigned long second, unsigned long third, void __user *ptr, long fifth); diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S index 17614251fb6d..30ca2b1d3a17 100644 --- a/arch/sparc/kernel/systbls_64.S +++ b/arch/sparc/kernel/systbls_64.S @@ -136,7 +136,7 @@ sys_call_table: /*200*/ .word sys_ssetmask, sys_nis_syscall, sys_newlstat, sys_uselib, sys_nis_syscall .word sys_readahead, sys_socketcall, sys_syslog, sys_lookup_dcookie, sys_fadvise64 /*210*/ .word sys_fadvise64_64, sys_tgkill, sys_waitpid, sys_swapoff, sys_sysinfo - .word sys_ipc, sys_nis_syscall, sys_clone, sys_ioprio_get, sys_adjtimex + .word sys_sparc_ipc, sys_nis_syscall, sys_clone, sys_ioprio_get, sys_adjtimex /*220*/ .word sys_nis_syscall, sys_ni_syscall, sys_delete_module, sys_ni_syscall, sys_getpgid .word sys_bdflush, sys_sysfs, sys_nis_syscall, sys_setfsuid, sys_setfsgid /*230*/ .word sys_select, sys_nis_syscall, sys_splice, sys_stime, sys_statfs64 diff --git a/arch/um/sys-i386/syscalls.c b/arch/um/sys-i386/syscalls.c index d0aa8f125ee6..70ca357393b8 100644 --- a/arch/um/sys-i386/syscalls.c +++ b/arch/um/sys-i386/syscalls.c @@ -34,92 +34,6 @@ long sys_clone(unsigned long clone_flags, unsigned long newsp, return ret; } -/* - * sys_ipc() is the de-multiplexer for the SysV IPC calls.. - * - * This is really horribly ugly. - */ -long sys_ipc (uint call, int first, int second, - int third, void __user *ptr, long fifth) -{ - int version, ret; - - version = call >> 16; /* hack for backward compatibility */ - call &= 0xffff; - - switch (call) { - case SEMOP: - return sys_semtimedop(first, (struct sembuf __user *) ptr, - second, NULL); - case SEMTIMEDOP: - return sys_semtimedop(first, (struct sembuf __user *) ptr, - second, - (const struct timespec __user *) fifth); - case SEMGET: - return sys_semget (first, second, third); - case SEMCTL: { - union semun fourth; - if (!ptr) - return -EINVAL; - if (get_user(fourth.__pad, (void __user * __user *) ptr)) - return -EFAULT; - return sys_semctl (first, second, third, fourth); - } - - case MSGSND: - return sys_msgsnd (first, (struct msgbuf *) ptr, - second, third); - case MSGRCV: - switch (version) { - case 0: { - struct ipc_kludge tmp; - if (!ptr) - return -EINVAL; - - if (copy_from_user(&tmp, - (struct ipc_kludge *) ptr, - sizeof (tmp))) - return -EFAULT; - return sys_msgrcv (first, tmp.msgp, second, - tmp.msgtyp, third); - } - default: - panic("msgrcv with version != 0"); - return sys_msgrcv (first, - (struct msgbuf *) ptr, - second, fifth, third); - } - case MSGGET: - return sys_msgget ((key_t) first, second); - case MSGCTL: - return sys_msgctl (first, second, (struct msqid_ds *) ptr); - - case SHMAT: - switch (version) { - default: { - ulong raddr; - ret = do_shmat (first, (char *) ptr, second, &raddr); - if (ret) - return ret; - return put_user (raddr, (ulong *) third); - } - case 1: /* iBCS2 emulator entry point */ - if (!segment_eq(get_fs(), get_ds())) - return -EINVAL; - return do_shmat (first, (char *) ptr, second, (ulong *) third); - } - case SHMDT: - return sys_shmdt ((char *)ptr); - case SHMGET: - return sys_shmget (first, second, third); - case SHMCTL: - return sys_shmctl (first, second, - (struct shmid_ds *) ptr); - default: - return -ENOSYS; - } -} - long sys_sigaction(int sig, const struct old_sigaction __user *act, struct old_sigaction __user *oact) { diff --git a/arch/x86/include/asm/syscalls.h b/arch/x86/include/asm/syscalls.h index 86ab6a0623fd..50f6a569f0d1 100644 --- a/arch/x86/include/asm/syscalls.h +++ b/arch/x86/include/asm/syscalls.h @@ -54,7 +54,6 @@ unsigned long sys_sigreturn(struct pt_regs *); struct oldold_utsname; struct old_utsname; -asmlinkage int sys_ipc(uint, int, int, int, void __user *, long); asmlinkage int sys_uname(struct old_utsname __user *); asmlinkage int sys_olduname(struct oldold_utsname __user *); diff --git a/arch/x86/include/asm/unistd_32.h b/arch/x86/include/asm/unistd_32.h index daa65d9aae95..45e64a17b86e 100644 --- a/arch/x86/include/asm/unistd_32.h +++ b/arch/x86/include/asm/unistd_32.h @@ -354,6 +354,7 @@ #define __ARCH_WANT_STAT64 #define __ARCH_WANT_SYS_ALARM #define __ARCH_WANT_SYS_GETHOSTNAME +#define __ARCH_WANT_SYS_IPC #define __ARCH_WANT_SYS_PAUSE #define __ARCH_WANT_SYS_SGETMASK #define __ARCH_WANT_SYS_SIGNAL diff --git a/arch/x86/kernel/sys_i386_32.c b/arch/x86/kernel/sys_i386_32.c index 7955e90c8341..8b5c348fdcf2 100644 --- a/arch/x86/kernel/sys_i386_32.c +++ b/arch/x86/kernel/sys_i386_32.c @@ -24,91 +24,6 @@ #include -/* - * sys_ipc() is the de-multiplexer for the SysV IPC calls.. - * - * This is really horribly ugly. - */ -asmlinkage int sys_ipc(uint call, int first, int second, - int third, void __user *ptr, long fifth) -{ - int version, ret; - - version = call >> 16; /* hack for backward compatibility */ - call &= 0xffff; - - switch (call) { - case SEMOP: - return sys_semtimedop(first, (struct sembuf __user *)ptr, second, NULL); - case SEMTIMEDOP: - return sys_semtimedop(first, (struct sembuf __user *)ptr, second, - (const struct timespec __user *)fifth); - - case SEMGET: - return sys_semget(first, second, third); - case SEMCTL: { - union semun fourth; - if (!ptr) - return -EINVAL; - if (get_user(fourth.__pad, (void __user * __user *) ptr)) - return -EFAULT; - return sys_semctl(first, second, third, fourth); - } - - case MSGSND: - return sys_msgsnd(first, (struct msgbuf __user *) ptr, - second, third); - case MSGRCV: - switch (version) { - case 0: { - struct ipc_kludge tmp; - if (!ptr) - return -EINVAL; - - if (copy_from_user(&tmp, - (struct ipc_kludge __user *) ptr, - sizeof(tmp))) - return -EFAULT; - return sys_msgrcv(first, tmp.msgp, second, - tmp.msgtyp, third); - } - default: - return sys_msgrcv(first, - (struct msgbuf __user *) ptr, - second, fifth, third); - } - case MSGGET: - return sys_msgget((key_t) first, second); - case MSGCTL: - return sys_msgctl(first, second, (struct msqid_ds __user *) ptr); - - case SHMAT: - switch (version) { - default: { - ulong raddr; - ret = do_shmat(first, (char __user *) ptr, second, &raddr); - if (ret) - return ret; - return put_user(raddr, (ulong __user *) third); - } - case 1: /* iBCS2 emulator entry point */ - if (!segment_eq(get_fs(), get_ds())) - return -EINVAL; - /* The "(ulong *) third" is valid _only_ because of the kernel segment thing */ - return do_shmat(first, (char __user *) ptr, second, (ulong *) third); - } - case SHMDT: - return sys_shmdt((char __user *)ptr); - case SHMGET: - return sys_shmget(first, second, third); - case SHMCTL: - return sys_shmctl(first, second, - (struct shmid_ds __user *) ptr); - default: - return -ENOSYS; - } -} - /* * Old cruft */ diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index b60907e3b0d5..fbb61ae70e06 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -684,6 +684,8 @@ asmlinkage long sys_shmat(int shmid, char __user *shmaddr, int shmflg); asmlinkage long sys_shmget(key_t key, size_t size, int flag); asmlinkage long sys_shmdt(char __user *shmaddr); asmlinkage long sys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf); +asmlinkage long sys_ipc(unsigned int call, int first, int second, + unsigned long third, void __user *ptr, long fifth); asmlinkage long sys_mq_open(const char __user *name, int oflag, mode_t mode, struct mq_attr __user *attr); asmlinkage long sys_mq_unlink(const char __user *name); diff --git a/ipc/Makefile b/ipc/Makefile index 4e1955ea815d..9075e172e52c 100644 --- a/ipc/Makefile +++ b/ipc/Makefile @@ -3,7 +3,7 @@ # obj-$(CONFIG_SYSVIPC_COMPAT) += compat.o -obj-$(CONFIG_SYSVIPC) += util.o msgutil.o msg.o sem.o shm.o ipcns_notifier.o +obj-$(CONFIG_SYSVIPC) += util.o msgutil.o msg.o sem.o shm.o ipcns_notifier.o syscall.o obj-$(CONFIG_SYSVIPC_SYSCTL) += ipc_sysctl.o obj_mq-$(CONFIG_COMPAT) += compat_mq.o obj-$(CONFIG_POSIX_MQUEUE) += mqueue.o msgutil.o $(obj_mq-y) diff --git a/ipc/syscall.c b/ipc/syscall.c new file mode 100644 index 000000000000..355a3da9ec73 --- /dev/null +++ b/ipc/syscall.c @@ -0,0 +1,99 @@ +/* + * sys_ipc() is the old de-multiplexer for the SysV IPC calls. + * + * This is really horribly ugly, and new architectures should just wire up + * the individual syscalls instead. + */ +#include + +#ifdef __ARCH_WANT_SYS_IPC +#include +#include +#include +#include +#include + +SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, int, second, + unsigned long, third, void __user *, ptr, long, fifth) +{ + int version, ret; + + version = call >> 16; /* hack for backward compatibility */ + call &= 0xffff; + + switch (call) { + case SEMOP: + return sys_semtimedop(first, (struct sembuf __user *)ptr, + second, NULL); + case SEMTIMEDOP: + return sys_semtimedop(first, (struct sembuf __user *)ptr, + second, + (const struct timespec __user *)fifth); + + case SEMGET: + return sys_semget(first, second, third); + case SEMCTL: { + union semun fourth; + if (!ptr) + return -EINVAL; + if (get_user(fourth.__pad, (void __user * __user *) ptr)) + return -EFAULT; + return sys_semctl(first, second, third, fourth); + } + + case MSGSND: + return sys_msgsnd(first, (struct msgbuf __user *) ptr, + second, third); + case MSGRCV: + switch (version) { + case 0: { + struct ipc_kludge tmp; + if (!ptr) + return -EINVAL; + + if (copy_from_user(&tmp, + (struct ipc_kludge __user *) ptr, + sizeof(tmp))) + return -EFAULT; + return sys_msgrcv(first, tmp.msgp, second, + tmp.msgtyp, third); + } + default: + return sys_msgrcv(first, + (struct msgbuf __user *) ptr, + second, fifth, third); + } + case MSGGET: + return sys_msgget((key_t) first, second); + case MSGCTL: + return sys_msgctl(first, second, (struct msqid_ds __user *)ptr); + + case SHMAT: + switch (version) { + default: { + unsigned long raddr; + ret = do_shmat(first, (char __user *)ptr, + second, &raddr); + if (ret) + return ret; + return put_user(raddr, (unsigned long __user *) third); + } + case 1: + /* + * This was the entry point for kernel-originating calls + * from iBCS2 in 2.2 days. + */ + return -EINVAL; + } + case SHMDT: + return sys_shmdt((char __user *)ptr); + case SHMGET: + return sys_shmget(first, second, third); + case SHMCTL: + return sys_shmctl(first, second, + (struct shmid_ds __user *) ptr); + default: + return -ENOSYS; + } +} +#endif diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c index 695384f12a7d..70f2ea758ffe 100644 --- a/kernel/sys_ni.c +++ b/kernel/sys_ni.c @@ -126,6 +126,7 @@ cond_syscall(sys_setreuid16); cond_syscall(sys_setuid16); cond_syscall(sys_vm86old); cond_syscall(sys_vm86); +cond_syscall(sys_ipc); cond_syscall(compat_sys_ipc); cond_syscall(compat_sys_sysctl); cond_syscall(sys_flock); -- cgit v1.2.3 From f1eb1332b8f07e937add24c6fd2ac40b8737a2f4 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 10 Mar 2010 15:23:05 -0800 Subject: ipc: use rlimit helpers Make sure compiler won't do weird things with limits. E.g. fetching them twice may return 2 different values after writable limits are implemented. I.e. either use rlimit helpers added in 3e10e716abf3c71bdb5d86b8f507f9e72236c9cd ("resource: add helpers for fetching rlimits") or ACCESS_ONCE if not applicable. Signed-off-by: Jiri Slaby Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- ipc/mqueue.c | 2 +- ipc/shm.c | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'ipc') diff --git a/ipc/mqueue.c b/ipc/mqueue.c index b6cb06451f4b..e4e3f04803ca 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c @@ -155,7 +155,7 @@ static struct inode *mqueue_get_inode(struct super_block *sb, spin_lock(&mq_lock); if (u->mq_bytes + mq_bytes < u->mq_bytes || u->mq_bytes + mq_bytes > - p->signal->rlim[RLIMIT_MSGQUEUE].rlim_cur) { + task_rlimit(p, RLIMIT_MSGQUEUE)) { spin_unlock(&mq_lock); kfree(info->messages); goto out_inode; diff --git a/ipc/shm.c b/ipc/shm.c index 23256b855819..1a314c89f93c 100644 --- a/ipc/shm.c +++ b/ipc/shm.c @@ -764,8 +764,7 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf) if (euid != shp->shm_perm.uid && euid != shp->shm_perm.cuid) goto out_unlock; - if (cmd == SHM_LOCK && - !current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur) + if (cmd == SHM_LOCK && !rlimit(RLIMIT_MEMLOCK)) goto out_unlock; } -- cgit v1.2.3 From 45575f5a426c01ec68cd33d998267ba2f6278fac Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Mon, 22 Mar 2010 17:47:59 +1100 Subject: ppc64 sys_ipc breakage in 2.6.34-rc2 I chased down a fail on ppc64 on 2.6.34-rc2 where an application that uses shared memory was getting a SEGV. Commit baed7fc9b580bd3fb8252ff1d9b36eaf1f86b670 ("Add generic sys_ipc wrapper") changed the second argument from an unsigned long to an int. When we call shmget the system call wrappers for sys_ipc will sign extend second (ie the size) which truncates it. It took a while to track down because the call succeeds and strace shows the untruncated size :) The patch below changes second from an int to an unsigned long which fixes shmget on ppc64 (and I assume s390, sparc64 and mips64). Signed-off-by: Anton Blanchard -- I assume the function prototypes for the other IPC methods would cause us to sign or zero extend second where appropriate (avoiding any security issues). Come to think of it, the syscall wrappers for each method should do that for us as well. Signed-off-by: Linus Torvalds --- ipc/syscall.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ipc') diff --git a/ipc/syscall.c b/ipc/syscall.c index 355a3da9ec73..1d6f53f6b562 100644 --- a/ipc/syscall.c +++ b/ipc/syscall.c @@ -13,7 +13,7 @@ #include #include -SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, int, second, +SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, unsigned long, second, unsigned long, third, void __user *, ptr, long, fifth) { int version, ret; -- cgit v1.2.3