예제 #1
0
long compat_sys_msgctl(int first, int second, void __user *uptr)
{
	int err, err2;
	struct msqid64_ds m64;
	int version = compat_ipc_parse_version(&second);
	void __user *p;

	memset(&m64, 0, sizeof(m64));

	switch (second & (~IPC_64)) {
	case IPC_INFO:
	case IPC_RMID:
	case MSG_INFO:
		err = sys_msgctl(first, second, uptr);
		break;

	case IPC_SET:
		if (version == IPC_64) {
			err = get_compat_msqid64(&m64, uptr);
		} else {
			err = get_compat_msqid(&m64, uptr);
		}
		if (err)
			break;
		p = compat_alloc_user_space(sizeof(m64));
		if (copy_to_user(p, &m64, sizeof(m64)))
			err = -EFAULT;
		else
			err = sys_msgctl(first, second, p);
		break;

	case IPC_STAT:
	case MSG_STAT:
		p = compat_alloc_user_space(sizeof(m64));
		err = sys_msgctl(first, second, p);
		if (err < 0)
			break;
		if (copy_from_user(&m64, p, sizeof(m64)))
			err2 = -EFAULT;
		else if (version == IPC_64)
			err2 = put_compat_msqid64_ds(&m64, uptr);
		else
			err2 = put_compat_msqid_ds(&m64, uptr);
		if (err2)
			err = -EFAULT;
		break;

	default:
		err = -EINVAL;
		break;
	}
	return err;
}
예제 #2
0
static long do_compat_semctl(int first, int second, int third, u32 pad)
{
	unsigned long fourth;
	int err, err2;
	struct semid64_ds s64;
	struct semid64_ds __user *up64;
	int version = compat_ipc_parse_version(&third);

	memset(&s64, 0, sizeof(s64));

	if ((third & (~IPC_64)) == SETVAL)
#ifdef __BIG_ENDIAN
		fourth = (unsigned long)pad << 32;
#else
		fourth = pad;
#endif
	else
예제 #3
0
long compat_sys_shmctl(int first, int second, void __user *uptr)
{
	void __user *p;
	struct shmid64_ds s64;
	struct shminfo64 smi;
	int err, err2;
	int version = compat_ipc_parse_version(&second);

	memset(&s64, 0, sizeof(s64));

	switch (second & (~IPC_64)) {
	case IPC_RMID:
	case SHM_LOCK:
	case SHM_UNLOCK:
		err = sys_shmctl(first, second, uptr);
		break;

	case IPC_INFO:
		p = compat_alloc_user_space(sizeof(smi));
		err = sys_shmctl(first, second, p);
		if (err < 0)
			break;
		if (copy_from_user(&smi, p, sizeof(smi)))
			err2 = -EFAULT;
		else if (version == IPC_64)
			err2 = put_compat_shminfo64(&smi, uptr);
		else
			err2 = put_compat_shminfo(&smi, uptr);
		if (err2)
			err = -EFAULT;
		break;


	case IPC_SET:
		if (version == IPC_64) {
			err = get_compat_shmid64_ds(&s64, uptr);
		} else {
			err = get_compat_shmid_ds(&s64, uptr);
		}
		if (err)
			break;
		p = compat_alloc_user_space(sizeof(s64));
		if (copy_to_user(p, &s64, sizeof(s64)))
			err = -EFAULT;
		else
			err = sys_shmctl(first, second, p);
		break;

	case IPC_STAT:
	case SHM_STAT:
		p = compat_alloc_user_space(sizeof(s64));
		err = sys_shmctl(first, second, p);
		if (err < 0)
			break;
		if (copy_from_user(&s64, p, sizeof(s64)))
			err2 = -EFAULT;
		else if (version == IPC_64)
			err2 = put_compat_shmid64_ds(&s64, uptr);
		else
			err2 = put_compat_shmid_ds(&s64, uptr);
		if (err2)
			err = -EFAULT;
		break;

	case SHM_INFO:
		p = compat_alloc_user_space(sizeof(struct shm_info));
		err = sys_shmctl(first, second, p);
		if (err < 0)
			break;
		err2 = put_compat_shm_info(p, uptr);
		if (err2)
			err = -EFAULT;
		break;

	default:
		err = -EINVAL;
		break;
	}
	return err;
}
예제 #4
0
static long do_compat_semctl(int first, int second, int third, u32 pad)
{
	union semun fourth;
	int err, err2;
	struct semid64_ds s64;
	struct semid64_ds __user *up64;
	int version = compat_ipc_parse_version(&third);

	memset(&s64, 0, sizeof(s64));

	if ((third & (~IPC_64)) == SETVAL)
		fourth.val = (int) pad;
	else
		fourth.__pad = compat_ptr(pad);
	switch (third & (~IPC_64)) {
	case IPC_INFO:
	case IPC_RMID:
	case SEM_INFO:
	case GETVAL:
	case GETPID:
	case GETNCNT:
	case GETZCNT:
	case GETALL:
	case SETVAL:
	case SETALL:
		err = sys_semctl(first, second, third, fourth);
		break;

	case IPC_STAT:
	case SEM_STAT:
		up64 = compat_alloc_user_space(sizeof(s64));
		fourth.__pad = up64;
		err = sys_semctl(first, second, third, fourth);
		if (err < 0)
			break;
		if (copy_from_user(&s64, up64, sizeof(s64)))
			err2 = -EFAULT;
		else if (version == IPC_64)
			err2 = put_compat_semid64_ds(&s64, compat_ptr(pad));
		else
			err2 = put_compat_semid_ds(&s64, compat_ptr(pad));
		if (err2)
			err = -EFAULT;
		break;

	case IPC_SET:
		if (version == IPC_64) {
			err = get_compat_semid64_ds(&s64, compat_ptr(pad));
		} else {
			err = get_compat_semid_ds(&s64, compat_ptr(pad));
		}
		up64 = compat_alloc_user_space(sizeof(s64));
		if (copy_to_user(up64, &s64, sizeof(s64)))
			err = -EFAULT;
		if (err)
			break;

		fourth.__pad = up64;
		err = sys_semctl(first, second, third, fourth);
		break;

	default:
		err = -EINVAL;
		break;
	}
	return err;
}