Index: head/sys/compat/cloudabi64/cloudabi64_fd.c =================================================================== --- head/sys/compat/cloudabi64/cloudabi64_fd.c (revision 304557) +++ head/sys/compat/cloudabi64/cloudabi64_fd.c (revision 304558) @@ -1,146 +1,145 @@ /*- * Copyright (c) 2015 Nuxi, https://nuxi.nl/ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include +#include /* Copies in 64-bit iovec structures from userspace. */ static int cloudabi64_copyinuio(const cloudabi64_iovec_t *iovp, size_t iovcnt, struct uio **uiop) { cloudabi64_iovec_t iovobj; struct uio *uio; struct iovec *iov; size_t i; int error; /* Allocate uio and iovecs. */ if (iovcnt > UIO_MAXIOV) return (EINVAL); uio = malloc(sizeof(struct uio) + iovcnt * sizeof(struct iovec), M_IOV, M_WAITOK); iov = (struct iovec *)(uio + 1); /* Initialize uio. */ uio->uio_iov = iov; uio->uio_iovcnt = iovcnt; uio->uio_segflg = UIO_USERSPACE; uio->uio_offset = -1; uio->uio_resid = 0; /* Copy in iovecs. */ for (i = 0; i < iovcnt; i++) { error = copyin(&iovp[i], &iovobj, sizeof(iovobj)); if (error != 0) { free(uio, M_IOV); return (error); } - iov[i].iov_base = (void *)iovobj.iov_base; + iov[i].iov_base = TO_PTR(iovobj.iov_base); iov[i].iov_len = iovobj.iov_len; if (iov[i].iov_len > INT64_MAX - uio->uio_resid) { free(uio, M_IOV); return (EINVAL); } uio->uio_resid += iov[i].iov_len; } *uiop = uio; return (0); } int cloudabi64_sys_fd_pread(struct thread *td, struct cloudabi64_sys_fd_pread_args *uap) { struct uio *uio; int error; error = cloudabi64_copyinuio(uap->iov, uap->iovcnt, &uio); if (error != 0) return (error); error = kern_preadv(td, uap->fd, uio, uap->offset); free(uio, M_IOV); return (error); } int cloudabi64_sys_fd_pwrite(struct thread *td, struct cloudabi64_sys_fd_pwrite_args *uap) { struct uio *uio; int error; - error = cloudabi64_copyinuio((const cloudabi64_iovec_t *)uap->iov, - uap->iovcnt, &uio); + error = cloudabi64_copyinuio(TO_PTR(uap->iov), uap->iovcnt, &uio); if (error != 0) return (error); error = kern_pwritev(td, uap->fd, uio, uap->offset); free(uio, M_IOV); return (error); } int cloudabi64_sys_fd_read(struct thread *td, struct cloudabi64_sys_fd_read_args *uap) { struct uio *uio; int error; error = cloudabi64_copyinuio(uap->iov, uap->iovcnt, &uio); if (error != 0) return (error); error = kern_readv(td, uap->fd, uio); free(uio, M_IOV); return (error); } int cloudabi64_sys_fd_write(struct thread *td, struct cloudabi64_sys_fd_write_args *uap) { struct uio *uio; int error; - error = cloudabi64_copyinuio((const cloudabi64_iovec_t *)uap->iov, - uap->iovcnt, &uio); + error = cloudabi64_copyinuio(TO_PTR(uap->iov), uap->iovcnt, &uio); if (error != 0) return (error); error = kern_writev(td, uap->fd, uio); free(uio, M_IOV); return (error); } Index: head/sys/compat/cloudabi64/cloudabi64_poll.c =================================================================== --- head/sys/compat/cloudabi64/cloudabi64_poll.c (revision 304557) +++ head/sys/compat/cloudabi64/cloudabi64_poll.c (revision 304558) @@ -1,407 +1,408 @@ /*- * Copyright (c) 2015 Nuxi, https://nuxi.nl/ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include +#include /* Converts a FreeBSD signal number to a CloudABI signal number. */ static cloudabi_signal_t convert_signal(int sig) { static const cloudabi_signal_t signals[] = { [SIGABRT] = CLOUDABI_SIGABRT, [SIGALRM] = CLOUDABI_SIGALRM, [SIGBUS] = CLOUDABI_SIGBUS, [SIGCHLD] = CLOUDABI_SIGCHLD, [SIGCONT] = CLOUDABI_SIGCONT, [SIGFPE] = CLOUDABI_SIGFPE, [SIGHUP] = CLOUDABI_SIGHUP, [SIGILL] = CLOUDABI_SIGILL, [SIGINT] = CLOUDABI_SIGINT, [SIGKILL] = CLOUDABI_SIGKILL, [SIGPIPE] = CLOUDABI_SIGPIPE, [SIGQUIT] = CLOUDABI_SIGQUIT, [SIGSEGV] = CLOUDABI_SIGSEGV, [SIGSTOP] = CLOUDABI_SIGSTOP, [SIGSYS] = CLOUDABI_SIGSYS, [SIGTERM] = CLOUDABI_SIGTERM, [SIGTRAP] = CLOUDABI_SIGTRAP, [SIGTSTP] = CLOUDABI_SIGTSTP, [SIGTTIN] = CLOUDABI_SIGTTIN, [SIGTTOU] = CLOUDABI_SIGTTOU, [SIGURG] = CLOUDABI_SIGURG, [SIGUSR1] = CLOUDABI_SIGUSR1, [SIGUSR2] = CLOUDABI_SIGUSR2, [SIGVTALRM] = CLOUDABI_SIGVTALRM, [SIGXCPU] = CLOUDABI_SIGXCPU, [SIGXFSZ] = CLOUDABI_SIGXFSZ, }; /* Convert unknown signals to SIGABRT. */ if (sig < 0 || sig >= nitems(signals) || signals[sig] == 0) return (SIGABRT); return (signals[sig]); } struct cloudabi64_kevent_args { const cloudabi64_subscription_t *in; cloudabi64_event_t *out; bool once; }; /* Converts CloudABI's subscription objects to FreeBSD's struct kevent. */ static int cloudabi64_kevent_copyin(void *arg, struct kevent *kevp, int count) { cloudabi64_subscription_t sub; struct cloudabi64_kevent_args *args; cloudabi_timestamp_t ts; int error; args = arg; while (count-- > 0) { /* TODO(ed): Copy in multiple entries at once. */ error = copyin(args->in++, &sub, sizeof(sub)); if (error != 0) return (error); memset(kevp, 0, sizeof(*kevp)); - kevp->udata = (void *)sub.userdata; + kevp->udata = TO_PTR(sub.userdata); switch (sub.type) { case CLOUDABI_EVENTTYPE_CLOCK: kevp->filter = EVFILT_TIMER; kevp->ident = sub.clock.identifier; kevp->fflags = NOTE_NSECONDS; if ((sub.clock.flags & CLOUDABI_SUBSCRIPTION_CLOCK_ABSTIME) != 0 && sub.clock.timeout > 0) { /* Convert absolute timestamp to a relative. */ error = cloudabi_clock_time_get(curthread, sub.clock.clock_id, &ts); if (error != 0) return (error); ts = ts > sub.clock.timeout ? 0 : sub.clock.timeout - ts; } else { /* Relative timestamp. */ ts = sub.clock.timeout; } kevp->data = ts > INTPTR_MAX ? INTPTR_MAX : ts; break; case CLOUDABI_EVENTTYPE_FD_READ: kevp->filter = EVFILT_READ; kevp->ident = sub.fd_readwrite.fd; if ((sub.fd_readwrite.flags & CLOUDABI_SUBSCRIPTION_FD_READWRITE_POLL) != 0) kevp->fflags = NOTE_FILE_POLL; break; case CLOUDABI_EVENTTYPE_FD_WRITE: kevp->filter = EVFILT_WRITE; kevp->ident = sub.fd_readwrite.fd; break; case CLOUDABI_EVENTTYPE_PROC_TERMINATE: kevp->filter = EVFILT_PROCDESC; kevp->ident = sub.proc_terminate.fd; kevp->fflags = NOTE_EXIT; break; } if (args->once) { /* Ignore flags. Simply use oneshot mode. */ kevp->flags = EV_ADD | EV_ONESHOT; } else { /* Translate flags. */ if ((sub.flags & CLOUDABI_SUBSCRIPTION_ADD) != 0) kevp->flags |= EV_ADD; if ((sub.flags & CLOUDABI_SUBSCRIPTION_CLEAR) != 0) kevp->flags |= EV_CLEAR; if ((sub.flags & CLOUDABI_SUBSCRIPTION_DELETE) != 0) kevp->flags |= EV_DELETE; if ((sub.flags & CLOUDABI_SUBSCRIPTION_DISABLE) != 0) kevp->flags |= EV_DISABLE; if ((sub.flags & CLOUDABI_SUBSCRIPTION_ENABLE) != 0) kevp->flags |= EV_ENABLE; if ((sub.flags & CLOUDABI_SUBSCRIPTION_ONESHOT) != 0) kevp->flags |= EV_ONESHOT; } ++kevp; } return (0); } /* Converts FreeBSD's struct kevent to CloudABI's event objects. */ static int cloudabi64_kevent_copyout(void *arg, struct kevent *kevp, int count) { cloudabi64_event_t ev; struct cloudabi64_kevent_args *args; int error; args = arg; while (count-- > 0) { /* Convert fields that should always be present. */ memset(&ev, 0, sizeof(ev)); ev.userdata = (uintptr_t)kevp->udata; switch (kevp->filter) { case EVFILT_TIMER: ev.type = CLOUDABI_EVENTTYPE_CLOCK; ev.clock.identifier = kevp->ident; break; case EVFILT_READ: ev.type = CLOUDABI_EVENTTYPE_FD_READ; ev.fd_readwrite.fd = kevp->ident; break; case EVFILT_WRITE: ev.type = CLOUDABI_EVENTTYPE_FD_WRITE; ev.fd_readwrite.fd = kevp->ident; break; case EVFILT_PROCDESC: ev.type = CLOUDABI_EVENTTYPE_PROC_TERMINATE; ev.proc_terminate.fd = kevp->ident; break; } if ((kevp->flags & EV_ERROR) == 0) { /* Success. */ switch (kevp->filter) { case EVFILT_READ: case EVFILT_WRITE: ev.fd_readwrite.nbytes = kevp->data; if ((kevp->flags & EV_EOF) != 0) { ev.fd_readwrite.flags |= CLOUDABI_EVENT_FD_READWRITE_HANGUP; } break; case EVFILT_PROCDESC: if (WIFSIGNALED(kevp->data)) { /* Process got signalled. */ ev.proc_terminate.signal = convert_signal(WTERMSIG(kevp->data)); ev.proc_terminate.exitcode = 0; } else { /* Process exited. */ ev.proc_terminate.signal = 0; ev.proc_terminate.exitcode = WEXITSTATUS(kevp->data); } break; } } else { /* Error. */ ev.error = cloudabi_convert_errno(kevp->data); } ++kevp; /* TODO(ed): Copy out multiple entries at once. */ error = copyout(&ev, args->out++, sizeof(ev)); if (error != 0) return (error); } return (0); } int cloudabi64_sys_poll(struct thread *td, struct cloudabi64_sys_poll_args *uap) { struct cloudabi64_kevent_args args = { .in = uap->in, .out = uap->out, .once = true, }; struct kevent_copyops copyops = { .k_copyin = cloudabi64_kevent_copyin, .k_copyout = cloudabi64_kevent_copyout, .arg = &args, }; /* * Bandaid to support CloudABI futex constructs that are not * implemented through FreeBSD's kqueue(). */ if (uap->nsubscriptions == 1) { cloudabi64_subscription_t sub; cloudabi64_event_t ev = {}; int error; error = copyin(uap->in, &sub, sizeof(sub)); if (error != 0) return (error); ev.userdata = sub.userdata; ev.type = sub.type; if (sub.type == CLOUDABI_EVENTTYPE_CONDVAR) { /* Wait on a condition variable. */ ev.condvar.condvar = sub.condvar.condvar; ev.error = cloudabi_convert_errno( cloudabi_futex_condvar_wait( - td, (cloudabi_condvar_t *)sub.condvar.condvar, + td, TO_PTR(sub.condvar.condvar), sub.condvar.condvar_scope, - (cloudabi_lock_t *)sub.condvar.lock, + TO_PTR(sub.condvar.lock), sub.condvar.lock_scope, CLOUDABI_CLOCK_MONOTONIC, UINT64_MAX, 0)); td->td_retval[0] = 1; return (copyout(&ev, uap->out, sizeof(ev))); } else if (sub.type == CLOUDABI_EVENTTYPE_LOCK_RDLOCK) { /* Acquire a read lock. */ ev.lock.lock = sub.lock.lock; ev.error = cloudabi_convert_errno( cloudabi_futex_lock_rdlock( - td, (cloudabi_lock_t *)sub.lock.lock, + td, TO_PTR(sub.lock.lock), sub.lock.lock_scope, CLOUDABI_CLOCK_MONOTONIC, UINT64_MAX, 0)); td->td_retval[0] = 1; return (copyout(&ev, uap->out, sizeof(ev))); } else if (sub.type == CLOUDABI_EVENTTYPE_LOCK_WRLOCK) { /* Acquire a write lock. */ ev.lock.lock = sub.lock.lock; ev.error = cloudabi_convert_errno( cloudabi_futex_lock_wrlock( - td, (cloudabi_lock_t *)sub.lock.lock, + td, TO_PTR(sub.lock.lock), sub.lock.lock_scope, CLOUDABI_CLOCK_MONOTONIC, UINT64_MAX, 0)); td->td_retval[0] = 1; return (copyout(&ev, uap->out, sizeof(ev))); } } else if (uap->nsubscriptions == 2) { cloudabi64_subscription_t sub[2]; cloudabi64_event_t ev[2] = {}; int error; error = copyin(uap->in, &sub, sizeof(sub)); if (error != 0) return (error); ev[0].userdata = sub[0].userdata; ev[0].type = sub[0].type; ev[1].userdata = sub[1].userdata; ev[1].type = sub[1].type; if (sub[0].type == CLOUDABI_EVENTTYPE_CONDVAR && sub[1].type == CLOUDABI_EVENTTYPE_CLOCK && sub[1].clock.flags == CLOUDABI_SUBSCRIPTION_CLOCK_ABSTIME) { /* Wait for a condition variable with timeout. */ ev[0].condvar.condvar = sub[0].condvar.condvar; ev[1].clock.identifier = sub[1].clock.identifier; error = cloudabi_futex_condvar_wait( - td, (cloudabi_condvar_t *)sub[0].condvar.condvar, + td, TO_PTR(sub[0].condvar.condvar), sub[0].condvar.condvar_scope, - (cloudabi_lock_t *)sub[0].condvar.lock, + TO_PTR(sub[0].condvar.lock), sub[0].condvar.lock_scope, sub[1].clock.clock_id, sub[1].clock.timeout, sub[1].clock.precision); if (error == ETIMEDOUT) { td->td_retval[0] = 1; return (copyout(&ev[1], uap->out, sizeof(ev[1]))); } ev[0].error = cloudabi_convert_errno(error); td->td_retval[0] = 1; return (copyout(&ev[0], uap->out, sizeof(ev[0]))); } else if (sub[0].type == CLOUDABI_EVENTTYPE_LOCK_RDLOCK && sub[1].type == CLOUDABI_EVENTTYPE_CLOCK && sub[1].clock.flags == CLOUDABI_SUBSCRIPTION_CLOCK_ABSTIME) { /* Acquire a read lock with a timeout. */ ev[0].lock.lock = sub[0].lock.lock; ev[1].clock.identifier = sub[1].clock.identifier; error = cloudabi_futex_lock_rdlock( - td, (cloudabi_lock_t *)sub[0].lock.lock, + td, TO_PTR(sub[0].lock.lock), sub[0].lock.lock_scope, sub[1].clock.clock_id, sub[1].clock.timeout, sub[1].clock.precision); if (error == ETIMEDOUT) { td->td_retval[0] = 1; return (copyout(&ev[1], uap->out, sizeof(ev[1]))); } ev[0].error = cloudabi_convert_errno(error); td->td_retval[0] = 1; return (copyout(&ev[0], uap->out, sizeof(ev[0]))); } else if (sub[0].type == CLOUDABI_EVENTTYPE_LOCK_WRLOCK && sub[1].type == CLOUDABI_EVENTTYPE_CLOCK && sub[1].clock.flags == CLOUDABI_SUBSCRIPTION_CLOCK_ABSTIME) { /* Acquire a write lock with a timeout. */ ev[0].lock.lock = sub[0].lock.lock; ev[1].clock.identifier = sub[1].clock.identifier; error = cloudabi_futex_lock_wrlock( - td, (cloudabi_lock_t *)sub[0].lock.lock, + td, TO_PTR(sub[0].lock.lock), sub[0].lock.lock_scope, sub[1].clock.clock_id, sub[1].clock.timeout, sub[1].clock.precision); if (error == ETIMEDOUT) { td->td_retval[0] = 1; return (copyout(&ev[1], uap->out, sizeof(ev[1]))); } ev[0].error = cloudabi_convert_errno(error); td->td_retval[0] = 1; return (copyout(&ev[0], uap->out, sizeof(ev[0]))); } } return (kern_kevent_anonymous(td, uap->nsubscriptions, ©ops)); } int cloudabi64_sys_poll_fd(struct thread *td, struct cloudabi64_sys_poll_fd_args *uap) { struct cloudabi64_kevent_args args = { .in = uap->in, .out = uap->out, .once = false, }; struct kevent_copyops copyops = { .k_copyin = cloudabi64_kevent_copyin, .k_copyout = cloudabi64_kevent_copyout, .arg = &args, }; cloudabi64_subscription_t subtimo; struct timespec timeout; int error; if (uap->timeout != NULL) { /* Poll with a timeout. */ error = copyin(uap->timeout, &subtimo, sizeof(subtimo)); if (error != 0) return (error); if (subtimo.type != CLOUDABI_EVENTTYPE_CLOCK || subtimo.clock.flags != 0) return (EINVAL); timeout.tv_sec = subtimo.clock.timeout / 1000000000; timeout.tv_nsec = subtimo.clock.timeout % 1000000000; return (kern_kevent(td, uap->fd, uap->nin, uap->nout, ©ops, &timeout)); } else { /* Poll without a timeout. */ return (kern_kevent(td, uap->fd, uap->nin, uap->nout, ©ops, NULL)); } } Index: head/sys/compat/cloudabi64/cloudabi64_sock.c =================================================================== --- head/sys/compat/cloudabi64/cloudabi64_sock.c (revision 304557) +++ head/sys/compat/cloudabi64/cloudabi64_sock.c (revision 304558) @@ -1,145 +1,148 @@ /*- * Copyright (c) 2015 Nuxi, https://nuxi.nl/ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include +#include static MALLOC_DEFINE(M_SOCKET, "socket", "CloudABI socket"); int cloudabi64_sys_sock_recv(struct thread *td, struct cloudabi64_sys_sock_recv_args *uap) { struct sockaddr_storage ss; cloudabi64_recv_in_t ri; cloudabi64_recv_out_t ro = {}; cloudabi64_iovec_t iovobj; struct msghdr msghdr = {}; + const cloudabi64_iovec_t *user_iov; size_t i; int error; error = copyin(uap->in, &ri, sizeof(ri)); if (error != 0) return (error); /* Convert results in cloudabi_recv_in_t to struct msghdr. */ if (ri.ri_datalen > UIO_MAXIOV) return (EINVAL); msghdr.msg_iovlen = ri.ri_datalen; msghdr.msg_iov = malloc(msghdr.msg_iovlen * sizeof(struct iovec), M_SOCKET, M_WAITOK); + user_iov = TO_PTR(ri.ri_data); for (i = 0; i < msghdr.msg_iovlen; i++) { - error = copyin(&((cloudabi64_iovec_t *)ri.ri_data)[i], &iovobj, - sizeof(iovobj)); + error = copyin(&user_iov[i], &iovobj, sizeof(iovobj)); if (error != 0) { free(msghdr.msg_iov, M_SOCKET); return (error); } - msghdr.msg_iov[i].iov_base = (void *)iovobj.iov_base; + msghdr.msg_iov[i].iov_base = TO_PTR(iovobj.iov_base); msghdr.msg_iov[i].iov_len = iovobj.iov_len; } msghdr.msg_name = &ss; msghdr.msg_namelen = sizeof(ss); if (ri.ri_flags & CLOUDABI_MSG_PEEK) msghdr.msg_flags |= MSG_PEEK; if (ri.ri_flags & CLOUDABI_MSG_WAITALL) msghdr.msg_flags |= MSG_WAITALL; /* TODO(ed): Add file descriptor passing. */ error = kern_recvit(td, uap->sock, &msghdr, UIO_SYSSPACE, NULL); free(msghdr.msg_iov, M_SOCKET); if (error != 0) return (error); /* Convert results in msghdr to cloudabi_recv_out_t. */ ro.ro_datalen = td->td_retval[0]; cloudabi_convert_sockaddr((struct sockaddr *)&ss, MIN(msghdr.msg_namelen, sizeof(ss)), &ro.ro_peername); td->td_retval[0] = 0; return (copyout(&ro, uap->out, sizeof(ro))); } int cloudabi64_sys_sock_send(struct thread *td, struct cloudabi64_sys_sock_send_args *uap) { cloudabi64_send_in_t si; cloudabi64_send_out_t so = {}; cloudabi64_ciovec_t iovobj; struct msghdr msghdr = {}; + const cloudabi64_ciovec_t *user_iov; size_t i; int error, flags; error = copyin(uap->in, &si, sizeof(si)); if (error != 0) return (error); /* Convert results in cloudabi_send_in_t to struct msghdr. */ if (si.si_datalen > UIO_MAXIOV) return (EINVAL); msghdr.msg_iovlen = si.si_datalen; msghdr.msg_iov = malloc(msghdr.msg_iovlen * sizeof(struct iovec), M_SOCKET, M_WAITOK); + user_iov = TO_PTR(si.si_data); for (i = 0; i < msghdr.msg_iovlen; i++) { - error = copyin(&((cloudabi64_ciovec_t *)si.si_data)[i], &iovobj, - sizeof(iovobj)); + error = copyin(&user_iov[i], &iovobj, sizeof(iovobj)); if (error != 0) { free(msghdr.msg_iov, M_SOCKET); return (error); } - msghdr.msg_iov[i].iov_base = (void *)iovobj.iov_base; + msghdr.msg_iov[i].iov_base = TO_PTR(iovobj.iov_base); msghdr.msg_iov[i].iov_len = iovobj.iov_len; } flags = MSG_NOSIGNAL; if (si.si_flags & CLOUDABI_MSG_EOR) flags |= MSG_EOR; /* TODO(ed): Add file descriptor passing. */ error = kern_sendit(td, uap->sock, &msghdr, flags, NULL, UIO_USERSPACE); free(msghdr.msg_iov, M_SOCKET); if (error != 0) return (error); /* Convert results in msghdr to cloudabi_send_out_t. */ so.so_datalen = td->td_retval[0]; td->td_retval[0] = 0; return (copyout(&so, uap->out, sizeof(so))); } Index: head/sys/compat/cloudabi64/cloudabi64_util.h =================================================================== --- head/sys/compat/cloudabi64/cloudabi64_util.h (revision 304557) +++ head/sys/compat/cloudabi64/cloudabi64_util.h (revision 304558) @@ -1,48 +1,50 @@ /*- * Copyright (c) 2015 Nuxi, https://nuxi.nl/ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ #ifndef _CLOUDABI64_UTIL_H_ #define _CLOUDABI64_UTIL_H_ #include #include #include struct image_params; struct thread; extern Elf64_Brandinfo cloudabi64_brand; +#define TO_PTR(x) ((void *)(uintptr_t)(x)) + /* Stack initialization during process execution. */ register_t *cloudabi64_copyout_strings(struct image_params *); int cloudabi64_fixup(register_t **, struct image_params *); int cloudabi64_thread_setregs(struct thread *, const cloudabi64_threadattr_t *, uint64_t); #endif