int
netbsd32_sysarch(struct lwp *l, const struct netbsd32_sysarch_args *uap, register_t *retval)
{
	/* {
		syscallarg(int) op;
		syscallarg(netbsd32_voidp) parms;
	} */
	int error;

	switch (SCARG(uap, op)) {
	case X86_IOPL:
		error = x86_iopl(l,
		    NETBSD32PTR64(SCARG(uap, parms)), retval);
		break;
	case X86_GET_MTRR:
		error = x86_64_get_mtrr32(l,
		    NETBSD32PTR64(SCARG(uap, parms)), retval);
		break;
	case X86_SET_MTRR:
		error = x86_64_set_mtrr32(l,
		    NETBSD32PTR64(SCARG(uap, parms)), retval);
		break;
	default:
		error = EINVAL;
		break;
	}
	return error;
}
Пример #2
0
static inline void
netbsd32_to_partinfo(struct netbsd32_partinfo *s32p, struct partinfo *p, u_long cmd)
{

	p->disklab = (struct disklabel *)NETBSD32PTR64(s32p->disklab);
	p->part = (struct partition *)NETBSD32PTR64(s32p->part);
}
Пример #3
0
/* convert to/from different structures */
static inline void
netbsd32_to_fbcmap(struct netbsd32_fbcmap *s32p, struct fbcmap *p, u_long cmd)
{

	p->index = s32p->index;
	p->count = s32p->count;
	p->red = NETBSD32PTR64(s32p->red);
	p->green = NETBSD32PTR64(s32p->green);
	p->blue = NETBSD32PTR64(s32p->blue);
}
Пример #4
0
static inline void
netbsd32_to_opiocdesc(struct netbsd32_opiocdesc *s32p, struct opiocdesc *p, u_long cmd)
{

	p->op_nodeid = s32p->op_nodeid;
	p->op_namelen = s32p->op_namelen;
	p->op_name = NETBSD32PTR64(s32p->op_name);
	p->op_buflen = s32p->op_buflen;
	p->op_buf = NETBSD32PTR64(s32p->op_buf);
}
Пример #5
0
static inline void
netbsd32_to_fbcursor(struct netbsd32_fbcursor *s32p, struct fbcursor *p, u_long cmd)
{

	p->set = s32p->set;
	p->enable = s32p->enable;
	p->pos = s32p->pos;
	p->hot = s32p->hot;
	netbsd32_to_fbcmap(&s32p->cmap, &p->cmap, cmd);
	p->size = s32p->size;
	p->image = NETBSD32PTR64(s32p->image);
	p->mask = NETBSD32PTR64(s32p->mask);
}
Пример #6
0
static int
netbsd32_copyinpiod(struct ptrace_io_desc *piod, const void *addr)
{
	struct netbsd32_ptrace_io_desc piod32;

	int error = copyin(addr, &piod32, sizeof(piod32));
	if (error)
		return error;
	piod->piod_op = piod32.piod_op;
	piod->piod_offs = NETBSD32PTR64(piod32.piod_offs);
	piod->piod_addr = NETBSD32PTR64(piod32.piod_addr);
	piod->piod_len = (size_t)piod32.piod_len;

	return 0;
}
Пример #7
0
static inline void
netbsd32_to_ifdrv(struct netbsd32_ifdrv *s32p, struct ifdrv *p, u_long cmd)
{

	memcpy(p, s32p, sizeof *s32p);
	p->ifd_data = (void *)NETBSD32PTR64(s32p->ifd_data);
}
Пример #8
0
int
linux32_sys_oldselect(struct lwp *l, const struct linux32_sys_oldselect_args *uap, register_t *retval)
{
	/* {
		syscallarg(linux32_oldselectp_t) lsp;
	} */
	struct linux32_oldselect lsp32;
	int error;

	if ((error = copyin(SCARG_P32(uap, lsp), &lsp32, sizeof(lsp32))) != 0)
		return error;

	return linux32_select1(l, retval, lsp32.nfds, 
	     NETBSD32PTR64(lsp32.readfds), NETBSD32PTR64(lsp32.writefds),
	     NETBSD32PTR64(lsp32.exceptfds), NETBSD32PTR64(lsp32.timeout));
}
Пример #9
0
void
linux32_to_native_sigaction(struct sigaction *bsa, const struct linux32_sigaction *lsa)
{
	bsa->sa_handler = NETBSD32PTR64(lsa->linux_sa_handler);
	linux32_to_native_sigset(&bsa->sa_mask, &lsa->linux_sa_mask);
	bsa->sa_flags = linux32_to_native_sigflags(lsa->linux_sa_flags);
}
Пример #10
0
static inline void
netbsd32_to_ifmediareq(struct netbsd32_ifmediareq *s32p, struct ifmediareq *p, u_long cmd)
{

	memcpy(p, s32p, sizeof *s32p);
	p->ifm_ulist = (int *)NETBSD32PTR64(s32p->ifm_ulist);
}
Пример #11
0
static inline void
netbsd32_to_ifconf(struct netbsd32_ifconf *s32p, struct ifconf *p, u_long cmd)
{

	p->ifc_len = s32p->ifc_len;
	/* ifc_buf & ifc_req are the same size so this works */
	p->ifc_buf = (void *)NETBSD32PTR64(s32p->ifc_buf);
}
Пример #12
0
static void
linux32_to_bsd_msqid_ds(struct linux32_msqid_ds *lmp, struct msqid_ds *bmp)
{

	memset(bmp, 0, sizeof(*bmp));
	linux32_to_bsd_ipc_perm(&lmp->l_msg_perm, &bmp->msg_perm);
	bmp->_msg_first = NETBSD32PTR64(lmp->l_msg_first);
	bmp->_msg_last = NETBSD32PTR64(lmp->l_msg_last);
	bmp->_msg_cbytes = lmp->l_msg_cbytes;
	bmp->msg_qnum = lmp->l_msg_qnum;
	bmp->msg_qbytes = lmp->l_msg_qbytes;
	bmp->msg_lspid = lmp->l_msg_lspid;
	bmp->msg_lrpid = lmp->l_msg_lrpid;
	bmp->msg_stime = lmp->l_msg_stime;
	bmp->msg_rtime = lmp->l_msg_rtime;
	bmp->msg_ctime = lmp->l_msg_ctime;
}
int
compat_16_netbsd32___sigreturn14(struct lwp *l, const struct compat_16_netbsd32___sigreturn14_args *uap, register_t *retval)
{
	/* {
		syscallarg(netbsd32_sigcontextp_t) sigcntxp;
	} */
	struct netbsd32_sigcontext *scp, context;
	struct proc *p = l->l_proc;
	struct trapframe *tf;
	int error;

	/*
	 * The trampoline code hands us the context.
	 * It is unsafe to keep track of it ourselves, in the event that a
	 * program jumps out of a signal handler.
	 */
	scp = NETBSD32PTR64(SCARG(uap, sigcntxp));
	if (copyin(scp, &context, sizeof(*scp)) != 0)
		return (EFAULT);

	/*
	 * Check for security violations.
	 */
	error = check_sigcontext32(l, &context);
	if (error != 0)
		return error;

	/* Restore register context. */
	tf = l->l_md.md_regs;
	tf->tf_ds = context.sc_ds;
	tf->tf_es = context.sc_es;
	cpu_fsgs_reload(l, context.sc_fs, context.sc_gs);
	tf->tf_rflags = context.sc_eflags;
	tf->tf_rdi = context.sc_edi;
	tf->tf_rsi = context.sc_esi;
	tf->tf_rbp = context.sc_ebp;
	tf->tf_rbx = context.sc_ebx;
	tf->tf_rdx = context.sc_edx;
	tf->tf_rcx = context.sc_ecx;
	tf->tf_rax = context.sc_eax;

	tf->tf_rip = context.sc_eip;
	tf->tf_cs = context.sc_cs;
	tf->tf_rsp = context.sc_esp;
	tf->tf_ss = context.sc_ss;

	mutex_enter(p->p_lock);
	/* Restore signal stack. */
	if (context.sc_onstack & SS_ONSTACK)
		l->l_sigstk.ss_flags |= SS_ONSTACK;
	else
		l->l_sigstk.ss_flags &= ~SS_ONSTACK;
	/* Restore signal mask. */
	(void) sigprocmask1(l, SIG_SETMASK, &context.sc_mask, 0);
	mutex_exit(p->p_lock);

	return (EJUSTRETURN);
}
Пример #14
0
static void
linux32_to_bsd_semid_ds(struct linux32_semid_ds *lsp, struct semid_ds *bsp)
{
	linux32_to_bsd_ipc_perm(&lsp->l_sem_perm, &bsp->sem_perm);
	bsp->sem_otime = lsp->l_sem_otime;
	bsp->sem_ctime = lsp->l_sem_ctime;
	bsp->sem_nsems = lsp->l_sem_nsems;
	bsp->_sem_base = NETBSD32PTR64(lsp->l_sem_base);
}
Пример #15
0
static inline void
netbsd32_to_format_op(struct netbsd32_format_op *s32p, struct format_op *p, u_long cmd)
{

	p->df_buf = (char *)NETBSD32PTR64(s32p->df_buf);
	p->df_count = s32p->df_count;
	p->df_startblk = s32p->df_startblk;
	memcpy(p->df_reg, s32p->df_reg, sizeof(s32p->df_reg));
}
Пример #16
0
static void
linux32_to_bsd_shmid_ds(struct linux32_shmid_ds *lsp, struct shmid_ds *bsp)
{
	linux32_to_bsd_ipc_perm(&lsp->l_shm_perm, &bsp->shm_perm);
	bsp->shm_segsz = lsp->l_shm_segsz;
	bsp->shm_atime = lsp->l_shm_atime;
	bsp->shm_dtime = lsp->l_shm_dtime;
	bsp->shm_ctime = lsp->l_shm_ctime;
	bsp->shm_cpid = lsp->l_shm_cpid;
	bsp->shm_lpid = lsp->l_shm_lpid;
	bsp->shm_nattch = lsp->l_shm_nattch;
	bsp->_shm_internal = NETBSD32PTR64(lsp->l_private2);
}
Пример #17
0
static int
netbsd32_execve_fetch_element(char * const *array, size_t index, char **value)
{
	int error;
	netbsd32_charp const *a32 = (void const *)array;
	netbsd32_charp e;

	error = copyin(a32 + index, &e, sizeof(e));
	if (error)
		return error;
	*value = (char *)NETBSD32PTR64(e);
	return 0;
}
Пример #18
0
static inline void
netbsd32_to_ifreq(struct netbsd32_ifreq *s32p, struct ifreq *p, u_long cmd)
{

	memcpy(p, s32p, sizeof *s32p);
	/*
	 * XXX
	 * struct ifreq says the same, but sometimes the ifr_data
	 * union member needs to be converted to 64 bits... this
	 * is very driver specific and so we ignore it for now..
	 */
	if (cmd == SIOCGIFDATA || cmd == SIOCZIFDATA)
		p->ifr_data = (void *)NETBSD32PTR64(s32p->ifr_data);
}
Пример #19
0
int
linux32_getifconf(struct lwp *l, register_t *retval, void *data)
{
	struct linux32_ifreq ifr, *ifrp;
	struct netbsd32_ifconf *ifc = data;
	struct ifnet *ifp;
	struct ifaddr *ifa;
	struct sockaddr *sa;
	struct osockaddr *osa;
	int space, error = 0;
	const int sz = (int)sizeof(ifr);

	ifrp = (struct linux32_ifreq *)NETBSD32PTR64(ifc->ifc_req);
	if (ifrp == NULL)
		space = 0;
	else
		space = ifc->ifc_len;

	IFNET_FOREACH(ifp) {
		(void)strncpy(ifr.ifr_name, ifp->if_xname,
		    sizeof(ifr.ifr_name));
		if (ifr.ifr_name[sizeof(ifr.ifr_name) - 1] != '\0')
			return ENAMETOOLONG;
		if (IFADDR_EMPTY(ifp))
			continue;
		IFADDR_FOREACH(ifa, ifp) {
			sa = ifa->ifa_addr;
			if (sa->sa_family != AF_INET ||
			    sa->sa_len > sizeof(*osa))
				continue;
			memcpy(&ifr.ifr_addr, sa, sa->sa_len);
			osa = (struct osockaddr *)&ifr.ifr_addr;
			osa->sa_family = sa->sa_family;
			if (space >= sz) {
				error = copyout(&ifr, ifrp, sz);
				if (error != 0)
					return error;
				ifrp++;
			}
			space -= sz;
		}
	}
Пример #20
0
int
netbsd32_sigaction(struct lwp *l, const struct netbsd32_sigaction_args *uap, register_t *retval)
{
	/* {
		syscallarg(int) signum;
		syscallarg(const netbsd32_sigactionp_t) nsa;
		syscallarg(netbsd32_sigactionp_t) osa;
	} */
	struct sigaction nsa, osa;
	struct netbsd32_sigaction13 *sa32p, sa32;
	int error;

	if (SCARG_P32(uap, nsa)) {
		sa32p = SCARG_P32(uap, nsa);
		if (copyin(sa32p, &sa32, sizeof(sa32)))
			return EFAULT;
		nsa.sa_handler = (void *)NETBSD32PTR64(sa32.netbsd32_sa_handler);
		memset(&nsa.sa_mask, 0, sizeof(nsa.sa_mask));
		nsa.sa_mask.__bits[0] = sa32.netbsd32_sa_mask;
		nsa.sa_flags = sa32.netbsd32_sa_flags;
	}
	error = sigaction1(l, SCARG(uap, signum),
			   SCARG_P32(uap, nsa) ? &nsa : 0,
			   SCARG_P32(uap, osa) ? &osa : 0,
			   NULL, 0);

	if (error)
		return (error);

	if (SCARG_P32(uap, osa)) {
		NETBSD32PTR32(sa32.netbsd32_sa_handler, osa.sa_handler);
		sa32.netbsd32_sa_mask = osa.sa_mask.__bits[0];
		sa32.netbsd32_sa_flags = osa.sa_flags;
		sa32p = SCARG_P32(uap, osa);
		if (copyout(&sa32, sa32p, sizeof(sa32)))
			return EFAULT;
	}

	return (0);
}
Пример #21
0
int
netbsd32_recvmsg(struct lwp *l, const struct netbsd32_recvmsg_args *uap, register_t *retval)
{
	/* {
		syscallarg(int) s;
		syscallarg(netbsd32_msghdrp_t) msg;
		syscallarg(int) flags;
	} */
	struct netbsd32_msghdr msg;
	struct iovec aiov[UIO_SMALLIOV], *uiov, *iov;
	int error;

	error = copyin(SCARG_P32(uap, msg), &msg, sizeof(msg));
		/* netbsd32_msghdr needs the iov pre-allocated */
	if (error)
		return (error);
	if ((u_int)msg.msg_iovlen > UIO_SMALLIOV) {
		if ((u_int)msg.msg_iovlen > IOV_MAX)
			return (EMSGSIZE);
		iov = (struct iovec *)malloc(
		       sizeof(struct iovec) * (u_int)msg.msg_iovlen, M_IOV,
		       M_WAITOK);
	} else 
		iov = aiov;
	msg.msg_flags = SCARG(uap, flags);
	uiov = (struct iovec *)NETBSD32PTR64(msg.msg_iov);
	error = netbsd32_to_iovecin((struct netbsd32_iovec *)uiov,
				   iov, msg.msg_iovlen);
	if (error)
		goto done;
	if ((error = recvit32(l, SCARG(uap, s), &msg, iov, (void *)0,
	    retval)) == 0) {
		error = copyout(&msg, SCARG_P32(uap, msg), sizeof(msg));
	}
done:
	if (iov != aiov)
		FREE(iov, M_IOV);
	return (error);
}
Пример #22
0
/* ARGSUSED */
int
netbsd32___sigaction_sigtramp(struct lwp *l, const struct netbsd32___sigaction_sigtramp_args *uap, register_t *retval)
{
	/* {
		syscallarg(int) signum;
		syscallarg(const netbsd32_sigactionp_t) nsa;
		syscallarg(netbsd32_sigactionp_t) osa;
		syscallarg(netbsd32_voidp) tramp;
		syscallarg(int) vers;
	} */
	struct netbsd32_sigaction sa32;
	struct sigaction nsa, osa;
	int error;

	if (SCARG_P32(uap, nsa)) {
		error = copyin(SCARG_P32(uap, nsa), &sa32, sizeof(sa32));
		if (error)
			return (error);
		nsa.sa_handler = NETBSD32PTR64(sa32.netbsd32_sa_handler);
		nsa.sa_mask = sa32.netbsd32_sa_mask;
		nsa.sa_flags = sa32.netbsd32_sa_flags;
	}
	error = sigaction1(l, SCARG(uap, signum),
	    SCARG_P32(uap, nsa) ? &nsa : 0,
	    SCARG_P32(uap, osa) ? &osa : 0,
	    SCARG_P32(uap, tramp), SCARG(uap, vers));
	if (error)
		return (error);
	if (SCARG_P32(uap, osa)) {
		NETBSD32PTR32(sa32.netbsd32_sa_handler, osa.sa_handler);
		sa32.netbsd32_sa_mask = osa.sa_mask;
		sa32.netbsd32_sa_flags = osa.sa_flags;
		error = copyout(&sa32, SCARG_P32(uap, osa), sizeof(sa32));
		if (error)
			return (error);
	}
	return (0);
}
Пример #23
0
int
linux32_sys___sysctl(struct lwp *l, const struct linux32_sys___sysctl_args *uap, register_t *retval)
{
	/* {
		syscallarg(linux32___sysctlp_t) lsp;
	} */
	struct linux32_sysctl ls32;
	int name[CTL_MAXNAME];
	size_t savelen;
	netbsd32_size_t oldlen32;
	size_t oldlen;
	int error;

	/*
	 * Read sysctl arguments 
	 */
	if ((error = copyin(SCARG_P32(uap, lsp), &ls32, sizeof(ls32))) != 0)
		return error;

	/*
	 * Read oldlen
	 */
	if (NETBSD32PTR64(ls32.oldlenp) != NULL) {
		if ((error = copyin(NETBSD32PTR64(ls32.oldlenp), 
		    &oldlen32, sizeof(oldlen32))) != 0)
			return error;
	} else {
		oldlen32 = 0;
	}

	savelen = (size_t)oldlen32;

	/* 
	 * Sanity check nlen
	 */
	if ((ls32.nlen > CTL_MAXNAME) || (ls32.nlen < 1))
		return ENOTDIR;

	/*
	 * Read the sysctl name
	 */
	if ((error = copyin(NETBSD32PTR64(ls32.name), &name, 
	   ls32.nlen * sizeof(int))) != 0)
		return error;

	ktrmib(name, ls32.nlen);
	/*
	 * First try linux32 tree, then linux tree
	 */
	oldlen = (size_t)oldlen32;
	sysctl_lock(NETBSD32PTR64(ls32.newval) != NULL);
	error = sysctl_dispatch(name, ls32.nlen,
				NETBSD32PTR64(ls32.oldval), &oldlen,
				NETBSD32PTR64(ls32.newval), ls32.newlen,
				name, l, &linux32_sysctl_root);
	oldlen32 = (netbsd32_size_t)oldlen;
	sysctl_unlock();

	/*
	 * Check for oldlen overflow (not likely, but who knows...)
	 */
	if (oldlen != oldlen32) {
#ifdef DEBUG_LINUX
		printf("%s: oldlen32 = %d, oldlen = %ld\n", 
		    __func__, oldlen32, oldlen);
#endif
		return EINVAL;
	}

	/*
	 * set caller's oldlen, even if we got an error
	 */
	if (NETBSD32PTR64(ls32.oldlenp)) {
		int nerror;

		nerror = copyout(&oldlen32, 
		    NETBSD32PTR64(ls32.oldlenp), sizeof(oldlen32));

		if (error == 0)
			error = nerror;
	}

	/*
	 * oldlen was too short
	 */
	if ((error == 0) && 
	    (NETBSD32PTR64(ls32.oldval) != NULL) &&
	    (savelen < oldlen32))
		error = ENOMEM;

	return error;
}
Пример #24
0
int
recvit32(struct lwp *l, int s, struct netbsd32_msghdr *mp, struct iovec *iov, void *namelenp, register_t *retsize)
{
	struct uio auio;
	int i, len, error, iovlen;
	struct mbuf *from = 0, *control = 0;
	struct socket *so;
	struct proc *p;
	struct iovec *ktriov = NULL;
	p = l->l_proc;

	/* fd_getsock() will use the descriptor for us */
	if ((error = fd_getsock(s, &so)) != 0)
		return (error);
	auio.uio_iov = iov;
	auio.uio_iovcnt = mp->msg_iovlen;
	auio.uio_rw = UIO_READ;
	auio.uio_vmspace = l->l_proc->p_vmspace;
	auio.uio_offset = 0;			/* XXX */
	auio.uio_resid = 0;
	for (i = 0; i < mp->msg_iovlen; i++, iov++) {
#if 0
		/* cannot happen iov_len is unsigned */
		if (iov->iov_len < 0) {
			error = EINVAL;
			goto out1;
		}
#endif
		/*
		 * Reads return ssize_t because -1 is returned on error.
		 * Therefore we must restrict the length to SSIZE_MAX to
		 * avoid garbage return values.
		 */
		auio.uio_resid += iov->iov_len;
		if (iov->iov_len > SSIZE_MAX || auio.uio_resid > SSIZE_MAX) {
			error = EINVAL;
			goto out1;
		}
	}

	if (ktrpoint(KTR_GENIO)) {
		iovlen = auio.uio_iovcnt * sizeof(struct iovec);
		ktriov = (struct iovec *)malloc(iovlen, M_TEMP, M_WAITOK);
		memcpy((void *)ktriov, (void *)auio.uio_iov, iovlen);
	}

	len = auio.uio_resid;
	error = (*so->so_receive)(so, &from, &auio, NULL,
			  NETBSD32PTR64(mp->msg_control) ? &control : NULL,
			  &mp->msg_flags);
	if (error) {
		if (auio.uio_resid != len && (error == ERESTART ||
		    error == EINTR || error == EWOULDBLOCK))
			error = 0;
	}

	if (ktriov != NULL) {
		ktrgeniov(s, UIO_READ, ktriov, len - auio.uio_resid, error);
		FREE(ktriov, M_TEMP);
	}

	if (error)
		goto out;
	*retsize = len - auio.uio_resid;
	if (NETBSD32PTR64(mp->msg_name)) {
		len = mp->msg_namelen;
		if (len <= 0 || from == 0)
			len = 0;
		else {
			if (len > from->m_len)
				len = from->m_len;
			/* else if len < from->m_len ??? */
			error = copyout(mtod(from, void *),
			    (void *)NETBSD32PTR64(mp->msg_name),
			    (unsigned)len);
			if (error)
				goto out;
		}
		mp->msg_namelen = len;
		if (namelenp &&
		    (error = copyout((void *)&len, namelenp, sizeof(int))))
			goto out;
	}
Пример #25
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);
}
Пример #26
0
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;
}
Пример #27
0
int
svr4_32_sock_ioctl(file_t *fp, struct lwp *l, register_t *retval, int fd, u_long cmd, void *data)
{
	int error;
	int (*ctl)(file_t *, u_long, void *) = fp->f_ops->fo_ioctl;

	*retval = 0;

	switch (cmd) {
	case SVR4_SIOCGIFNUM:
		{
			struct ifnet *ifp;
			int ifnum = 0;
			int s;

			/*
			 * This does not return the number of physical
			 * interfaces (if_index), but the number of interfaces
			 * + addresses like ifconf() does, because this number
			 * is used by code that will call SVR4_SIOCGIFCONF to
			 * find the space needed for SVR4_SIOCGIFCONF. So we
			 * count the number of ifreq entries that the next
			 * SVR4_SIOCGIFCONF will return. Maybe a more correct
			 * fix is to make SVR4_SIOCGIFCONF return only one
			 * entry per physical interface?
			 */

			s = pserialize_read_enter();
			IFNET_READER_FOREACH(ifp)
				ifnum += svr4_count_ifnum(ifp);
			pserialize_read_exit(s);

			DPRINTF(("SIOCGIFNUM %d\n", ifnum));
			return copyout(&ifnum, data, sizeof(ifnum));
		}

	case SVR4_32_SIOCGIFFLAGS:
		{
			struct oifreq br;
			struct svr4_32_ifreq sr;

			if ((error = copyin(data, &sr, sizeof(sr))) != 0)
				return error;

			(void) strncpy(br.ifr_name, sr.svr4_ifr_name,
			    sizeof(br.ifr_name));

			if ((error = (*ctl)(fp, SIOCGIFFLAGS, &br)) != 0) {
				DPRINTF(("SIOCGIFFLAGS %s: error %d\n",
					 sr.svr4_ifr_name, error));
				return error;
			}

			sr.svr4_ifr_flags = bsd_to_svr4_flags(br.ifr_flags);
			DPRINTF(("SIOCGIFFLAGS %s = %x\n",
				sr.svr4_ifr_name, sr.svr4_ifr_flags));
			return copyout(&sr, data, sizeof(sr));
		}

	case SVR4_32_SIOCGIFCONF:
		{
			struct svr4_32_ifconf sc;
			struct oifconf ifc;

			if ((error = copyin(data, &sc, sizeof(sc))) != 0)
				return error;

			DPRINTF(("ifreq %ld svr4_32_ifreq %ld ifc_len %d\n",
				(unsigned long)sizeof(struct oifreq),
				(unsigned long)sizeof(struct svr4_32_ifreq),
				sc.svr4_32_ifc_len));

			ifc.ifc_len = sc.svr4_32_ifc_len;
			ifc.ifc_buf = NETBSD32PTR64(sc.ifc_ifcu.ifcu_buf);

			if ((error = (*ctl)(fp, OOSIOCGIFCONF, &ifc)) != 0)
				return error;

			DPRINTF(("SIOCGIFCONF\n"));
			return 0;
		}


	default:
		DPRINTF(("Unknown svr4_32 sockio %lx\n", cmd));
		return 0;	/* ENOSYS really */
	}
}
Пример #28
0
/*
 * This is a brutal clone of compat_43_sys_recvmsg().
 */
int
compat_43_netbsd32_orecvmsg(struct lwp *l, const struct compat_43_netbsd32_orecvmsg_args *uap, register_t *retval)
{
	/* {
		syscallarg(int) s;
		syscallarg(netbsd32_omsghdrp_t) msg;
		syscallarg(int) flags;
	} */
	struct netbsd32_omsghdr omsg;
	struct msghdr msg;
	struct mbuf *from, *control;
	struct iovec *iov, aiov[UIO_SMALLIOV];
	int error;

	error = copyin(SCARG_P32(uap, msg), &omsg, sizeof (struct omsghdr));
	if (error)
		return (error);

	if (NETBSD32PTR64(omsg.msg_accrights) == NULL)
		omsg.msg_accrightslen = 0;
	/* it was this way in 4.4BSD */
	if (omsg.msg_accrightslen > MLEN)
		return EINVAL;

	iov = netbsd32_get_iov(NETBSD32PTR64(omsg.msg_iov), omsg.msg_iovlen,
	    aiov, __arraycount(aiov));
	if (iov == NULL)
		return EFAULT;

	msg.msg_name	= NETBSD32PTR64(omsg.msg_name);
	msg.msg_namelen = omsg.msg_namelen;
	msg.msg_iovlen	= omsg.msg_iovlen;
	msg.msg_iov	= iov;
	msg.msg_flags	= SCARG(uap, flags) & MSG_USERFLAGS;

	error = do_sys_recvmsg(l, SCARG(uap, s), &msg, &from,
	    NETBSD32PTR64(omsg.msg_accrights) != NULL ? &control : NULL,
	    retval);
	if (error != 0)
		return error;

	/*
	 * If there is any control information and it's SCM_RIGHTS,
	 * pass it back to the program.
	 * XXX: maybe there can be more than one chunk of control data?
	 */
	if (NETBSD32PTR64(omsg.msg_accrights) != NULL && control != NULL) {
		struct cmsghdr *cmsg = mtod(control, void *);

		if (cmsg->cmsg_level == SOL_SOCKET
		    && cmsg->cmsg_type == SCM_RIGHTS
		    && cmsg->cmsg_len < omsg.msg_accrightslen
		    && copyout(CMSG_DATA(cmsg),
			    NETBSD32PTR64(omsg.msg_accrights),
			    cmsg->cmsg_len) == 0) {
			omsg.msg_accrightslen = cmsg->cmsg_len;
			free_control_mbuf(l, control, control->m_next);
		} else {
			omsg.msg_accrightslen = 0;
			free_control_mbuf(l, control, control);
		}
	} else