diff options
Diffstat (limited to 'ipc')
| -rw-r--r-- | ipc/Makefile | 2 | ||||
| -rw-r--r-- | ipc/mqueue.c | 2 | ||||
| -rw-r--r-- | ipc/shm.c | 3 | ||||
| -rw-r--r-- | ipc/syscall.c | 99 | 
4 files changed, 102 insertions, 4 deletions
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/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;  		} 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 <linux/unistd.h> + +#ifdef __ARCH_WANT_SYS_IPC +#include <linux/errno.h> +#include <linux/ipc.h> +#include <linux/shm.h> +#include <linux/syscalls.h> +#include <linux/uaccess.h> + +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  |