Beispiel #1
0
static int
svr4_msgctl(int arg1, int cmd, char *arg3)
{
	struct ibcs2_msqid_ds	im;
	struct abi4_msqid_ds	im4;
	struct msqid_ds		lm;
	mm_segment_t		fs;
	int			err;

	switch (cmd) {
	case SVR4_IPC_SET:
		err = copy_from_user(&im, arg3, sizeof(im)) ? -EFAULT : 0;
		if (err)
			break;

		imsq_to_lmsq(&im, &lm);

		fs = get_fs();
		set_fs(get_ds());
#ifdef CONFIG_65BIT
		err = SYS(msgctl, arg1, IPC_SET, &lm);
#else
		err = SYS(ipc,MSGCTL,arg1, IPC_SET,0, &lm);
#endif
		set_fs(fs);

		lmsq_to_imsq(&lm, &im);
		err = copy_to_user(arg3, &im, sizeof(im)) ? -EFAULT : 0;
		break;
	case SVR4_IPC_SET_L:
		err = copy_from_user(&im4, arg3, sizeof(im4)) ? -EFAULT : 0;
		if (err)
			break;
		imsq_to_lmsq_l(&im4, &lm);

		fs = get_fs();
		set_fs(get_ds());
#ifdef CONFIG_65BIT
		err = SYS(msgctl, arg1, IPC_SET, &lm);
#else
		err = SYS(ipc,MSGCTL,arg1, IPC_SET,0, &lm);
#endif
		set_fs(fs);

		lmsq_to_imsq_l(&lm, &im4);
		err = copy_to_user(arg3, &im4, sizeof(im4)) ? -EFAULT : 0;
		break;
	case SVR4_IPC_RMID:
	case SVR4_IPC_RMID_L:
#ifdef CONFIG_65BIT
		err= SYS(msgctl, arg1, IPC_RMID, arg3);
#else
		err = SYS(ipc,MSGCTL,arg1, IPC_RMID,0, arg3);
#endif
		return err;
	case SVR4_IPC_STAT:
		fs = get_fs();
		set_fs(get_ds());
#ifdef CONFIG_65BIT
		err = SYS(msgctl, arg1, IPC_STAT, &lm);
#else
		err = SYS(ipc,MSGCTL,arg1, IPC_STAT,0, &lm);
#endif
		set_fs(fs);

		if (err < 0)
			break;

		lmsq_to_imsq(&lm, &im);
		err = copy_to_user(arg3, &im, sizeof(im)) ? -EFAULT : 0;
		break;
	case SVR4_IPC_STAT_L:
		fs = get_fs();
		set_fs(get_ds());
#ifdef CONFIG_65BIT
		err = SYS(msgctl, arg1, IPC_STAT, &lm);
#else
		err = SYS(ipc,MSGCTL,arg1, IPC_STAT,0, &lm);
#endif
		set_fs(fs);

		if (err < 0)
			break;

		lmsq_to_imsq_l(&lm, &im4);
		err = copy_to_user(arg3, &im4, sizeof(im4)) ? -EFAULT : 0;
		break;
	default:
#if defined(CONFIG_ABI_TRACE)
		__abi_trace("msgctl: unsupported command: %x\n", cmd);
#endif
		err = -EINVAL;
	}

	return (err);
}
Beispiel #2
0
int svr4_msgsys(struct pt_regs * regs)
{
	int command = get_syscall_parameter (regs, 0);
	int arg1, arg2, arg4, arg5;
	mm_segment_t old_fs;
	char *arg3;
	int retval;

	arg1 = get_syscall_parameter (regs, 1);
	arg2 = get_syscall_parameter (regs, 2);
	arg3 = (char *) get_syscall_parameter (regs, 3);

	switch (command) {
		/* hard one first */
		case U_MSGCTL:
			switch (arg2) {
				case U_IPC_SET: {
					struct ibcs_msqid_ds im;
					struct msqid_ds lm;

					retval = verify_area(VERIFY_WRITE, arg3, sizeof(im));
					if (retval)
						return retval;

					copy_from_user(&im, (char *) arg3, sizeof(im));
					imsq_to_lmsq(&im, &lm);

					old_fs = get_fs();
					set_fs (get_ds());
					retval = SYS (ipc) (MSGCTL, arg1, IPC_SET, 0, &lm);
					set_fs (old_fs);

					lmsq_to_imsq(&lm, &im);
					copy_to_user((char *)arg3, &im, sizeof(im));
					return retval;
				}

				case U_IPC_SET_L: {
					struct ibcs_msqid_ds_l im;
					struct msqid_ds lm;

					retval = verify_area(VERIFY_WRITE, arg3, sizeof(im));
					if (retval)
						return retval;

					copy_from_user(&im, (char *) arg3, sizeof(im));
					imsq_to_lmsq_l(&im, &lm);

					old_fs = get_fs();
					set_fs (get_ds());
					retval = SYS (ipc) (MSGCTL, arg1, IPC_SET, 0, &lm);
					set_fs (old_fs);

					lmsq_to_imsq_l(&lm, &im);
					copy_to_user((char *)arg3, &im, sizeof(im));
					return retval;
				}

			case U_IPC_RMID:
			case U_IPC_RMID_L:
				return SYS (ipc) (MSGCTL, arg1, IPC_RMID, 0, arg3);

			case U_IPC_STAT: {
				struct ibcs_msqid_ds im;
				struct msqid_ds lm;

				retval = verify_area(VERIFY_WRITE, arg3, sizeof(im));
				if (retval)
					return retval;

				old_fs = get_fs();
				set_fs (get_ds());
				retval = SYS (ipc) (MSGCTL, arg1, IPC_STAT, 0, &lm);
				set_fs (old_fs);

				if (retval < 0)
					return retval;

				lmsq_to_imsq(&lm, &im);
				copy_to_user((char *)arg3, &im, sizeof(im));
				return retval;
			}

			case U_IPC_STAT_L: {
				struct ibcs_msqid_ds_l im;
				struct msqid_ds lm;

				retval = verify_area(VERIFY_WRITE, arg3, sizeof(im));
				if (retval)
					return retval;

				old_fs = get_fs();
				set_fs (get_ds());
				retval = SYS (ipc) (MSGCTL, arg1, IPC_STAT, 0, &lm);
				set_fs (old_fs);

				if (retval < 0)
					return retval;

				lmsq_to_imsq_l(&lm, &im);
				copy_to_user((char *)arg3, &im, sizeof(im));
				return retval;
			}

			default:
				printk(KERN_ERR "%d ibcs_msgctl: unsupported command %d\n",
					current->pid, arg2);
		}

		case U_MSGGET:
			return SYS (ipc) (MSGGET, arg1, arg2, 0, 0);

		case U_MSGSND:
			arg4 = get_syscall_parameter (regs, 4);
			retval = SYS (ipc) (MSGSND, arg1, arg3, arg4, (char *) arg2);
			return ((retval > 0) ? 0 : retval);

		case U_MSGRCV: {
#ifdef IPCCALL
			arg4 = get_syscall_parameter (regs, 4);
			arg5 = get_syscall_parameter (regs, 5);
			return SYS(ipc)(IPCCALL(1,MSGRCV), arg1, arg3, arg5, arg2, arg4);
#else
#ifdef __sparc__
		        printk(KERN_ERR
				"%d Sparc/IBCS: Kludgy U_MSGRCV not implemented\n",
				current->pid);
			return -EINVAL;
#else /* __sparc__ */
			struct ipc_kludge *scratch;
			long old_esp = regs->esp;

			scratch = (struct ipc_kludge *)((regs->esp-1024-sizeof(struct ipc_kludge)) & 0xfffffffc);
			regs->esp = (long)scratch;
			get_user(arg4, ((unsigned long *) regs->esp) + 5);
			get_user(arg5, ((unsigned long *) regs->esp) + 6);
			put_user((long)arg2, &scratch->msgp);
			put_user((long)arg4, &scratch->msgtyp);
			retval = SYS (ipc) (MSGRCV, arg1, arg3, arg5, scratch);
			regs->esp = old_esp;
			return retval;
#endif /* sparc */
#endif /* IPCCALL */
		}

		default:
			printk(KERN_ERR "%d ibcs_msgctl: unsupported command %d\n",
				current->pid, command);
	}
	return -EINVAL;
}