-
- if ((u_int)msg.msg_iovlen >= UIO_SMALLIOV) {
- if ((u_int)msg.msg_iovlen >= UIO_MAXIOV) {
- KERNEL_DEBUG(DBG_FNC_SENDMSG | DBG_FUNC_END, EMSGSIZE,0,0,0,0);
- return (EMSGSIZE);
- }
- MALLOC(iov, struct iovec *,
- sizeof(struct iovec) * (u_int)msg.msg_iovlen, M_IOV,
- M_WAITOK);
- } else
- iov = aiov;
- if (msg.msg_iovlen &&
- (error = copyin((caddr_t)msg.msg_iov, (caddr_t)iov,
- (unsigned)(msg.msg_iovlen * sizeof (struct iovec)))))
- goto done;
- msg.msg_iov = iov;
-#ifdef COMPAT_OLDSOCK
- msg.msg_flags = 0;
+
+ /* only need to copy if user process is not 64-bit */
+ if (!IS_64BIT_PROCESS(p)) {
+ user_msg.msg_flags = msg.msg_flags;
+ user_msg.msg_controllen = msg.msg_controllen;
+ user_msg.msg_control = CAST_USER_ADDR_T(msg.msg_control);
+ user_msg.msg_iovlen = msg.msg_iovlen;
+ user_msg.msg_iov = CAST_USER_ADDR_T(msg.msg_iov);
+ user_msg.msg_namelen = msg.msg_namelen;
+ user_msg.msg_name = CAST_USER_ADDR_T(msg.msg_name);
+ }
+
+ if (user_msg.msg_iovlen <= 0 || user_msg.msg_iovlen > UIO_MAXIOV) {
+ KERNEL_DEBUG(DBG_FNC_SENDMSG | DBG_FUNC_END, EMSGSIZE,0,0,0,0);
+ return (EMSGSIZE);
+ }
+
+ /* allocate a uio large enough to hold the number of iovecs passed */
+ auio = uio_create(user_msg.msg_iovlen, 0,
+ (IS_64BIT_PROCESS(p) ? UIO_USERSPACE64 : UIO_USERSPACE32),
+ UIO_WRITE);
+ if (auio == NULL) {
+ error = ENOBUFS;
+ goto done;
+ }
+
+ if (user_msg.msg_iovlen) {
+ /* get location of iovecs within the uio. then copyin the iovecs from
+ * user space.
+ */
+ iovp = uio_iovsaddr(auio);
+ if (iovp == NULL) {
+ error = ENOBUFS;
+ goto done;
+ }
+ error = copyin(user_msg.msg_iov, (caddr_t)iovp, (user_msg.msg_iovlen * size_of_iovec));
+ if (error)
+ goto done;
+ user_msg.msg_iov = CAST_USER_ADDR_T(iovp);
+
+ /* finish setup of uio_t */
+ uio_calculateresid(auio);
+ }
+ else {
+ user_msg.msg_iov = 0;
+ }
+
+#if COMPAT_43_SOCKET
+ user_msg.msg_flags = 0;