mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	put iov_iter into msghdr
Note that the code _using_ ->msg_iter at that point will be very unhappy with anything other than unshifted iovec-backed iov_iter. We still need to convert users to proper primitives. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
		
							parent
							
								
									d838df2e5d
								
							
						
					
					
						commit
						c0371da604
					
				
					 33 changed files with 90 additions and 112 deletions
				
			
		| 
						 | 
				
			
			@ -42,7 +42,7 @@ static int hash_sendmsg(struct kiocb *unused, struct socket *sock,
 | 
			
		|||
	struct alg_sock *ask = alg_sk(sk);
 | 
			
		||||
	struct hash_ctx *ctx = ask->private;
 | 
			
		||||
	unsigned long iovlen;
 | 
			
		||||
	struct iovec *iov;
 | 
			
		||||
	const struct iovec *iov;
 | 
			
		||||
	long copied = 0;
 | 
			
		||||
	int err;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -58,7 +58,7 @@ static int hash_sendmsg(struct kiocb *unused, struct socket *sock,
 | 
			
		|||
 | 
			
		||||
	ctx->more = 0;
 | 
			
		||||
 | 
			
		||||
	for (iov = msg->msg_iov, iovlen = msg->msg_iovlen; iovlen > 0;
 | 
			
		||||
	for (iov = msg->msg_iter.iov, iovlen = msg->msg_iter.nr_segs; iovlen > 0;
 | 
			
		||||
	     iovlen--, iov++) {
 | 
			
		||||
		unsigned long seglen = iov->iov_len;
 | 
			
		||||
		char __user *from = iov->iov_base;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -429,13 +429,13 @@ static int skcipher_recvmsg(struct kiocb *unused, struct socket *sock,
 | 
			
		|||
	struct skcipher_sg_list *sgl;
 | 
			
		||||
	struct scatterlist *sg;
 | 
			
		||||
	unsigned long iovlen;
 | 
			
		||||
	struct iovec *iov;
 | 
			
		||||
	const struct iovec *iov;
 | 
			
		||||
	int err = -EAGAIN;
 | 
			
		||||
	int used;
 | 
			
		||||
	long copied = 0;
 | 
			
		||||
 | 
			
		||||
	lock_sock(sk);
 | 
			
		||||
	for (iov = msg->msg_iov, iovlen = msg->msg_iovlen; iovlen > 0;
 | 
			
		||||
	for (iov = msg->msg_iter.iov, iovlen = msg->msg_iter.nr_segs; iovlen > 0;
 | 
			
		||||
	     iovlen--, iov++) {
 | 
			
		||||
		unsigned long seglen = iov->iov_len;
 | 
			
		||||
		char __user *from = iov->iov_base;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1095,9 +1095,7 @@ static int macvtap_sendmsg(struct kiocb *iocb, struct socket *sock,
 | 
			
		|||
			   struct msghdr *m, size_t total_len)
 | 
			
		||||
{
 | 
			
		||||
	struct macvtap_queue *q = container_of(sock, struct macvtap_queue, sock);
 | 
			
		||||
	struct iov_iter from;
 | 
			
		||||
	iov_iter_init(&from, WRITE, m->msg_iov, m->msg_iovlen, total_len);
 | 
			
		||||
	return macvtap_get_user(q, m, &from, m->msg_flags & MSG_DONTWAIT);
 | 
			
		||||
	return macvtap_get_user(q, m, &m->msg_iter, m->msg_flags & MSG_DONTWAIT);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int macvtap_recvmsg(struct kiocb *iocb, struct socket *sock,
 | 
			
		||||
| 
						 | 
				
			
			@ -1105,12 +1103,10 @@ static int macvtap_recvmsg(struct kiocb *iocb, struct socket *sock,
 | 
			
		|||
			   int flags)
 | 
			
		||||
{
 | 
			
		||||
	struct macvtap_queue *q = container_of(sock, struct macvtap_queue, sock);
 | 
			
		||||
	struct iov_iter to;
 | 
			
		||||
	int ret;
 | 
			
		||||
	if (flags & ~(MSG_DONTWAIT|MSG_TRUNC))
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
	iov_iter_init(&to, READ, m->msg_iov, m->msg_iovlen, total_len);
 | 
			
		||||
	ret = macvtap_do_read(q, &to, flags & MSG_DONTWAIT);
 | 
			
		||||
	ret = macvtap_do_read(q, &m->msg_iter, flags & MSG_DONTWAIT);
 | 
			
		||||
	if (ret > total_len) {
 | 
			
		||||
		m->msg_flags |= MSG_TRUNC;
 | 
			
		||||
		ret = flags & MSG_TRUNC ? ret : total_len;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1449,13 +1449,11 @@ static int tun_sendmsg(struct kiocb *iocb, struct socket *sock,
 | 
			
		|||
	int ret;
 | 
			
		||||
	struct tun_file *tfile = container_of(sock, struct tun_file, socket);
 | 
			
		||||
	struct tun_struct *tun = __tun_get(tfile);
 | 
			
		||||
	struct iov_iter from;
 | 
			
		||||
 | 
			
		||||
	if (!tun)
 | 
			
		||||
		return -EBADFD;
 | 
			
		||||
 | 
			
		||||
	iov_iter_init(&from, WRITE, m->msg_iov, m->msg_iovlen, total_len);
 | 
			
		||||
	ret = tun_get_user(tun, tfile, m->msg_control, &from,
 | 
			
		||||
	ret = tun_get_user(tun, tfile, m->msg_control, &m->msg_iter,
 | 
			
		||||
			   m->msg_flags & MSG_DONTWAIT);
 | 
			
		||||
	tun_put(tun);
 | 
			
		||||
	return ret;
 | 
			
		||||
| 
						 | 
				
			
			@ -1467,7 +1465,6 @@ static int tun_recvmsg(struct kiocb *iocb, struct socket *sock,
 | 
			
		|||
{
 | 
			
		||||
	struct tun_file *tfile = container_of(sock, struct tun_file, socket);
 | 
			
		||||
	struct tun_struct *tun = __tun_get(tfile);
 | 
			
		||||
	struct iov_iter to;
 | 
			
		||||
	int ret;
 | 
			
		||||
 | 
			
		||||
	if (!tun)
 | 
			
		||||
| 
						 | 
				
			
			@ -1482,8 +1479,7 @@ static int tun_recvmsg(struct kiocb *iocb, struct socket *sock,
 | 
			
		|||
					 SOL_PACKET, TUN_TX_TIMESTAMP);
 | 
			
		||||
		goto out;
 | 
			
		||||
	}
 | 
			
		||||
	iov_iter_init(&to, READ, m->msg_iov, m->msg_iovlen, total_len);
 | 
			
		||||
	ret = tun_do_read(tun, tfile, &to, flags & MSG_DONTWAIT);
 | 
			
		||||
	ret = tun_do_read(tun, tfile, &m->msg_iter, flags & MSG_DONTWAIT);
 | 
			
		||||
	if (ret > total_len) {
 | 
			
		||||
		m->msg_flags |= MSG_TRUNC;
 | 
			
		||||
		ret = flags & MSG_TRUNC ? ret : total_len;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -342,7 +342,6 @@ static void handle_tx(struct vhost_net *net)
 | 
			
		|||
		.msg_namelen = 0,
 | 
			
		||||
		.msg_control = NULL,
 | 
			
		||||
		.msg_controllen = 0,
 | 
			
		||||
		.msg_iov = vq->iov,
 | 
			
		||||
		.msg_flags = MSG_DONTWAIT,
 | 
			
		||||
	};
 | 
			
		||||
	size_t len, total_len = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -396,8 +395,8 @@ static void handle_tx(struct vhost_net *net)
 | 
			
		|||
		}
 | 
			
		||||
		/* Skip header. TODO: support TSO. */
 | 
			
		||||
		s = move_iovec_hdr(vq->iov, nvq->hdr, hdr_size, out);
 | 
			
		||||
		msg.msg_iovlen = out;
 | 
			
		||||
		len = iov_length(vq->iov, out);
 | 
			
		||||
		iov_iter_init(&msg.msg_iter, WRITE, vq->iov, out, len);
 | 
			
		||||
		/* Sanity check */
 | 
			
		||||
		if (!len) {
 | 
			
		||||
			vq_err(vq, "Unexpected header len for TX: "
 | 
			
		||||
| 
						 | 
				
			
			@ -562,7 +561,6 @@ static void handle_rx(struct vhost_net *net)
 | 
			
		|||
		.msg_namelen = 0,
 | 
			
		||||
		.msg_control = NULL, /* FIXME: get and handle RX aux data. */
 | 
			
		||||
		.msg_controllen = 0,
 | 
			
		||||
		.msg_iov = vq->iov,
 | 
			
		||||
		.msg_flags = MSG_DONTWAIT,
 | 
			
		||||
	};
 | 
			
		||||
	struct virtio_net_hdr_mrg_rxbuf hdr = {
 | 
			
		||||
| 
						 | 
				
			
			@ -600,7 +598,7 @@ static void handle_rx(struct vhost_net *net)
 | 
			
		|||
			break;
 | 
			
		||||
		/* On overrun, truncate and discard */
 | 
			
		||||
		if (unlikely(headcount > UIO_MAXIOV)) {
 | 
			
		||||
			msg.msg_iovlen = 1;
 | 
			
		||||
			iov_iter_init(&msg.msg_iter, READ, vq->iov, 1, 1);
 | 
			
		||||
			err = sock->ops->recvmsg(NULL, sock, &msg,
 | 
			
		||||
						 1, MSG_DONTWAIT | MSG_TRUNC);
 | 
			
		||||
			pr_debug("Discarded rx packet: len %zd\n", sock_len);
 | 
			
		||||
| 
						 | 
				
			
			@ -626,7 +624,7 @@ static void handle_rx(struct vhost_net *net)
 | 
			
		|||
			/* Copy the header for use in VIRTIO_NET_F_MRG_RXBUF:
 | 
			
		||||
			 * needed because recvmsg can modify msg_iov. */
 | 
			
		||||
			copy_iovec_hdr(vq->iov, nvq->hdr, sock_hlen, in);
 | 
			
		||||
		msg.msg_iovlen = in;
 | 
			
		||||
		iov_iter_init(&msg.msg_iter, READ, vq->iov, in, sock_len);
 | 
			
		||||
		err = sock->ops->recvmsg(NULL, sock, &msg,
 | 
			
		||||
					 sock_len, MSG_DONTWAIT | MSG_TRUNC);
 | 
			
		||||
		/* Userspace might have consumed the packet meanwhile:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -306,8 +306,8 @@ static int afs_send_pages(struct afs_call *call, struct msghdr *msg,
 | 
			
		|||
 | 
			
		||||
			_debug("- range %u-%u%s",
 | 
			
		||||
			       offset, to, msg->msg_flags ? " [more]" : "");
 | 
			
		||||
			msg->msg_iov = (struct iovec *) iov;
 | 
			
		||||
			msg->msg_iovlen = 1;
 | 
			
		||||
			iov_iter_init(&msg->msg_iter, WRITE,
 | 
			
		||||
				      (struct iovec *) iov, 1, to - offset);
 | 
			
		||||
 | 
			
		||||
			/* have to change the state *before* sending the last
 | 
			
		||||
			 * packet as RxRPC might give us the reply before it
 | 
			
		||||
| 
						 | 
				
			
			@ -384,8 +384,8 @@ int afs_make_call(struct in_addr *addr, struct afs_call *call, gfp_t gfp,
 | 
			
		|||
 | 
			
		||||
	msg.msg_name		= NULL;
 | 
			
		||||
	msg.msg_namelen		= 0;
 | 
			
		||||
	msg.msg_iov		= (struct iovec *) iov;
 | 
			
		||||
	msg.msg_iovlen		= 1;
 | 
			
		||||
	iov_iter_init(&msg.msg_iter, WRITE, (struct iovec *)iov, 1,
 | 
			
		||||
		      call->request_size);
 | 
			
		||||
	msg.msg_control		= NULL;
 | 
			
		||||
	msg.msg_controllen	= 0;
 | 
			
		||||
	msg.msg_flags		= (call->send_pages ? MSG_MORE : 0);
 | 
			
		||||
| 
						 | 
				
			
			@ -778,8 +778,7 @@ void afs_send_empty_reply(struct afs_call *call)
 | 
			
		|||
	iov[0].iov_len		= 0;
 | 
			
		||||
	msg.msg_name		= NULL;
 | 
			
		||||
	msg.msg_namelen		= 0;
 | 
			
		||||
	msg.msg_iov		= iov;
 | 
			
		||||
	msg.msg_iovlen		= 0;
 | 
			
		||||
	iov_iter_init(&msg.msg_iter, WRITE, iov, 0, 0);	/* WTF? */
 | 
			
		||||
	msg.msg_control		= NULL;
 | 
			
		||||
	msg.msg_controllen	= 0;
 | 
			
		||||
	msg.msg_flags		= 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -815,8 +814,7 @@ void afs_send_simple_reply(struct afs_call *call, const void *buf, size_t len)
 | 
			
		|||
	iov[0].iov_len		= len;
 | 
			
		||||
	msg.msg_name		= NULL;
 | 
			
		||||
	msg.msg_namelen		= 0;
 | 
			
		||||
	msg.msg_iov		= iov;
 | 
			
		||||
	msg.msg_iovlen		= 1;
 | 
			
		||||
	iov_iter_init(&msg.msg_iter, WRITE, iov, 1, len);
 | 
			
		||||
	msg.msg_control		= NULL;
 | 
			
		||||
	msg.msg_controllen	= 0;
 | 
			
		||||
	msg.msg_flags		= 0;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2646,22 +2646,24 @@ unsigned int datagram_poll(struct file *file, struct socket *sock,
 | 
			
		|||
			   struct poll_table_struct *wait);
 | 
			
		||||
int skb_copy_datagram_iovec(const struct sk_buff *from, int offset,
 | 
			
		||||
			    struct iovec *to, int size);
 | 
			
		||||
int skb_copy_datagram_iter(const struct sk_buff *from, int offset,
 | 
			
		||||
			   struct iov_iter *to, int size);
 | 
			
		||||
static inline int skb_copy_datagram_msg(const struct sk_buff *from, int offset,
 | 
			
		||||
					struct msghdr *msg, int size)
 | 
			
		||||
{
 | 
			
		||||
	return skb_copy_datagram_iovec(from, offset, msg->msg_iov, size);
 | 
			
		||||
	/* XXX: stripping const */
 | 
			
		||||
	return skb_copy_datagram_iovec(from, offset, (struct iovec *)msg->msg_iter.iov, size);
 | 
			
		||||
}
 | 
			
		||||
int skb_copy_and_csum_datagram_iovec(struct sk_buff *skb, int hlen,
 | 
			
		||||
				     struct iovec *iov);
 | 
			
		||||
static inline int skb_copy_and_csum_datagram_msg(struct sk_buff *skb, int hlen,
 | 
			
		||||
			    struct msghdr *msg)
 | 
			
		||||
{
 | 
			
		||||
	return skb_copy_and_csum_datagram_iovec(skb, hlen, msg->msg_iov);
 | 
			
		||||
	/* XXX: stripping const */
 | 
			
		||||
	return skb_copy_and_csum_datagram_iovec(skb, hlen, (struct iovec *)msg->msg_iter.iov);
 | 
			
		||||
}
 | 
			
		||||
int skb_copy_datagram_from_iter(struct sk_buff *skb, int offset,
 | 
			
		||||
				 struct iov_iter *from, int len);
 | 
			
		||||
int skb_copy_datagram_iter(const struct sk_buff *from, int offset,
 | 
			
		||||
			   struct iov_iter *to, int size);
 | 
			
		||||
int zerocopy_sg_from_iter(struct sk_buff *skb, struct iov_iter *frm);
 | 
			
		||||
void skb_free_datagram(struct sock *sk, struct sk_buff *skb);
 | 
			
		||||
void skb_free_datagram_locked(struct sock *sk, struct sk_buff *skb);
 | 
			
		||||
| 
						 | 
				
			
			@ -2689,12 +2691,14 @@ int skb_vlan_push(struct sk_buff *skb, __be16 vlan_proto, u16 vlan_tci);
 | 
			
		|||
 | 
			
		||||
static inline int memcpy_from_msg(void *data, struct msghdr *msg, int len)
 | 
			
		||||
{
 | 
			
		||||
	return memcpy_fromiovec(data, msg->msg_iov, len);
 | 
			
		||||
	/* XXX: stripping const */
 | 
			
		||||
	return memcpy_fromiovec(data, (struct iovec *)msg->msg_iter.iov, len);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int memcpy_to_msg(struct msghdr *msg, void *data, int len)
 | 
			
		||||
{
 | 
			
		||||
	return memcpy_toiovec(msg->msg_iov, data, len);
 | 
			
		||||
	/* XXX: stripping const */
 | 
			
		||||
	return memcpy_toiovec((struct iovec *)msg->msg_iter.iov, data, len);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct skb_checksum_ops {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -47,8 +47,7 @@ struct linger {
 | 
			
		|||
struct msghdr {
 | 
			
		||||
	void		*msg_name;	/* ptr to socket address structure */
 | 
			
		||||
	int		msg_namelen;	/* size of socket address structure */
 | 
			
		||||
	struct iovec	*msg_iov;	/* scatter/gather array */
 | 
			
		||||
	__kernel_size_t	msg_iovlen;	/* # elements in msg_iov */
 | 
			
		||||
	struct iov_iter	msg_iter;	/* data */
 | 
			
		||||
	void		*msg_control;	/* ancillary data */
 | 
			
		||||
	__kernel_size_t	msg_controllen;	/* ancillary data buffer length */
 | 
			
		||||
	unsigned int	msg_flags;	/* flags on received message */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -911,7 +911,7 @@ static inline int l2cap_chan_no_memcpy_fromiovec(struct l2cap_chan *chan,
 | 
			
		|||
	/* Following is safe since for compiler definitions of kvec and
 | 
			
		||||
	 * iovec are identical, yielding the same in-core layout and alignment
 | 
			
		||||
	 */
 | 
			
		||||
	struct kvec *vec = (struct kvec *)msg->msg_iov;
 | 
			
		||||
	struct kvec *vec = (struct kvec *)msg->msg_iter.iov;
 | 
			
		||||
 | 
			
		||||
	while (len > 0) {
 | 
			
		||||
		if (vec->iov_len) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,7 +20,8 @@ static __inline__ int udplite_getfrag(void *from, char *to, int  offset,
 | 
			
		|||
				      int len, int odd, struct sk_buff *skb)
 | 
			
		||||
{
 | 
			
		||||
	struct msghdr *msg = from;
 | 
			
		||||
	return memcpy_fromiovecend(to, msg->msg_iov, offset, len);
 | 
			
		||||
	/* XXX: stripping const */
 | 
			
		||||
	return memcpy_fromiovecend(to, (struct iovec *)msg->msg_iter.iov, offset, len);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Designate sk as UDP-Lite socket */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -577,9 +577,6 @@ int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,
 | 
			
		|||
	struct atm_vcc *vcc;
 | 
			
		||||
	struct sk_buff *skb;
 | 
			
		||||
	int eff, error;
 | 
			
		||||
	struct iov_iter from;
 | 
			
		||||
 | 
			
		||||
	iov_iter_init(&from, WRITE, m->msg_iov, m->msg_iovlen, size);
 | 
			
		||||
 | 
			
		||||
	lock_sock(sk);
 | 
			
		||||
	if (sock->state != SS_CONNECTED) {
 | 
			
		||||
| 
						 | 
				
			
			@ -634,7 +631,7 @@ int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,
 | 
			
		|||
		goto out;
 | 
			
		||||
	skb->dev = NULL; /* for paths shared with net_device interfaces */
 | 
			
		||||
	ATM_SKB(skb)->atm_options = vcc->atm_options;
 | 
			
		||||
	if (copy_from_iter(skb_put(skb, size), size, &from) != size) {
 | 
			
		||||
	if (copy_from_iter(skb_put(skb, size), size, &m->msg_iter) != size) {
 | 
			
		||||
		kfree_skb(skb);
 | 
			
		||||
		error = -EFAULT;
 | 
			
		||||
		goto out;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -537,12 +537,12 @@ static int send_pkt(struct l2cap_chan *chan, struct sk_buff *skb,
 | 
			
		|||
	 */
 | 
			
		||||
	chan->data = skb;
 | 
			
		||||
 | 
			
		||||
	memset(&msg, 0, sizeof(msg));
 | 
			
		||||
	msg.msg_iov = (struct iovec *) &iv;
 | 
			
		||||
	msg.msg_iovlen = 1;
 | 
			
		||||
	iv.iov_base = skb->data;
 | 
			
		||||
	iv.iov_len = skb->len;
 | 
			
		||||
 | 
			
		||||
	memset(&msg, 0, sizeof(msg));
 | 
			
		||||
	iov_iter_init(&msg.msg_iter, WRITE, (struct iovec *) &iv, 1, skb->len);
 | 
			
		||||
 | 
			
		||||
	err = l2cap_chan_send(chan, &msg, skb->len);
 | 
			
		||||
	if (err > 0) {
 | 
			
		||||
		netdev->stats.tx_bytes += err;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,8 +60,7 @@ void a2mp_send(struct amp_mgr *mgr, u8 code, u8 ident, u16 len, void *data)
 | 
			
		|||
 | 
			
		||||
	memset(&msg, 0, sizeof(msg));
 | 
			
		||||
 | 
			
		||||
	msg.msg_iov = (struct iovec *) &iv;
 | 
			
		||||
	msg.msg_iovlen = 1;
 | 
			
		||||
	iov_iter_init(&msg.msg_iter, WRITE, (struct iovec *)&iv, 1, total_len);
 | 
			
		||||
 | 
			
		||||
	l2cap_chan_send(chan, &msg, total_len);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -268,8 +268,7 @@ static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data)
 | 
			
		|||
 | 
			
		||||
	memset(&msg, 0, sizeof(msg));
 | 
			
		||||
 | 
			
		||||
	msg.msg_iov = (struct iovec *) &iv;
 | 
			
		||||
	msg.msg_iovlen = 2;
 | 
			
		||||
	iov_iter_init(&msg.msg_iter, WRITE, (struct iovec *)iv, 2, 1 + len);
 | 
			
		||||
 | 
			
		||||
	l2cap_chan_send(chan, &msg, 1 + len);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -535,7 +535,7 @@ static int caif_seqpkt_sendmsg(struct kiocb *kiocb, struct socket *sock,
 | 
			
		|||
		goto err;
 | 
			
		||||
 | 
			
		||||
	ret = -EINVAL;
 | 
			
		||||
	if (unlikely(msg->msg_iov->iov_base == NULL))
 | 
			
		||||
	if (unlikely(msg->msg_iter.iov->iov_base == NULL))
 | 
			
		||||
		goto err;
 | 
			
		||||
	noblock = msg->msg_flags & MSG_DONTWAIT;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										10
									
								
								net/compat.c
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								net/compat.c
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -37,13 +37,14 @@ ssize_t get_compat_msghdr(struct msghdr *kmsg,
 | 
			
		|||
			  struct iovec **iov)
 | 
			
		||||
{
 | 
			
		||||
	compat_uptr_t uaddr, uiov, tmp3;
 | 
			
		||||
	compat_size_t nr_segs;
 | 
			
		||||
	ssize_t err;
 | 
			
		||||
 | 
			
		||||
	if (!access_ok(VERIFY_READ, umsg, sizeof(*umsg)) ||
 | 
			
		||||
	    __get_user(uaddr, &umsg->msg_name) ||
 | 
			
		||||
	    __get_user(kmsg->msg_namelen, &umsg->msg_namelen) ||
 | 
			
		||||
	    __get_user(uiov, &umsg->msg_iov) ||
 | 
			
		||||
	    __get_user(kmsg->msg_iovlen, &umsg->msg_iovlen) ||
 | 
			
		||||
	    __get_user(nr_segs, &umsg->msg_iovlen) ||
 | 
			
		||||
	    __get_user(tmp3, &umsg->msg_control) ||
 | 
			
		||||
	    __get_user(kmsg->msg_controllen, &umsg->msg_controllen) ||
 | 
			
		||||
	    __get_user(kmsg->msg_flags, &umsg->msg_flags))
 | 
			
		||||
| 
						 | 
				
			
			@ -68,14 +69,15 @@ ssize_t get_compat_msghdr(struct msghdr *kmsg,
 | 
			
		|||
		kmsg->msg_namelen = 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (kmsg->msg_iovlen > UIO_MAXIOV)
 | 
			
		||||
	if (nr_segs > UIO_MAXIOV)
 | 
			
		||||
		return -EMSGSIZE;
 | 
			
		||||
 | 
			
		||||
	err = compat_rw_copy_check_uvector(save_addr ? READ : WRITE,
 | 
			
		||||
					   compat_ptr(uiov), kmsg->msg_iovlen,
 | 
			
		||||
					   compat_ptr(uiov), nr_segs,
 | 
			
		||||
					   UIO_FASTIOV, *iov, iov);
 | 
			
		||||
	if (err >= 0)
 | 
			
		||||
		kmsg->msg_iov = *iov;
 | 
			
		||||
		iov_iter_init(&kmsg->msg_iter, save_addr ? READ : WRITE,
 | 
			
		||||
			      *iov, nr_segs, err);
 | 
			
		||||
	return err;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -755,11 +755,13 @@ ip_generic_getfrag(void *from, char *to, int offset, int len, int odd, struct sk
 | 
			
		|||
	struct msghdr *msg = from;
 | 
			
		||||
 | 
			
		||||
	if (skb->ip_summed == CHECKSUM_PARTIAL) {
 | 
			
		||||
		if (memcpy_fromiovecend(to, msg->msg_iov, offset, len) < 0)
 | 
			
		||||
		/* XXX: stripping const */
 | 
			
		||||
		if (memcpy_fromiovecend(to, (struct iovec *)msg->msg_iter.iov, offset, len) < 0)
 | 
			
		||||
			return -EFAULT;
 | 
			
		||||
	} else {
 | 
			
		||||
		__wsum csum = 0;
 | 
			
		||||
		if (csum_partial_copy_fromiovecend(to, msg->msg_iov, offset, len, &csum) < 0)
 | 
			
		||||
		/* XXX: stripping const */
 | 
			
		||||
		if (csum_partial_copy_fromiovecend(to, (struct iovec *)msg->msg_iter.iov, offset, len, &csum) < 0)
 | 
			
		||||
			return -EFAULT;
 | 
			
		||||
		skb->csum = csum_block_add(skb->csum, csum, odd);
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -811,7 +811,8 @@ static int ping_v4_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m
 | 
			
		|||
	pfh.icmph.checksum = 0;
 | 
			
		||||
	pfh.icmph.un.echo.id = inet->inet_sport;
 | 
			
		||||
	pfh.icmph.un.echo.sequence = user_icmph.un.echo.sequence;
 | 
			
		||||
	pfh.iov = msg->msg_iov;
 | 
			
		||||
	/* XXX: stripping const */
 | 
			
		||||
	pfh.iov = (struct iovec *)msg->msg_iter.iov;
 | 
			
		||||
	pfh.wcheck = 0;
 | 
			
		||||
	pfh.family = AF_INET;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -625,7 +625,8 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
 | 
			
		|||
back_from_confirm:
 | 
			
		||||
 | 
			
		||||
	if (inet->hdrincl)
 | 
			
		||||
		err = raw_send_hdrinc(sk, &fl4, msg->msg_iov, len,
 | 
			
		||||
		/* XXX: stripping const */
 | 
			
		||||
		err = raw_send_hdrinc(sk, &fl4, (struct iovec *)msg->msg_iter.iov, len,
 | 
			
		||||
				      &rt, msg->msg_flags);
 | 
			
		||||
 | 
			
		||||
	 else {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1085,7 +1085,7 @@ static int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,
 | 
			
		|||
int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
 | 
			
		||||
		size_t size)
 | 
			
		||||
{
 | 
			
		||||
	struct iovec *iov;
 | 
			
		||||
	const struct iovec *iov;
 | 
			
		||||
	struct tcp_sock *tp = tcp_sk(sk);
 | 
			
		||||
	struct sk_buff *skb;
 | 
			
		||||
	int iovlen, flags, err, copied = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -1136,8 +1136,8 @@ int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
 | 
			
		|||
	mss_now = tcp_send_mss(sk, &size_goal, flags);
 | 
			
		||||
 | 
			
		||||
	/* Ok commence sending. */
 | 
			
		||||
	iovlen = msg->msg_iovlen;
 | 
			
		||||
	iov = msg->msg_iov;
 | 
			
		||||
	iovlen = msg->msg_iter.nr_segs;
 | 
			
		||||
	iov = msg->msg_iter.iov;
 | 
			
		||||
	copied = 0;
 | 
			
		||||
 | 
			
		||||
	err = -EPIPE;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3050,7 +3050,7 @@ static int tcp_send_syn_data(struct sock *sk, struct sk_buff *syn)
 | 
			
		|||
	syn_data->ip_summed = CHECKSUM_PARTIAL;
 | 
			
		||||
	memcpy(syn_data->cb, syn->cb, sizeof(syn->cb));
 | 
			
		||||
	if (unlikely(memcpy_fromiovecend(skb_put(syn_data, space),
 | 
			
		||||
					 fo->data->msg_iov, 0, space))) {
 | 
			
		||||
					 fo->data->msg_iter.iov, 0, space))) {
 | 
			
		||||
		kfree_skb(syn_data);
 | 
			
		||||
		goto fallback;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -163,7 +163,8 @@ int ping_v6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
 | 
			
		|||
	pfh.icmph.checksum = 0;
 | 
			
		||||
	pfh.icmph.un.echo.id = inet->inet_sport;
 | 
			
		||||
	pfh.icmph.un.echo.sequence = user_icmph.icmp6_sequence;
 | 
			
		||||
	pfh.iov = msg->msg_iov;
 | 
			
		||||
	/* XXX: stripping const */
 | 
			
		||||
	pfh.iov = (struct iovec *)msg->msg_iter.iov;
 | 
			
		||||
	pfh.wcheck = 0;
 | 
			
		||||
	pfh.family = AF_INET6;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -886,7 +886,8 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
 | 
			
		|||
 | 
			
		||||
back_from_confirm:
 | 
			
		||||
	if (inet->hdrincl)
 | 
			
		||||
		err = rawv6_send_hdrinc(sk, msg->msg_iov, len, &fl6, &dst, msg->msg_flags);
 | 
			
		||||
		/* XXX: stripping const */
 | 
			
		||||
		err = rawv6_send_hdrinc(sk, (struct iovec *)msg->msg_iter.iov, len, &fl6, &dst, msg->msg_flags);
 | 
			
		||||
	else {
 | 
			
		||||
		lock_sock(sk);
 | 
			
		||||
		err = ip6_append_data(sk, raw6_getfrag, &rfv,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2305,7 +2305,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	if (netlink_tx_is_mmaped(sk) &&
 | 
			
		||||
	    msg->msg_iov->iov_base == NULL) {
 | 
			
		||||
	    msg->msg_iter.iov->iov_base == NULL) {
 | 
			
		||||
		err = netlink_mmap_sendmsg(sk, msg, dst_portid, dst_group,
 | 
			
		||||
					   siocb);
 | 
			
		||||
		goto out;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2408,11 +2408,8 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
 | 
			
		|||
	unsigned short gso_type = 0;
 | 
			
		||||
	int hlen, tlen;
 | 
			
		||||
	int extra_len = 0;
 | 
			
		||||
	struct iov_iter from;
 | 
			
		||||
	ssize_t n;
 | 
			
		||||
 | 
			
		||||
	iov_iter_init(&from, WRITE, msg->msg_iov, msg->msg_iovlen, len);
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 *	Get and verify the address.
 | 
			
		||||
	 */
 | 
			
		||||
| 
						 | 
				
			
			@ -2451,7 +2448,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
 | 
			
		|||
		len -= vnet_hdr_len;
 | 
			
		||||
 | 
			
		||||
		err = -EFAULT;
 | 
			
		||||
		n = copy_from_iter(&vnet_hdr, vnet_hdr_len, &from);
 | 
			
		||||
		n = copy_from_iter(&vnet_hdr, vnet_hdr_len, &msg->msg_iter);
 | 
			
		||||
		if (n != vnet_hdr_len)
 | 
			
		||||
			goto out_unlock;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2522,7 +2519,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	/* Returns -EFAULT on error */
 | 
			
		||||
	err = skb_copy_datagram_from_iter(skb, offset, &from, len);
 | 
			
		||||
	err = skb_copy_datagram_from_iter(skb, offset, &msg->msg_iter, len);
 | 
			
		||||
	if (err)
 | 
			
		||||
		goto out_free;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -404,7 +404,6 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
 | 
			
		|||
	int ret = 0, nonblock = msg_flags & MSG_DONTWAIT;
 | 
			
		||||
	DECLARE_SOCKADDR(struct sockaddr_in *, sin, msg->msg_name);
 | 
			
		||||
	struct rds_incoming *inc = NULL;
 | 
			
		||||
	struct iov_iter to;
 | 
			
		||||
 | 
			
		||||
	/* udp_recvmsg()->sock_recvtimeo() gets away without locking too.. */
 | 
			
		||||
	timeo = sock_rcvtimeo(sk, nonblock);
 | 
			
		||||
| 
						 | 
				
			
			@ -415,6 +414,7 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
 | 
			
		|||
		goto out;
 | 
			
		||||
 | 
			
		||||
	while (1) {
 | 
			
		||||
		struct iov_iter save;
 | 
			
		||||
		/* If there are pending notifications, do those - and nothing else */
 | 
			
		||||
		if (!list_empty(&rs->rs_notify_queue)) {
 | 
			
		||||
			ret = rds_notify_queue_get(rs, msg);
 | 
			
		||||
| 
						 | 
				
			
			@ -450,8 +450,8 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
 | 
			
		|||
		rdsdebug("copying inc %p from %pI4:%u to user\n", inc,
 | 
			
		||||
			 &inc->i_conn->c_faddr,
 | 
			
		||||
			 ntohs(inc->i_hdr.h_sport));
 | 
			
		||||
		iov_iter_init(&to, READ, msg->msg_iov, msg->msg_iovlen, size);
 | 
			
		||||
		ret = inc->i_conn->c_trans->inc_copy_to_user(inc, &to);
 | 
			
		||||
		save = msg->msg_iter;
 | 
			
		||||
		ret = inc->i_conn->c_trans->inc_copy_to_user(inc, &msg->msg_iter);
 | 
			
		||||
		if (ret < 0)
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -464,6 +464,7 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
 | 
			
		|||
			rds_inc_put(inc);
 | 
			
		||||
			inc = NULL;
 | 
			
		||||
			rds_stats_inc(s_recv_deliver_raced);
 | 
			
		||||
			msg->msg_iter = save;
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -934,9 +934,7 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
 | 
			
		|||
	int queued = 0, allocated_mr = 0;
 | 
			
		||||
	int nonblock = msg->msg_flags & MSG_DONTWAIT;
 | 
			
		||||
	long timeo = sock_sndtimeo(sk, nonblock);
 | 
			
		||||
	struct iov_iter from;
 | 
			
		||||
 | 
			
		||||
	iov_iter_init(&from, WRITE, msg->msg_iov, msg->msg_iovlen, payload_len);
 | 
			
		||||
	/* Mirror Linux UDP mirror of BSD error message compatibility */
 | 
			
		||||
	/* XXX: Perhaps MSG_MORE someday */
 | 
			
		||||
	if (msg->msg_flags & ~(MSG_DONTWAIT | MSG_CMSG_COMPAT)) {
 | 
			
		||||
| 
						 | 
				
			
			@ -984,7 +982,7 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
 | 
			
		|||
			ret = -ENOMEM;
 | 
			
		||||
			goto out;
 | 
			
		||||
		}
 | 
			
		||||
		ret = rds_message_copy_from_user(rm, &from);
 | 
			
		||||
		ret = rds_message_copy_from_user(rm, &msg->msg_iter);
 | 
			
		||||
		if (ret)
 | 
			
		||||
			goto out;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -531,14 +531,12 @@ static int rxrpc_send_data(struct kiocb *iocb,
 | 
			
		|||
	struct rxrpc_skb_priv *sp;
 | 
			
		||||
	unsigned char __user *from;
 | 
			
		||||
	struct sk_buff *skb;
 | 
			
		||||
	struct iovec *iov;
 | 
			
		||||
	const struct iovec *iov;
 | 
			
		||||
	struct sock *sk = &rx->sk;
 | 
			
		||||
	long timeo;
 | 
			
		||||
	bool more;
 | 
			
		||||
	int ret, ioc, segment, copied;
 | 
			
		||||
 | 
			
		||||
	_enter(",,,{%zu},%zu", msg->msg_iovlen, len);
 | 
			
		||||
 | 
			
		||||
	timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT);
 | 
			
		||||
 | 
			
		||||
	/* this should be in poll */
 | 
			
		||||
| 
						 | 
				
			
			@ -547,8 +545,8 @@ static int rxrpc_send_data(struct kiocb *iocb,
 | 
			
		|||
	if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN))
 | 
			
		||||
		return -EPIPE;
 | 
			
		||||
 | 
			
		||||
	iov = msg->msg_iov;
 | 
			
		||||
	ioc = msg->msg_iovlen - 1;
 | 
			
		||||
	iov = msg->msg_iter.iov;
 | 
			
		||||
	ioc = msg->msg_iter.nr_segs - 1;
 | 
			
		||||
	from = iov->iov_base;
 | 
			
		||||
	segment = iov->iov_len;
 | 
			
		||||
	iov++;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1609,9 +1609,6 @@ static int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
 | 
			
		|||
	__u16 sinfo_flags = 0;
 | 
			
		||||
	long timeo;
 | 
			
		||||
	int err;
 | 
			
		||||
	struct iov_iter from;
 | 
			
		||||
 | 
			
		||||
	iov_iter_init(&from, WRITE, msg->msg_iov, msg->msg_iovlen, msg_len);
 | 
			
		||||
 | 
			
		||||
	err = 0;
 | 
			
		||||
	sp = sctp_sk(sk);
 | 
			
		||||
| 
						 | 
				
			
			@ -1950,7 +1947,7 @@ static int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	/* Break the message into multiple chunks of maximum size. */
 | 
			
		||||
	datamsg = sctp_datamsg_from_user(asoc, sinfo, &from);
 | 
			
		||||
	datamsg = sctp_datamsg_from_user(asoc, sinfo, &msg->msg_iter);
 | 
			
		||||
	if (IS_ERR(datamsg)) {
 | 
			
		||||
		err = PTR_ERR(datamsg);
 | 
			
		||||
		goto out_free;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										27
									
								
								net/socket.c
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								net/socket.c
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -689,8 +689,7 @@ int kernel_sendmsg(struct socket *sock, struct msghdr *msg,
 | 
			
		|||
	 * the following is safe, since for compiler definitions of kvec and
 | 
			
		||||
	 * iovec are identical, yielding the same in-core layout and alignment
 | 
			
		||||
	 */
 | 
			
		||||
	msg->msg_iov = (struct iovec *)vec;
 | 
			
		||||
	msg->msg_iovlen = num;
 | 
			
		||||
	iov_iter_init(&msg->msg_iter, WRITE, (struct iovec *)vec, num, size);
 | 
			
		||||
	result = sock_sendmsg(sock, msg, size);
 | 
			
		||||
	set_fs(oldfs);
 | 
			
		||||
	return result;
 | 
			
		||||
| 
						 | 
				
			
			@ -853,7 +852,7 @@ int kernel_recvmsg(struct socket *sock, struct msghdr *msg,
 | 
			
		|||
	 * the following is safe, since for compiler definitions of kvec and
 | 
			
		||||
	 * iovec are identical, yielding the same in-core layout and alignment
 | 
			
		||||
	 */
 | 
			
		||||
	msg->msg_iov = (struct iovec *)vec, msg->msg_iovlen = num;
 | 
			
		||||
	iov_iter_init(&msg->msg_iter, READ, (struct iovec *)vec, num, size);
 | 
			
		||||
	result = sock_recvmsg(sock, msg, size, flags);
 | 
			
		||||
	set_fs(oldfs);
 | 
			
		||||
	return result;
 | 
			
		||||
| 
						 | 
				
			
			@ -913,8 +912,7 @@ static ssize_t do_sock_read(struct msghdr *msg, struct kiocb *iocb,
 | 
			
		|||
	msg->msg_namelen = 0;
 | 
			
		||||
	msg->msg_control = NULL;
 | 
			
		||||
	msg->msg_controllen = 0;
 | 
			
		||||
	msg->msg_iov = (struct iovec *)iov;
 | 
			
		||||
	msg->msg_iovlen = nr_segs;
 | 
			
		||||
	iov_iter_init(&msg->msg_iter, READ, iov, nr_segs, size);
 | 
			
		||||
	msg->msg_flags = (file->f_flags & O_NONBLOCK) ? MSG_DONTWAIT : 0;
 | 
			
		||||
 | 
			
		||||
	return __sock_recvmsg(iocb, sock, msg, size, msg->msg_flags);
 | 
			
		||||
| 
						 | 
				
			
			@ -953,8 +951,7 @@ static ssize_t do_sock_write(struct msghdr *msg, struct kiocb *iocb,
 | 
			
		|||
	msg->msg_namelen = 0;
 | 
			
		||||
	msg->msg_control = NULL;
 | 
			
		||||
	msg->msg_controllen = 0;
 | 
			
		||||
	msg->msg_iov = (struct iovec *)iov;
 | 
			
		||||
	msg->msg_iovlen = nr_segs;
 | 
			
		||||
	iov_iter_init(&msg->msg_iter, WRITE, iov, nr_segs, size);
 | 
			
		||||
	msg->msg_flags = (file->f_flags & O_NONBLOCK) ? MSG_DONTWAIT : 0;
 | 
			
		||||
	if (sock->type == SOCK_SEQPACKET)
 | 
			
		||||
		msg->msg_flags |= MSG_EOR;
 | 
			
		||||
| 
						 | 
				
			
			@ -1798,8 +1795,7 @@ SYSCALL_DEFINE6(sendto, int, fd, void __user *, buff, size_t, len,
 | 
			
		|||
	iov.iov_base = buff;
 | 
			
		||||
	iov.iov_len = len;
 | 
			
		||||
	msg.msg_name = NULL;
 | 
			
		||||
	msg.msg_iov = &iov;
 | 
			
		||||
	msg.msg_iovlen = 1;
 | 
			
		||||
	iov_iter_init(&msg.msg_iter, WRITE, &iov, 1, len);
 | 
			
		||||
	msg.msg_control = NULL;
 | 
			
		||||
	msg.msg_controllen = 0;
 | 
			
		||||
	msg.msg_namelen = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -1856,10 +1852,9 @@ SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, ubuf, size_t, size,
 | 
			
		|||
 | 
			
		||||
	msg.msg_control = NULL;
 | 
			
		||||
	msg.msg_controllen = 0;
 | 
			
		||||
	msg.msg_iovlen = 1;
 | 
			
		||||
	msg.msg_iov = &iov;
 | 
			
		||||
	iov.iov_len = size;
 | 
			
		||||
	iov.iov_base = ubuf;
 | 
			
		||||
	iov_iter_init(&msg.msg_iter, READ, &iov, 1, size);
 | 
			
		||||
	/* Save some cycles and don't copy the address if not needed */
 | 
			
		||||
	msg.msg_name = addr ? (struct sockaddr *)&address : NULL;
 | 
			
		||||
	/* We assume all kernel code knows the size of sockaddr_storage */
 | 
			
		||||
| 
						 | 
				
			
			@ -1993,13 +1988,14 @@ static ssize_t copy_msghdr_from_user(struct msghdr *kmsg,
 | 
			
		|||
{
 | 
			
		||||
	struct sockaddr __user *uaddr;
 | 
			
		||||
	struct iovec __user *uiov;
 | 
			
		||||
	size_t nr_segs;
 | 
			
		||||
	ssize_t err;
 | 
			
		||||
 | 
			
		||||
	if (!access_ok(VERIFY_READ, umsg, sizeof(*umsg)) ||
 | 
			
		||||
	    __get_user(uaddr, &umsg->msg_name) ||
 | 
			
		||||
	    __get_user(kmsg->msg_namelen, &umsg->msg_namelen) ||
 | 
			
		||||
	    __get_user(uiov, &umsg->msg_iov) ||
 | 
			
		||||
	    __get_user(kmsg->msg_iovlen, &umsg->msg_iovlen) ||
 | 
			
		||||
	    __get_user(nr_segs, &umsg->msg_iovlen) ||
 | 
			
		||||
	    __get_user(kmsg->msg_control, &umsg->msg_control) ||
 | 
			
		||||
	    __get_user(kmsg->msg_controllen, &umsg->msg_controllen) ||
 | 
			
		||||
	    __get_user(kmsg->msg_flags, &umsg->msg_flags))
 | 
			
		||||
| 
						 | 
				
			
			@ -2029,14 +2025,15 @@ static ssize_t copy_msghdr_from_user(struct msghdr *kmsg,
 | 
			
		|||
		kmsg->msg_namelen = 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (kmsg->msg_iovlen > UIO_MAXIOV)
 | 
			
		||||
	if (nr_segs > UIO_MAXIOV)
 | 
			
		||||
		return -EMSGSIZE;
 | 
			
		||||
 | 
			
		||||
	err = rw_copy_check_uvector(save_addr ? READ : WRITE,
 | 
			
		||||
				    uiov, kmsg->msg_iovlen,
 | 
			
		||||
				    uiov, nr_segs,
 | 
			
		||||
				    UIO_FASTIOV, *iov, iov);
 | 
			
		||||
	if (err >= 0)
 | 
			
		||||
		kmsg->msg_iov = *iov;
 | 
			
		||||
		iov_iter_init(&kmsg->msg_iter, save_addr ? READ : WRITE,
 | 
			
		||||
			      *iov, nr_segs, err);
 | 
			
		||||
	return err;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -194,7 +194,7 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m, int offset,
 | 
			
		|||
		__skb_queue_tail(list, skb);
 | 
			
		||||
		skb_copy_to_linear_data(skb, mhdr, mhsz);
 | 
			
		||||
		pktpos = skb->data + mhsz;
 | 
			
		||||
		if (!dsz || !memcpy_fromiovecend(pktpos, m->msg_iov, offset,
 | 
			
		||||
		if (!dsz || !memcpy_fromiovecend(pktpos, m->msg_iter.iov, offset,
 | 
			
		||||
						 dsz))
 | 
			
		||||
			return dsz;
 | 
			
		||||
		rc = -EFAULT;
 | 
			
		||||
| 
						 | 
				
			
			@ -224,7 +224,7 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m, int offset,
 | 
			
		|||
		if (drem < pktrem)
 | 
			
		||||
			pktrem = drem;
 | 
			
		||||
 | 
			
		||||
		if (memcpy_fromiovecend(pktpos, m->msg_iov, offset, pktrem)) {
 | 
			
		||||
		if (memcpy_fromiovecend(pktpos, m->msg_iter.iov, offset, pktrem)) {
 | 
			
		||||
			rc = -EFAULT;
 | 
			
		||||
			goto error;
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1459,9 +1459,6 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
 | 
			
		|||
	struct scm_cookie tmp_scm;
 | 
			
		||||
	int max_level;
 | 
			
		||||
	int data_len = 0;
 | 
			
		||||
	struct iov_iter from;
 | 
			
		||||
 | 
			
		||||
	iov_iter_init(&from, WRITE, msg->msg_iov, msg->msg_iovlen, len);
 | 
			
		||||
 | 
			
		||||
	if (NULL == siocb->scm)
 | 
			
		||||
		siocb->scm = &tmp_scm;
 | 
			
		||||
| 
						 | 
				
			
			@ -1519,7 +1516,7 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
 | 
			
		|||
	skb_put(skb, len - data_len);
 | 
			
		||||
	skb->data_len = data_len;
 | 
			
		||||
	skb->len = len;
 | 
			
		||||
	err = skb_copy_datagram_from_iter(skb, 0, &from, len);
 | 
			
		||||
	err = skb_copy_datagram_from_iter(skb, 0, &msg->msg_iter, len);
 | 
			
		||||
	if (err)
 | 
			
		||||
		goto out_free;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1641,9 +1638,6 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
 | 
			
		|||
	bool fds_sent = false;
 | 
			
		||||
	int max_level;
 | 
			
		||||
	int data_len;
 | 
			
		||||
	struct iov_iter from;
 | 
			
		||||
 | 
			
		||||
	iov_iter_init(&from, WRITE, msg->msg_iov, msg->msg_iovlen, len);
 | 
			
		||||
 | 
			
		||||
	if (NULL == siocb->scm)
 | 
			
		||||
		siocb->scm = &tmp_scm;
 | 
			
		||||
| 
						 | 
				
			
			@ -1700,7 +1694,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
 | 
			
		|||
		skb_put(skb, size - data_len);
 | 
			
		||||
		skb->data_len = data_len;
 | 
			
		||||
		skb->len = size;
 | 
			
		||||
		err = skb_copy_datagram_from_iter(skb, 0, &from, size);
 | 
			
		||||
		err = skb_copy_datagram_from_iter(skb, 0, &msg->msg_iter, size);
 | 
			
		||||
		if (err) {
 | 
			
		||||
			kfree_skb(skb);
 | 
			
		||||
			goto out_err;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1850,7 +1850,8 @@ static ssize_t vmci_transport_stream_enqueue(
 | 
			
		|||
	struct msghdr *msg,
 | 
			
		||||
	size_t len)
 | 
			
		||||
{
 | 
			
		||||
	return vmci_qpair_enquev(vmci_trans(vsk)->qpair, msg->msg_iov, len, 0);
 | 
			
		||||
	/* XXX: stripping const */
 | 
			
		||||
	return vmci_qpair_enquev(vmci_trans(vsk)->qpair, (struct iovec *)msg->msg_iter.iov, len, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static s64 vmci_transport_stream_has_data(struct vsock_sock *vsk)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue