Example #1
0
/*
 * OpenBSD 3.5 semctl(2) with 16bit mode_t in struct ipcperm.
 */
int
compat_35_sys___semctl(struct proc *p, void *v, register_t *retval)
{
	struct compat_35_sys___semctl_args /* {
		syscallarg(int) semid;
		syscallarg(int) semnum;
		syscallarg(int) cmd;
		syscallarg(union semun *) arg;
	} */ *uap = v;
	union semun arg;
	int error = 0, cmd = SCARG(uap, cmd);

	switch (cmd) {
	case IPC_SET:
	case IPC_STAT:
	case GETALL:
	case SETVAL:
	case SETALL:
		error = copyin(SCARG(uap, arg), &arg, sizeof(arg));
		break;
	}
	if (error == 0) {
		error = semctl1(p, SCARG(uap, semid), SCARG(uap, semnum),
		    cmd, &arg, retval, semid_copyin, semid_copyout);
	}
	return (error);
}
Example #2
0
int
ibcs2_sys_semsys(struct lwp *l, const struct ibcs2_sys_semsys_args *uap, register_t *retval)
{
#ifdef SYSVSEM
	/* {
		syscallarg(int) which;
		syscallarg(int) a2;
		syscallarg(int) a3;
		syscallarg(int) a4;
		syscallarg(int) a5;
	} */
	struct semid_ds sembuf;
	struct ibcs2_semid_ds isembuf;
	void *pass_arg;
	int a5 = SCARG(uap, a5);
	int error;

	switch (SCARG(uap, which)) {
	case 0:					/* semctl */
#define	semctl_semid	SCARG(uap, a2)
#define	semctl_semnum	SCARG(uap, a3)
#define	semctl_cmd	SCARG(uap, a4)
#define	semctl_arg	((union __semun *)&a5)
		pass_arg = get_semctl_arg(semctl_cmd, &sembuf, semctl_arg);
		if (semctl_cmd == IPC_SET) {
			error = copyin(semctl_arg->buf, &isembuf, sizeof isembuf);
			if (error != 0)
				return error;
			cvt_isemid2semid(&isembuf, &sembuf);
		}
		error = semctl1(l, semctl_semid, semctl_semnum, semctl_cmd, 
		    pass_arg, retval);
		if (error == 0 && semctl_cmd == IPC_STAT) {
			cvt_semid2isemid(&sembuf, &isembuf);
			error = copyout(&isembuf, semctl_arg->buf, sizeof(isembuf));
		}
		return error;
#undef	semctl_semid
#undef	semctl_semnum
#undef	semctl_cmd
#undef	semctl_arg

	case 1:				/* semget */
		return compat_10_sys_semsys(l, (const void *)uap, retval);

	case 2:				/* semop */
		return compat_10_sys_semsys(l, (const void *)uap, retval);
	}
#endif
	return EINVAL;
}
int
compat_14_sys___semctl(struct lwp *l, const struct compat_14_sys___semctl_args *uap, register_t *retval)
{
	/* {
		syscallarg(int) semid;
		syscallarg(int) semnum;
		syscallarg(int) cmd;
		syscallarg(union __semun *) arg;
	} */
	union __semun arg;
	struct semid_ds sembuf;
	struct semid_ds14 osembuf;
	int cmd, error;
	void *pass_arg;

	cmd = SCARG(uap, cmd);

	pass_arg = get_semctl_arg(cmd, &sembuf, &arg);

	if (pass_arg != NULL) {
		error = copyin(SCARG(uap, arg), &arg, sizeof(arg));
		if (error)
			return (error);
		if (cmd == IPC_SET) {
			error = copyin(arg.buf, &osembuf, sizeof(osembuf));
			if (error)
				return (error);
			__semid_ds14_to_native(&osembuf, &sembuf);
		}
	}

	error = semctl1(l, SCARG(uap, semid), SCARG(uap, semnum), cmd,
	    pass_arg, retval);

	if (error == 0 && cmd == IPC_STAT) {
		__native_to_semid_ds14(&sembuf, &osembuf);
		error = copyout(&osembuf, arg.buf, sizeof(osembuf));
	}

	return (error);
}
Example #4
0
int
sys_____semctl50(struct lwp *l, const struct sys_____semctl50_args *uap,
    register_t *retval)
{
	/* {
		syscallarg(int) semid;
		syscallarg(int) semnum;
		syscallarg(int) cmd;
		syscallarg(union __semun *) arg;
	} */
	struct semid_ds sembuf;
	int cmd, error;
	void *pass_arg;
	union __semun karg;

	cmd = SCARG(uap, cmd);

	pass_arg = get_semctl_arg(cmd, &sembuf, &karg);

	if (pass_arg) {
		error = copyin(SCARG(uap, arg), &karg, sizeof(karg));
		if (error)
			return error;
		if (cmd == IPC_SET) {
			error = copyin(karg.buf, &sembuf, sizeof(sembuf));
			if (error)
				return (error);
		}
	}

	error = semctl1(l, SCARG(uap, semid), SCARG(uap, semnum), cmd,
	    pass_arg, retval);

	if (error == 0 && cmd == IPC_STAT)
		error = copyout(&sembuf, karg.buf, sizeof(sembuf));

	return (error);
}
Example #5
0
int
do_netbsd32___semctl14(struct lwp *l, const struct netbsd32___semctl14_args *uap, register_t *retval, void *vkarg)
{
	/* {
		syscallarg(int) semid;
		syscallarg(int) semnum;
		syscallarg(int) cmd;
		syscallarg(netbsd32_semunp_t) arg;
	} */
	struct semid_ds sembuf;
	struct netbsd32_semid_ds sembuf32;
	int cmd, error;
	void *pass_arg;
	union __semun karg;
	union netbsd32_semun karg32;

	cmd = SCARG(uap, cmd);

	switch (cmd) {
	case IPC_SET:
	case IPC_STAT:
		pass_arg = &sembuf;
		break;

	case GETALL:
	case SETVAL:
	case SETALL:
		pass_arg = &karg;
		break;
	default:
		pass_arg = NULL;
		break;
	}

	if (pass_arg) {
		if (vkarg != NULL)
			karg32 = *(union netbsd32_semun *)vkarg;
		else {
			error = copyin(SCARG_P32(uap, arg), &karg32,
					sizeof(karg32));
			if (error)
				return error;
		}
		if (pass_arg == &karg) {
			switch (cmd) {
			case GETALL:
			case SETALL:
				karg.array = NETBSD32PTR64(karg32.array);
				break;
			case SETVAL:
				karg.val = karg32.val;
				break;
			}
		}
		if (cmd == IPC_SET) {
			error = copyin(NETBSD32PTR64(karg32.buf), &sembuf32,
			    sizeof(sembuf32));
			if (error)
				return (error);
			netbsd32_to_semid_ds(&sembuf32, &sembuf);
		}
	}

	error = semctl1(l, SCARG(uap, semid), SCARG(uap, semnum), cmd,
	    pass_arg, retval);

	if (error == 0 && cmd == IPC_STAT) {
		netbsd32_from_semid_ds(&sembuf, &sembuf32);
		error = copyout(&sembuf32, NETBSD32PTR64(karg32.buf),
		    sizeof(sembuf32));
	}

	return (error);
}
static int
linux32_semctl(struct lwp *l, const struct linux32_sys_ipc_args *uap,
    register_t *retval)
{
	int lcmd, cmd, error;
	struct semid_ds bs;
	struct linux32_semid_ds ls;
	struct linux32_semid64_ds ls64;
	union linux32_semun lsem;
	union __semun bsem;
	void *buf = NULL;

	if ((error = copyin(SCARG_P32(uap, ptr), &lsem, sizeof lsem)))
		return error;

	lcmd = SCARG(uap, a3);

	switch (lcmd & ~LINUX32_IPC_64) {
	case LINUX32_IPC_RMID:
		cmd = IPC_RMID;
		break;
	case LINUX32_IPC_STAT:
		cmd = IPC_STAT;
		buf = &bs;
		break;
	case LINUX32_IPC_SET:
		if (lcmd & LINUX32_IPC_64) {
			error = copyin(NETBSD32PTR64(lsem.l_buf), &ls64,
			    sizeof ls64);
			linux32_to_bsd_semid64_ds(&ls64, &bs);
		} else {
			error = copyin(NETBSD32PTR64(lsem.l_buf), &ls,
			    sizeof ls);
			linux32_to_bsd_semid_ds(&ls, &bs);
		}
		if (error)
			return error;
		cmd = IPC_SET;
		buf = &bs;
		break;
	case LINUX32_GETVAL:
		cmd = GETVAL;
		break;
	case LINUX32_SETVAL:
		cmd = SETVAL;
		bsem.val = lsem.l_val;
		buf = &bsem;
		break;
	case LINUX32_GETPID:
		cmd = GETPID;
		break;
	case LINUX32_GETNCNT:
		cmd = GETNCNT;
		break;
	case LINUX32_GETZCNT:
		cmd = GETZCNT;
		break;
	case LINUX32_GETALL:
		cmd = GETALL;
		bsem.array = NETBSD32PTR64(lsem.l_array);
		buf = &bsem;
		break;
	case LINUX32_SETALL:
		cmd = SETALL;
		bsem.array = NETBSD32PTR64(lsem.l_array);
		buf = &bsem;
		break;
	default:
		return EINVAL;
	}

	error = semctl1(l, SCARG(uap, a1), SCARG(uap, a2), cmd, buf, retval);
	if (error)
		return error;

	switch (lcmd) {
	case LINUX32_IPC_STAT:
		bsd_to_linux32_semid_ds(&bs, &ls);
		error = copyout(&ls, NETBSD32PTR64(lsem.l_buf), sizeof ls);
		break;
	case LINUX32_IPC_STAT|LINUX32_IPC_64:
		bsd_to_linux32_semid64_ds(&bs, &ls64);
		error = copyout(&ls64, NETBSD32PTR64(lsem.l_buf), sizeof ls64);
		break;
	default:
		break;
	}

	return error;
}