diff options
author | David S. Miller <davem@davemloft.net> | 2014-12-10 13:17:23 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-12-10 13:17:23 -0500 |
commit | 6e5f59aacbf9527dfe425541c78cb8c56623e7eb (patch) | |
tree | dc5614e1546dba2bd6896d4aa21410e1d3297a09 /net | |
parent | 6c702fab626328c33b539b0c618a5511aed23bed (diff) | |
parent | 218321e7a0838c2be974539f0a5341b398d4432b (diff) |
Merge branch 'for-davem-2' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
More iov_iter work for the networking from Al Viro.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/atm/common.c | 5 | ||||
-rw-r--r-- | net/bluetooth/6lowpan.c | 7 | ||||
-rw-r--r-- | net/bluetooth/a2mp.c | 4 | ||||
-rw-r--r-- | net/bluetooth/l2cap_core.c | 7 | ||||
-rw-r--r-- | net/bluetooth/l2cap_sock.c | 8 | ||||
-rw-r--r-- | net/bluetooth/smp.c | 5 | ||||
-rw-r--r-- | net/caif/caif_socket.c | 2 | ||||
-rw-r--r-- | net/compat.c | 10 | ||||
-rw-r--r-- | net/core/datagram.c | 138 | ||||
-rw-r--r-- | net/ipv4/ip_output.c | 8 | ||||
-rw-r--r-- | net/ipv4/ping.c | 3 | ||||
-rw-r--r-- | net/ipv4/raw.c | 11 | ||||
-rw-r--r-- | net/ipv4/tcp.c | 8 | ||||
-rw-r--r-- | net/ipv4/tcp_input.c | 7 | ||||
-rw-r--r-- | net/ipv4/tcp_output.c | 2 | ||||
-rw-r--r-- | net/ipv4/udp.c | 4 | ||||
-rw-r--r-- | net/ipv6/ping.c | 3 | ||||
-rw-r--r-- | net/ipv6/raw.c | 115 | ||||
-rw-r--r-- | net/ipv6/udp.c | 2 | ||||
-rw-r--r-- | net/l2tp/l2tp_ip6.c | 2 | ||||
-rw-r--r-- | net/netlink/af_netlink.c | 2 | ||||
-rw-r--r-- | net/packet/af_packet.c | 7 | ||||
-rw-r--r-- | net/rds/recv.c | 7 | ||||
-rw-r--r-- | net/rds/send.c | 4 | ||||
-rw-r--r-- | net/rxrpc/ar-output.c | 8 | ||||
-rw-r--r-- | net/sctp/socket.c | 5 | ||||
-rw-r--r-- | net/socket.c | 27 | ||||
-rw-r--r-- | net/tipc/msg.c | 4 | ||||
-rw-r--r-- | net/unix/af_unix.c | 10 | ||||
-rw-r--r-- | net/vmw_vsock/vmci_transport.c | 7 |
30 files changed, 152 insertions, 280 deletions
diff --git a/net/atm/common.c b/net/atm/common.c index f59112944c91..b84057e41bd6 100644 --- a/net/atm/common.c +++ b/net/atm/common.c | |||
@@ -577,9 +577,6 @@ int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m, | |||
577 | struct atm_vcc *vcc; | 577 | struct atm_vcc *vcc; |
578 | struct sk_buff *skb; | 578 | struct sk_buff *skb; |
579 | int eff, error; | 579 | int eff, error; |
580 | struct iov_iter from; | ||
581 | |||
582 | iov_iter_init(&from, WRITE, m->msg_iov, m->msg_iovlen, size); | ||
583 | 580 | ||
584 | lock_sock(sk); | 581 | lock_sock(sk); |
585 | if (sock->state != SS_CONNECTED) { | 582 | if (sock->state != SS_CONNECTED) { |
@@ -634,7 +631,7 @@ int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m, | |||
634 | goto out; | 631 | goto out; |
635 | skb->dev = NULL; /* for paths shared with net_device interfaces */ | 632 | skb->dev = NULL; /* for paths shared with net_device interfaces */ |
636 | ATM_SKB(skb)->atm_options = vcc->atm_options; | 633 | ATM_SKB(skb)->atm_options = vcc->atm_options; |
637 | if (copy_from_iter(skb_put(skb, size), size, &from) != size) { | 634 | if (copy_from_iter(skb_put(skb, size), size, &m->msg_iter) != size) { |
638 | kfree_skb(skb); | 635 | kfree_skb(skb); |
639 | error = -EFAULT; | 636 | error = -EFAULT; |
640 | goto out; | 637 | goto out; |
diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c index bdcaefd2db12..76617be1e797 100644 --- a/net/bluetooth/6lowpan.c +++ b/net/bluetooth/6lowpan.c | |||
@@ -537,12 +537,12 @@ static int send_pkt(struct l2cap_chan *chan, struct sk_buff *skb, | |||
537 | */ | 537 | */ |
538 | chan->data = skb; | 538 | chan->data = skb; |
539 | 539 | ||
540 | memset(&msg, 0, sizeof(msg)); | ||
541 | msg.msg_iov = (struct iovec *) &iv; | ||
542 | msg.msg_iovlen = 1; | ||
543 | iv.iov_base = skb->data; | 540 | iv.iov_base = skb->data; |
544 | iv.iov_len = skb->len; | 541 | iv.iov_len = skb->len; |
545 | 542 | ||
543 | memset(&msg, 0, sizeof(msg)); | ||
544 | iov_iter_kvec(&msg.msg_iter, WRITE | ITER_KVEC, &iv, 1, skb->len); | ||
545 | |||
546 | err = l2cap_chan_send(chan, &msg, skb->len); | 546 | err = l2cap_chan_send(chan, &msg, skb->len); |
547 | if (err > 0) { | 547 | if (err > 0) { |
548 | netdev->stats.tx_bytes += err; | 548 | netdev->stats.tx_bytes += err; |
@@ -1050,7 +1050,6 @@ static const struct l2cap_ops bt_6lowpan_chan_ops = { | |||
1050 | .suspend = chan_suspend_cb, | 1050 | .suspend = chan_suspend_cb, |
1051 | .get_sndtimeo = chan_get_sndtimeo_cb, | 1051 | .get_sndtimeo = chan_get_sndtimeo_cb, |
1052 | .alloc_skb = chan_alloc_skb_cb, | 1052 | .alloc_skb = chan_alloc_skb_cb, |
1053 | .memcpy_fromiovec = l2cap_chan_no_memcpy_fromiovec, | ||
1054 | 1053 | ||
1055 | .teardown = l2cap_chan_no_teardown, | 1054 | .teardown = l2cap_chan_no_teardown, |
1056 | .defer = l2cap_chan_no_defer, | 1055 | .defer = l2cap_chan_no_defer, |
diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c index 5dcade511fdb..cedfbda15dad 100644 --- a/net/bluetooth/a2mp.c +++ b/net/bluetooth/a2mp.c | |||
@@ -60,8 +60,7 @@ void a2mp_send(struct amp_mgr *mgr, u8 code, u8 ident, u16 len, void *data) | |||
60 | 60 | ||
61 | memset(&msg, 0, sizeof(msg)); | 61 | memset(&msg, 0, sizeof(msg)); |
62 | 62 | ||
63 | msg.msg_iov = (struct iovec *) &iv; | 63 | iov_iter_kvec(&msg.msg_iter, WRITE | ITER_KVEC, &iv, 1, total_len); |
64 | msg.msg_iovlen = 1; | ||
65 | 64 | ||
66 | l2cap_chan_send(chan, &msg, total_len); | 65 | l2cap_chan_send(chan, &msg, total_len); |
67 | 66 | ||
@@ -720,7 +719,6 @@ static const struct l2cap_ops a2mp_chan_ops = { | |||
720 | .resume = l2cap_chan_no_resume, | 719 | .resume = l2cap_chan_no_resume, |
721 | .set_shutdown = l2cap_chan_no_set_shutdown, | 720 | .set_shutdown = l2cap_chan_no_set_shutdown, |
722 | .get_sndtimeo = l2cap_chan_no_get_sndtimeo, | 721 | .get_sndtimeo = l2cap_chan_no_get_sndtimeo, |
723 | .memcpy_fromiovec = l2cap_chan_no_memcpy_fromiovec, | ||
724 | }; | 722 | }; |
725 | 723 | ||
726 | static struct l2cap_chan *a2mp_chan_open(struct l2cap_conn *conn, bool locked) | 724 | static struct l2cap_chan *a2mp_chan_open(struct l2cap_conn *conn, bool locked) |
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index a8da7ea9c2c0..a2b6dfa38a0c 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -2103,8 +2103,7 @@ static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan, | |||
2103 | struct sk_buff **frag; | 2103 | struct sk_buff **frag; |
2104 | int sent = 0; | 2104 | int sent = 0; |
2105 | 2105 | ||
2106 | if (chan->ops->memcpy_fromiovec(chan, skb_put(skb, count), | 2106 | if (copy_from_iter(skb_put(skb, count), count, &msg->msg_iter) != count) |
2107 | msg->msg_iov, count)) | ||
2108 | return -EFAULT; | 2107 | return -EFAULT; |
2109 | 2108 | ||
2110 | sent += count; | 2109 | sent += count; |
@@ -2124,8 +2123,8 @@ static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan, | |||
2124 | 2123 | ||
2125 | *frag = tmp; | 2124 | *frag = tmp; |
2126 | 2125 | ||
2127 | if (chan->ops->memcpy_fromiovec(chan, skb_put(*frag, count), | 2126 | if (copy_from_iter(skb_put(*frag, count), count, |
2128 | msg->msg_iov, count)) | 2127 | &msg->msg_iter) != count) |
2129 | return -EFAULT; | 2128 | return -EFAULT; |
2130 | 2129 | ||
2131 | sent += count; | 2130 | sent += count; |
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index b0efb7202957..f65caf41953f 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c | |||
@@ -1336,13 +1336,6 @@ static struct sk_buff *l2cap_sock_alloc_skb_cb(struct l2cap_chan *chan, | |||
1336 | return skb; | 1336 | return skb; |
1337 | } | 1337 | } |
1338 | 1338 | ||
1339 | static int l2cap_sock_memcpy_fromiovec_cb(struct l2cap_chan *chan, | ||
1340 | unsigned char *kdata, | ||
1341 | struct iovec *iov, int len) | ||
1342 | { | ||
1343 | return memcpy_fromiovec(kdata, iov, len); | ||
1344 | } | ||
1345 | |||
1346 | static void l2cap_sock_ready_cb(struct l2cap_chan *chan) | 1339 | static void l2cap_sock_ready_cb(struct l2cap_chan *chan) |
1347 | { | 1340 | { |
1348 | struct sock *sk = chan->data; | 1341 | struct sock *sk = chan->data; |
@@ -1427,7 +1420,6 @@ static const struct l2cap_ops l2cap_chan_ops = { | |||
1427 | .set_shutdown = l2cap_sock_set_shutdown_cb, | 1420 | .set_shutdown = l2cap_sock_set_shutdown_cb, |
1428 | .get_sndtimeo = l2cap_sock_get_sndtimeo_cb, | 1421 | .get_sndtimeo = l2cap_sock_get_sndtimeo_cb, |
1429 | .alloc_skb = l2cap_sock_alloc_skb_cb, | 1422 | .alloc_skb = l2cap_sock_alloc_skb_cb, |
1430 | .memcpy_fromiovec = l2cap_sock_memcpy_fromiovec_cb, | ||
1431 | }; | 1423 | }; |
1432 | 1424 | ||
1433 | static void l2cap_sock_destruct(struct sock *sk) | 1425 | static void l2cap_sock_destruct(struct sock *sk) |
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 96bf16dcd9e9..6a46252fe66f 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c | |||
@@ -539,8 +539,7 @@ static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data) | |||
539 | 539 | ||
540 | memset(&msg, 0, sizeof(msg)); | 540 | memset(&msg, 0, sizeof(msg)); |
541 | 541 | ||
542 | msg.msg_iov = (struct iovec *) &iv; | 542 | iov_iter_kvec(&msg.msg_iter, WRITE | ITER_KVEC, iv, 2, 1 + len); |
543 | msg.msg_iovlen = 2; | ||
544 | 543 | ||
545 | l2cap_chan_send(chan, &msg, 1 + len); | 544 | l2cap_chan_send(chan, &msg, 1 + len); |
546 | 545 | ||
@@ -2865,7 +2864,6 @@ static const struct l2cap_ops smp_chan_ops = { | |||
2865 | .suspend = l2cap_chan_no_suspend, | 2864 | .suspend = l2cap_chan_no_suspend, |
2866 | .set_shutdown = l2cap_chan_no_set_shutdown, | 2865 | .set_shutdown = l2cap_chan_no_set_shutdown, |
2867 | .get_sndtimeo = l2cap_chan_no_get_sndtimeo, | 2866 | .get_sndtimeo = l2cap_chan_no_get_sndtimeo, |
2868 | .memcpy_fromiovec = l2cap_chan_no_memcpy_fromiovec, | ||
2869 | }; | 2867 | }; |
2870 | 2868 | ||
2871 | static inline struct l2cap_chan *smp_new_conn_cb(struct l2cap_chan *pchan) | 2869 | static inline struct l2cap_chan *smp_new_conn_cb(struct l2cap_chan *pchan) |
@@ -2914,7 +2912,6 @@ static const struct l2cap_ops smp_root_chan_ops = { | |||
2914 | .resume = l2cap_chan_no_resume, | 2912 | .resume = l2cap_chan_no_resume, |
2915 | .set_shutdown = l2cap_chan_no_set_shutdown, | 2913 | .set_shutdown = l2cap_chan_no_set_shutdown, |
2916 | .get_sndtimeo = l2cap_chan_no_get_sndtimeo, | 2914 | .get_sndtimeo = l2cap_chan_no_get_sndtimeo, |
2917 | .memcpy_fromiovec = l2cap_chan_no_memcpy_fromiovec, | ||
2918 | }; | 2915 | }; |
2919 | 2916 | ||
2920 | static struct l2cap_chan *smp_add_cid(struct hci_dev *hdev, u16 cid) | 2917 | static struct l2cap_chan *smp_add_cid(struct hci_dev *hdev, u16 cid) |
diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c index ac618b0b8a4f..769b185fefbd 100644 --- a/net/caif/caif_socket.c +++ b/net/caif/caif_socket.c | |||
@@ -535,7 +535,7 @@ static int caif_seqpkt_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
535 | goto err; | 535 | goto err; |
536 | 536 | ||
537 | ret = -EINVAL; | 537 | ret = -EINVAL; |
538 | if (unlikely(msg->msg_iov->iov_base == NULL)) | 538 | if (unlikely(msg->msg_iter.iov->iov_base == NULL)) |
539 | goto err; | 539 | goto err; |
540 | noblock = msg->msg_flags & MSG_DONTWAIT; | 540 | noblock = msg->msg_flags & MSG_DONTWAIT; |
541 | 541 | ||
diff --git a/net/compat.c b/net/compat.c index 062f157d2a6b..3236b4167a32 100644 --- a/net/compat.c +++ b/net/compat.c | |||
@@ -37,13 +37,14 @@ ssize_t get_compat_msghdr(struct msghdr *kmsg, | |||
37 | struct iovec **iov) | 37 | struct iovec **iov) |
38 | { | 38 | { |
39 | compat_uptr_t uaddr, uiov, tmp3; | 39 | compat_uptr_t uaddr, uiov, tmp3; |
40 | compat_size_t nr_segs; | ||
40 | ssize_t err; | 41 | ssize_t err; |
41 | 42 | ||
42 | if (!access_ok(VERIFY_READ, umsg, sizeof(*umsg)) || | 43 | if (!access_ok(VERIFY_READ, umsg, sizeof(*umsg)) || |
43 | __get_user(uaddr, &umsg->msg_name) || | 44 | __get_user(uaddr, &umsg->msg_name) || |
44 | __get_user(kmsg->msg_namelen, &umsg->msg_namelen) || | 45 | __get_user(kmsg->msg_namelen, &umsg->msg_namelen) || |
45 | __get_user(uiov, &umsg->msg_iov) || | 46 | __get_user(uiov, &umsg->msg_iov) || |
46 | __get_user(kmsg->msg_iovlen, &umsg->msg_iovlen) || | 47 | __get_user(nr_segs, &umsg->msg_iovlen) || |
47 | __get_user(tmp3, &umsg->msg_control) || | 48 | __get_user(tmp3, &umsg->msg_control) || |
48 | __get_user(kmsg->msg_controllen, &umsg->msg_controllen) || | 49 | __get_user(kmsg->msg_controllen, &umsg->msg_controllen) || |
49 | __get_user(kmsg->msg_flags, &umsg->msg_flags)) | 50 | __get_user(kmsg->msg_flags, &umsg->msg_flags)) |
@@ -68,14 +69,15 @@ ssize_t get_compat_msghdr(struct msghdr *kmsg, | |||
68 | kmsg->msg_namelen = 0; | 69 | kmsg->msg_namelen = 0; |
69 | } | 70 | } |
70 | 71 | ||
71 | if (kmsg->msg_iovlen > UIO_MAXIOV) | 72 | if (nr_segs > UIO_MAXIOV) |
72 | return -EMSGSIZE; | 73 | return -EMSGSIZE; |
73 | 74 | ||
74 | err = compat_rw_copy_check_uvector(save_addr ? READ : WRITE, | 75 | err = compat_rw_copy_check_uvector(save_addr ? READ : WRITE, |
75 | compat_ptr(uiov), kmsg->msg_iovlen, | 76 | compat_ptr(uiov), nr_segs, |
76 | UIO_FASTIOV, *iov, iov); | 77 | UIO_FASTIOV, *iov, iov); |
77 | if (err >= 0) | 78 | if (err >= 0) |
78 | kmsg->msg_iov = *iov; | 79 | iov_iter_init(&kmsg->msg_iter, save_addr ? READ : WRITE, |
80 | *iov, nr_segs, err); | ||
79 | return err; | 81 | return err; |
80 | } | 82 | } |
81 | 83 | ||
diff --git a/net/core/datagram.c b/net/core/datagram.c index b6e303b0f01f..df493d68330c 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c | |||
@@ -310,90 +310,6 @@ int skb_kill_datagram(struct sock *sk, struct sk_buff *skb, unsigned int flags) | |||
310 | EXPORT_SYMBOL(skb_kill_datagram); | 310 | EXPORT_SYMBOL(skb_kill_datagram); |
311 | 311 | ||
312 | /** | 312 | /** |
313 | * skb_copy_datagram_iovec - Copy a datagram to an iovec. | ||
314 | * @skb: buffer to copy | ||
315 | * @offset: offset in the buffer to start copying from | ||
316 | * @to: io vector to copy to | ||
317 | * @len: amount of data to copy from buffer to iovec | ||
318 | * | ||
319 | * Note: the iovec is modified during the copy. | ||
320 | */ | ||
321 | int skb_copy_datagram_iovec(const struct sk_buff *skb, int offset, | ||
322 | struct iovec *to, int len) | ||
323 | { | ||
324 | int start = skb_headlen(skb); | ||
325 | int i, copy = start - offset; | ||
326 | struct sk_buff *frag_iter; | ||
327 | |||
328 | trace_skb_copy_datagram_iovec(skb, len); | ||
329 | |||
330 | /* Copy header. */ | ||
331 | if (copy > 0) { | ||
332 | if (copy > len) | ||
333 | copy = len; | ||
334 | if (memcpy_toiovec(to, skb->data + offset, copy)) | ||
335 | goto fault; | ||
336 | if ((len -= copy) == 0) | ||
337 | return 0; | ||
338 | offset += copy; | ||
339 | } | ||
340 | |||
341 | /* Copy paged appendix. Hmm... why does this look so complicated? */ | ||
342 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { | ||
343 | int end; | ||
344 | const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; | ||
345 | |||
346 | WARN_ON(start > offset + len); | ||
347 | |||
348 | end = start + skb_frag_size(frag); | ||
349 | if ((copy = end - offset) > 0) { | ||
350 | int err; | ||
351 | u8 *vaddr; | ||
352 | struct page *page = skb_frag_page(frag); | ||
353 | |||
354 | if (copy > len) | ||
355 | copy = len; | ||
356 | vaddr = kmap(page); | ||
357 | err = memcpy_toiovec(to, vaddr + frag->page_offset + | ||
358 | offset - start, copy); | ||
359 | kunmap(page); | ||
360 | if (err) | ||
361 | goto fault; | ||
362 | if (!(len -= copy)) | ||
363 | return 0; | ||
364 | offset += copy; | ||
365 | } | ||
366 | start = end; | ||
367 | } | ||
368 | |||
369 | skb_walk_frags(skb, frag_iter) { | ||
370 | int end; | ||
371 | |||
372 | WARN_ON(start > offset + len); | ||
373 | |||
374 | end = start + frag_iter->len; | ||
375 | if ((copy = end - offset) > 0) { | ||
376 | if (copy > len) | ||
377 | copy = len; | ||
378 | if (skb_copy_datagram_iovec(frag_iter, | ||
379 | offset - start, | ||
380 | to, copy)) | ||
381 | goto fault; | ||
382 | if ((len -= copy) == 0) | ||
383 | return 0; | ||
384 | offset += copy; | ||
385 | } | ||
386 | start = end; | ||
387 | } | ||
388 | if (!len) | ||
389 | return 0; | ||
390 | |||
391 | fault: | ||
392 | return -EFAULT; | ||
393 | } | ||
394 | EXPORT_SYMBOL(skb_copy_datagram_iovec); | ||
395 | |||
396 | /** | ||
397 | * skb_copy_datagram_iter - Copy a datagram to an iovec iterator. | 313 | * skb_copy_datagram_iter - Copy a datagram to an iovec iterator. |
398 | * @skb: buffer to copy | 314 | * @skb: buffer to copy |
399 | * @offset: offset in the buffer to start copying from | 315 | * @offset: offset in the buffer to start copying from |
@@ -615,27 +531,25 @@ int zerocopy_sg_from_iter(struct sk_buff *skb, struct iov_iter *from) | |||
615 | EXPORT_SYMBOL(zerocopy_sg_from_iter); | 531 | EXPORT_SYMBOL(zerocopy_sg_from_iter); |
616 | 532 | ||
617 | static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset, | 533 | static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset, |
618 | u8 __user *to, int len, | 534 | struct iov_iter *to, int len, |
619 | __wsum *csump) | 535 | __wsum *csump) |
620 | { | 536 | { |
621 | int start = skb_headlen(skb); | 537 | int start = skb_headlen(skb); |
622 | int i, copy = start - offset; | 538 | int i, copy = start - offset; |
623 | struct sk_buff *frag_iter; | 539 | struct sk_buff *frag_iter; |
624 | int pos = 0; | 540 | int pos = 0; |
541 | int n; | ||
625 | 542 | ||
626 | /* Copy header. */ | 543 | /* Copy header. */ |
627 | if (copy > 0) { | 544 | if (copy > 0) { |
628 | int err = 0; | ||
629 | if (copy > len) | 545 | if (copy > len) |
630 | copy = len; | 546 | copy = len; |
631 | *csump = csum_and_copy_to_user(skb->data + offset, to, copy, | 547 | n = csum_and_copy_to_iter(skb->data + offset, copy, csump, to); |
632 | *csump, &err); | 548 | if (n != copy) |
633 | if (err) | ||
634 | goto fault; | 549 | goto fault; |
635 | if ((len -= copy) == 0) | 550 | if ((len -= copy) == 0) |
636 | return 0; | 551 | return 0; |
637 | offset += copy; | 552 | offset += copy; |
638 | to += copy; | ||
639 | pos = copy; | 553 | pos = copy; |
640 | } | 554 | } |
641 | 555 | ||
@@ -647,26 +561,22 @@ static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset, | |||
647 | 561 | ||
648 | end = start + skb_frag_size(frag); | 562 | end = start + skb_frag_size(frag); |
649 | if ((copy = end - offset) > 0) { | 563 | if ((copy = end - offset) > 0) { |
650 | __wsum csum2; | 564 | __wsum csum2 = 0; |
651 | int err = 0; | ||
652 | u8 *vaddr; | ||
653 | struct page *page = skb_frag_page(frag); | 565 | struct page *page = skb_frag_page(frag); |
566 | u8 *vaddr = kmap(page); | ||
654 | 567 | ||
655 | if (copy > len) | 568 | if (copy > len) |
656 | copy = len; | 569 | copy = len; |
657 | vaddr = kmap(page); | 570 | n = csum_and_copy_to_iter(vaddr + frag->page_offset + |
658 | csum2 = csum_and_copy_to_user(vaddr + | 571 | offset - start, copy, |
659 | frag->page_offset + | 572 | &csum2, to); |
660 | offset - start, | ||
661 | to, copy, 0, &err); | ||
662 | kunmap(page); | 573 | kunmap(page); |
663 | if (err) | 574 | if (n != copy) |
664 | goto fault; | 575 | goto fault; |
665 | *csump = csum_block_add(*csump, csum2, pos); | 576 | *csump = csum_block_add(*csump, csum2, pos); |
666 | if (!(len -= copy)) | 577 | if (!(len -= copy)) |
667 | return 0; | 578 | return 0; |
668 | offset += copy; | 579 | offset += copy; |
669 | to += copy; | ||
670 | pos += copy; | 580 | pos += copy; |
671 | } | 581 | } |
672 | start = end; | 582 | start = end; |
@@ -691,7 +601,6 @@ static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset, | |||
691 | if ((len -= copy) == 0) | 601 | if ((len -= copy) == 0) |
692 | return 0; | 602 | return 0; |
693 | offset += copy; | 603 | offset += copy; |
694 | to += copy; | ||
695 | pos += copy; | 604 | pos += copy; |
696 | } | 605 | } |
697 | start = end; | 606 | start = end; |
@@ -744,20 +653,19 @@ __sum16 __skb_checksum_complete(struct sk_buff *skb) | |||
744 | EXPORT_SYMBOL(__skb_checksum_complete); | 653 | EXPORT_SYMBOL(__skb_checksum_complete); |
745 | 654 | ||
746 | /** | 655 | /** |
747 | * skb_copy_and_csum_datagram_iovec - Copy and checksum skb to user iovec. | 656 | * skb_copy_and_csum_datagram_msg - Copy and checksum skb to user iovec. |
748 | * @skb: skbuff | 657 | * @skb: skbuff |
749 | * @hlen: hardware length | 658 | * @hlen: hardware length |
750 | * @iov: io vector | 659 | * @msg: destination |
751 | * | 660 | * |
752 | * Caller _must_ check that skb will fit to this iovec. | 661 | * Caller _must_ check that skb will fit to this iovec. |
753 | * | 662 | * |
754 | * Returns: 0 - success. | 663 | * Returns: 0 - success. |
755 | * -EINVAL - checksum failure. | 664 | * -EINVAL - checksum failure. |
756 | * -EFAULT - fault during copy. Beware, in this case iovec | 665 | * -EFAULT - fault during copy. |
757 | * can be modified! | ||
758 | */ | 666 | */ |
759 | int skb_copy_and_csum_datagram_iovec(struct sk_buff *skb, | 667 | int skb_copy_and_csum_datagram_msg(struct sk_buff *skb, |
760 | int hlen, struct iovec *iov) | 668 | int hlen, struct msghdr *msg) |
761 | { | 669 | { |
762 | __wsum csum; | 670 | __wsum csum; |
763 | int chunk = skb->len - hlen; | 671 | int chunk = skb->len - hlen; |
@@ -765,28 +673,20 @@ int skb_copy_and_csum_datagram_iovec(struct sk_buff *skb, | |||
765 | if (!chunk) | 673 | if (!chunk) |
766 | return 0; | 674 | return 0; |
767 | 675 | ||
768 | /* Skip filled elements. | 676 | if (iov_iter_count(&msg->msg_iter) < chunk) { |
769 | * Pretty silly, look at memcpy_toiovec, though 8) | ||
770 | */ | ||
771 | while (!iov->iov_len) | ||
772 | iov++; | ||
773 | |||
774 | if (iov->iov_len < chunk) { | ||
775 | if (__skb_checksum_complete(skb)) | 677 | if (__skb_checksum_complete(skb)) |
776 | goto csum_error; | 678 | goto csum_error; |
777 | if (skb_copy_datagram_iovec(skb, hlen, iov, chunk)) | 679 | if (skb_copy_datagram_msg(skb, hlen, msg, chunk)) |
778 | goto fault; | 680 | goto fault; |
779 | } else { | 681 | } else { |
780 | csum = csum_partial(skb->data, hlen, skb->csum); | 682 | csum = csum_partial(skb->data, hlen, skb->csum); |
781 | if (skb_copy_and_csum_datagram(skb, hlen, iov->iov_base, | 683 | if (skb_copy_and_csum_datagram(skb, hlen, &msg->msg_iter, |
782 | chunk, &csum)) | 684 | chunk, &csum)) |
783 | goto fault; | 685 | goto fault; |
784 | if (csum_fold(csum)) | 686 | if (csum_fold(csum)) |
785 | goto csum_error; | 687 | goto csum_error; |
786 | if (unlikely(skb->ip_summed == CHECKSUM_COMPLETE)) | 688 | if (unlikely(skb->ip_summed == CHECKSUM_COMPLETE)) |
787 | netdev_rx_csum_fault(skb->dev); | 689 | netdev_rx_csum_fault(skb->dev); |
788 | iov->iov_len -= chunk; | ||
789 | iov->iov_base += chunk; | ||
790 | } | 690 | } |
791 | return 0; | 691 | return 0; |
792 | csum_error: | 692 | csum_error: |
@@ -794,7 +694,7 @@ csum_error: | |||
794 | fault: | 694 | fault: |
795 | return -EFAULT; | 695 | return -EFAULT; |
796 | } | 696 | } |
797 | EXPORT_SYMBOL(skb_copy_and_csum_datagram_iovec); | 697 | EXPORT_SYMBOL(skb_copy_and_csum_datagram_msg); |
798 | 698 | ||
799 | /** | 699 | /** |
800 | * datagram_poll - generic datagram poll | 700 | * datagram_poll - generic datagram poll |
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 4a929adf2ab7..b50861b22b6b 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
@@ -752,14 +752,16 @@ EXPORT_SYMBOL(ip_fragment); | |||
752 | int | 752 | int |
753 | ip_generic_getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb) | 753 | ip_generic_getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb) |
754 | { | 754 | { |
755 | struct iovec *iov = from; | 755 | struct msghdr *msg = from; |
756 | 756 | ||
757 | if (skb->ip_summed == CHECKSUM_PARTIAL) { | 757 | if (skb->ip_summed == CHECKSUM_PARTIAL) { |
758 | if (memcpy_fromiovecend(to, iov, offset, len) < 0) | 758 | /* XXX: stripping const */ |
759 | if (memcpy_fromiovecend(to, (struct iovec *)msg->msg_iter.iov, offset, len) < 0) | ||
759 | return -EFAULT; | 760 | return -EFAULT; |
760 | } else { | 761 | } else { |
761 | __wsum csum = 0; | 762 | __wsum csum = 0; |
762 | if (csum_partial_copy_fromiovecend(to, iov, offset, len, &csum) < 0) | 763 | /* XXX: stripping const */ |
764 | if (csum_partial_copy_fromiovecend(to, (struct iovec *)msg->msg_iter.iov, offset, len, &csum) < 0) | ||
763 | return -EFAULT; | 765 | return -EFAULT; |
764 | skb->csum = csum_block_add(skb->csum, csum, odd); | 766 | skb->csum = csum_block_add(skb->csum, csum, odd); |
765 | } | 767 | } |
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c index 8dd4ae0424fc..c0d82f78d364 100644 --- a/net/ipv4/ping.c +++ b/net/ipv4/ping.c | |||
@@ -811,7 +811,8 @@ back_from_confirm: | |||
811 | pfh.icmph.checksum = 0; | 811 | pfh.icmph.checksum = 0; |
812 | pfh.icmph.un.echo.id = inet->inet_sport; | 812 | pfh.icmph.un.echo.id = inet->inet_sport; |
813 | pfh.icmph.un.echo.sequence = user_icmph.un.echo.sequence; | 813 | pfh.icmph.un.echo.sequence = user_icmph.un.echo.sequence; |
814 | pfh.iov = msg->msg_iov; | 814 | /* XXX: stripping const */ |
815 | pfh.iov = (struct iovec *)msg->msg_iter.iov; | ||
815 | pfh.wcheck = 0; | 816 | pfh.wcheck = 0; |
816 | pfh.family = AF_INET; | 817 | pfh.family = AF_INET; |
817 | 818 | ||
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index 43385a9fa441..0bb68df5055d 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c | |||
@@ -82,7 +82,7 @@ | |||
82 | #include <linux/uio.h> | 82 | #include <linux/uio.h> |
83 | 83 | ||
84 | struct raw_frag_vec { | 84 | struct raw_frag_vec { |
85 | struct iovec *iov; | 85 | struct msghdr *msg; |
86 | union { | 86 | union { |
87 | struct icmphdr icmph; | 87 | struct icmphdr icmph; |
88 | char c[1]; | 88 | char c[1]; |
@@ -440,7 +440,7 @@ static int raw_probe_proto_opt(struct raw_frag_vec *rfv, struct flowi4 *fl4) | |||
440 | /* We only need the first two bytes. */ | 440 | /* We only need the first two bytes. */ |
441 | rfv->hlen = 2; | 441 | rfv->hlen = 2; |
442 | 442 | ||
443 | err = memcpy_fromiovec(rfv->hdr.c, rfv->iov, rfv->hlen); | 443 | err = memcpy_from_msg(rfv->hdr.c, rfv->msg, rfv->hlen); |
444 | if (err) | 444 | if (err) |
445 | return err; | 445 | return err; |
446 | 446 | ||
@@ -478,7 +478,7 @@ static int raw_getfrag(void *from, char *to, int offset, int len, int odd, | |||
478 | 478 | ||
479 | offset -= rfv->hlen; | 479 | offset -= rfv->hlen; |
480 | 480 | ||
481 | return ip_generic_getfrag(rfv->iov, to, offset, len, odd, skb); | 481 | return ip_generic_getfrag(rfv->msg, to, offset, len, odd, skb); |
482 | } | 482 | } |
483 | 483 | ||
484 | static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | 484 | static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, |
@@ -600,7 +600,7 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
600 | daddr, saddr, 0, 0); | 600 | daddr, saddr, 0, 0); |
601 | 601 | ||
602 | if (!inet->hdrincl) { | 602 | if (!inet->hdrincl) { |
603 | rfv.iov = msg->msg_iov; | 603 | rfv.msg = msg; |
604 | rfv.hlen = 0; | 604 | rfv.hlen = 0; |
605 | 605 | ||
606 | err = raw_probe_proto_opt(&rfv, &fl4); | 606 | err = raw_probe_proto_opt(&rfv, &fl4); |
@@ -625,7 +625,8 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
625 | back_from_confirm: | 625 | back_from_confirm: |
626 | 626 | ||
627 | if (inet->hdrincl) | 627 | if (inet->hdrincl) |
628 | err = raw_send_hdrinc(sk, &fl4, msg->msg_iov, len, | 628 | /* XXX: stripping const */ |
629 | err = raw_send_hdrinc(sk, &fl4, (struct iovec *)msg->msg_iter.iov, len, | ||
629 | &rt, msg->msg_flags); | 630 | &rt, msg->msg_flags); |
630 | 631 | ||
631 | else { | 632 | else { |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 427aee33ffc0..3075723c729b 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -1067,7 +1067,7 @@ static int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg, | |||
1067 | int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | 1067 | int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, |
1068 | size_t size) | 1068 | size_t size) |
1069 | { | 1069 | { |
1070 | struct iovec *iov; | 1070 | const struct iovec *iov; |
1071 | struct tcp_sock *tp = tcp_sk(sk); | 1071 | struct tcp_sock *tp = tcp_sk(sk); |
1072 | struct sk_buff *skb; | 1072 | struct sk_buff *skb; |
1073 | int iovlen, flags, err, copied = 0; | 1073 | int iovlen, flags, err, copied = 0; |
@@ -1118,8 +1118,8 @@ int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
1118 | mss_now = tcp_send_mss(sk, &size_goal, flags); | 1118 | mss_now = tcp_send_mss(sk, &size_goal, flags); |
1119 | 1119 | ||
1120 | /* Ok commence sending. */ | 1120 | /* Ok commence sending. */ |
1121 | iovlen = msg->msg_iovlen; | 1121 | iovlen = msg->msg_iter.nr_segs; |
1122 | iov = msg->msg_iov; | 1122 | iov = msg->msg_iter.iov; |
1123 | copied = 0; | 1123 | copied = 0; |
1124 | 1124 | ||
1125 | err = -EPIPE; | 1125 | err = -EPIPE; |
@@ -1711,7 +1711,7 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
1711 | if (!user_recv && !(flags & (MSG_TRUNC | MSG_PEEK))) { | 1711 | if (!user_recv && !(flags & (MSG_TRUNC | MSG_PEEK))) { |
1712 | user_recv = current; | 1712 | user_recv = current; |
1713 | tp->ucopy.task = user_recv; | 1713 | tp->ucopy.task = user_recv; |
1714 | tp->ucopy.iov = msg->msg_iov; | 1714 | tp->ucopy.msg = msg; |
1715 | } | 1715 | } |
1716 | 1716 | ||
1717 | tp->ucopy.len = len; | 1717 | tp->ucopy.len = len; |
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 69de1a1c05c9..075ab4d5af5e 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -4421,7 +4421,7 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) | |||
4421 | __set_current_state(TASK_RUNNING); | 4421 | __set_current_state(TASK_RUNNING); |
4422 | 4422 | ||
4423 | local_bh_enable(); | 4423 | local_bh_enable(); |
4424 | if (!skb_copy_datagram_iovec(skb, 0, tp->ucopy.iov, chunk)) { | 4424 | if (!skb_copy_datagram_msg(skb, 0, tp->ucopy.msg, chunk)) { |
4425 | tp->ucopy.len -= chunk; | 4425 | tp->ucopy.len -= chunk; |
4426 | tp->copied_seq += chunk; | 4426 | tp->copied_seq += chunk; |
4427 | eaten = (chunk == skb->len); | 4427 | eaten = (chunk == skb->len); |
@@ -4941,10 +4941,9 @@ static int tcp_copy_to_iovec(struct sock *sk, struct sk_buff *skb, int hlen) | |||
4941 | 4941 | ||
4942 | local_bh_enable(); | 4942 | local_bh_enable(); |
4943 | if (skb_csum_unnecessary(skb)) | 4943 | if (skb_csum_unnecessary(skb)) |
4944 | err = skb_copy_datagram_iovec(skb, hlen, tp->ucopy.iov, chunk); | 4944 | err = skb_copy_datagram_msg(skb, hlen, tp->ucopy.msg, chunk); |
4945 | else | 4945 | else |
4946 | err = skb_copy_and_csum_datagram_iovec(skb, hlen, | 4946 | err = skb_copy_and_csum_datagram_msg(skb, hlen, tp->ucopy.msg); |
4947 | tp->ucopy.iov); | ||
4948 | 4947 | ||
4949 | if (!err) { | 4948 | if (!err) { |
4950 | tp->ucopy.len -= chunk; | 4949 | tp->ucopy.len -= chunk; |
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index f37ecf53ee8a..7f18262e2326 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -3073,7 +3073,7 @@ static int tcp_send_syn_data(struct sock *sk, struct sk_buff *syn) | |||
3073 | syn_data->ip_summed = CHECKSUM_PARTIAL; | 3073 | syn_data->ip_summed = CHECKSUM_PARTIAL; |
3074 | memcpy(syn_data->cb, syn->cb, sizeof(syn->cb)); | 3074 | memcpy(syn_data->cb, syn->cb, sizeof(syn->cb)); |
3075 | if (unlikely(memcpy_fromiovecend(skb_put(syn_data, space), | 3075 | if (unlikely(memcpy_fromiovecend(skb_put(syn_data, space), |
3076 | fo->data->msg_iov, 0, space))) { | 3076 | fo->data->msg_iter.iov, 0, space))) { |
3077 | kfree_skb(syn_data); | 3077 | kfree_skb(syn_data); |
3078 | goto fallback; | 3078 | goto fallback; |
3079 | } | 3079 | } |
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index dd8e00634563..13b4dcf86ef6 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -1049,7 +1049,7 @@ back_from_confirm: | |||
1049 | 1049 | ||
1050 | /* Lockless fast path for the non-corking case. */ | 1050 | /* Lockless fast path for the non-corking case. */ |
1051 | if (!corkreq) { | 1051 | if (!corkreq) { |
1052 | skb = ip_make_skb(sk, fl4, getfrag, msg->msg_iov, ulen, | 1052 | skb = ip_make_skb(sk, fl4, getfrag, msg, ulen, |
1053 | sizeof(struct udphdr), &ipc, &rt, | 1053 | sizeof(struct udphdr), &ipc, &rt, |
1054 | msg->msg_flags); | 1054 | msg->msg_flags); |
1055 | err = PTR_ERR(skb); | 1055 | err = PTR_ERR(skb); |
@@ -1080,7 +1080,7 @@ back_from_confirm: | |||
1080 | 1080 | ||
1081 | do_append_data: | 1081 | do_append_data: |
1082 | up->len += ulen; | 1082 | up->len += ulen; |
1083 | err = ip_append_data(sk, fl4, getfrag, msg->msg_iov, ulen, | 1083 | err = ip_append_data(sk, fl4, getfrag, msg, ulen, |
1084 | sizeof(struct udphdr), &ipc, &rt, | 1084 | sizeof(struct udphdr), &ipc, &rt, |
1085 | corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags); | 1085 | corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags); |
1086 | if (err) | 1086 | if (err) |
diff --git a/net/ipv6/ping.c b/net/ipv6/ping.c index 5b7a1ed2aba9..2d3148378a1f 100644 --- a/net/ipv6/ping.c +++ b/net/ipv6/ping.c | |||
@@ -163,7 +163,8 @@ int ping_v6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
163 | pfh.icmph.checksum = 0; | 163 | pfh.icmph.checksum = 0; |
164 | pfh.icmph.un.echo.id = inet->inet_sport; | 164 | pfh.icmph.un.echo.id = inet->inet_sport; |
165 | pfh.icmph.un.echo.sequence = user_icmph.icmp6_sequence; | 165 | pfh.icmph.un.echo.sequence = user_icmph.icmp6_sequence; |
166 | pfh.iov = msg->msg_iov; | 166 | /* XXX: stripping const */ |
167 | pfh.iov = (struct iovec *)msg->msg_iter.iov; | ||
167 | pfh.wcheck = 0; | 168 | pfh.wcheck = 0; |
168 | pfh.family = AF_INET6; | 169 | pfh.family = AF_INET6; |
169 | 170 | ||
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 8baa53e17a30..ee25631f8c29 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
@@ -672,65 +672,62 @@ error: | |||
672 | return err; | 672 | return err; |
673 | } | 673 | } |
674 | 674 | ||
675 | static int rawv6_probe_proto_opt(struct flowi6 *fl6, struct msghdr *msg) | 675 | struct raw6_frag_vec { |
676 | struct msghdr *msg; | ||
677 | int hlen; | ||
678 | char c[4]; | ||
679 | }; | ||
680 | |||
681 | static int rawv6_probe_proto_opt(struct raw6_frag_vec *rfv, struct flowi6 *fl6) | ||
676 | { | 682 | { |
677 | struct iovec *iov; | 683 | int err = 0; |
678 | u8 __user *type = NULL; | 684 | switch (fl6->flowi6_proto) { |
679 | u8 __user *code = NULL; | 685 | case IPPROTO_ICMPV6: |
680 | u8 len = 0; | 686 | rfv->hlen = 2; |
681 | int probed = 0; | 687 | err = memcpy_from_msg(rfv->c, rfv->msg, rfv->hlen); |
682 | int i; | 688 | if (!err) { |
683 | 689 | fl6->fl6_icmp_type = rfv->c[0]; | |
684 | if (!msg->msg_iov) | 690 | fl6->fl6_icmp_code = rfv->c[1]; |
685 | return 0; | 691 | } |
692 | break; | ||
693 | case IPPROTO_MH: | ||
694 | rfv->hlen = 4; | ||
695 | err = memcpy_from_msg(rfv->c, rfv->msg, rfv->hlen); | ||
696 | if (!err) | ||
697 | fl6->fl6_mh_type = rfv->c[2]; | ||
698 | } | ||
699 | return err; | ||
700 | } | ||
686 | 701 | ||
687 | for (i = 0; i < msg->msg_iovlen; i++) { | 702 | static int raw6_getfrag(void *from, char *to, int offset, int len, int odd, |
688 | iov = &msg->msg_iov[i]; | 703 | struct sk_buff *skb) |
689 | if (!iov) | 704 | { |
690 | continue; | 705 | struct raw6_frag_vec *rfv = from; |
691 | 706 | ||
692 | switch (fl6->flowi6_proto) { | 707 | if (offset < rfv->hlen) { |
693 | case IPPROTO_ICMPV6: | 708 | int copy = min(rfv->hlen - offset, len); |
694 | /* check if one-byte field is readable or not. */ | ||
695 | if (iov->iov_base && iov->iov_len < 1) | ||
696 | break; | ||
697 | |||
698 | if (!type) { | ||
699 | type = iov->iov_base; | ||
700 | /* check if code field is readable or not. */ | ||
701 | if (iov->iov_len > 1) | ||
702 | code = type + 1; | ||
703 | } else if (!code) | ||
704 | code = iov->iov_base; | ||
705 | |||
706 | if (type && code) { | ||
707 | if (get_user(fl6->fl6_icmp_type, type) || | ||
708 | get_user(fl6->fl6_icmp_code, code)) | ||
709 | return -EFAULT; | ||
710 | probed = 1; | ||
711 | } | ||
712 | break; | ||
713 | case IPPROTO_MH: | ||
714 | if (iov->iov_base && iov->iov_len < 1) | ||
715 | break; | ||
716 | /* check if type field is readable or not. */ | ||
717 | if (iov->iov_len > 2 - len) { | ||
718 | u8 __user *p = iov->iov_base; | ||
719 | if (get_user(fl6->fl6_mh_type, &p[2 - len])) | ||
720 | return -EFAULT; | ||
721 | probed = 1; | ||
722 | } else | ||
723 | len += iov->iov_len; | ||
724 | 709 | ||
725 | break; | 710 | if (skb->ip_summed == CHECKSUM_PARTIAL) |
726 | default: | 711 | memcpy(to, rfv->c + offset, copy); |
727 | probed = 1; | 712 | else |
728 | break; | 713 | skb->csum = csum_block_add( |
729 | } | 714 | skb->csum, |
730 | if (probed) | 715 | csum_partial_copy_nocheck(rfv->c + offset, |
731 | break; | 716 | to, copy, 0), |
717 | odd); | ||
718 | |||
719 | odd = 0; | ||
720 | offset += copy; | ||
721 | to += copy; | ||
722 | len -= copy; | ||
723 | |||
724 | if (!len) | ||
725 | return 0; | ||
732 | } | 726 | } |
733 | return 0; | 727 | |
728 | offset -= rfv->hlen; | ||
729 | |||
730 | return ip_generic_getfrag(rfv->msg, to, offset, len, odd, skb); | ||
734 | } | 731 | } |
735 | 732 | ||
736 | static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, | 733 | static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, |
@@ -745,6 +742,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
745 | struct ipv6_txoptions *opt = NULL; | 742 | struct ipv6_txoptions *opt = NULL; |
746 | struct ip6_flowlabel *flowlabel = NULL; | 743 | struct ip6_flowlabel *flowlabel = NULL; |
747 | struct dst_entry *dst = NULL; | 744 | struct dst_entry *dst = NULL; |
745 | struct raw6_frag_vec rfv; | ||
748 | struct flowi6 fl6; | 746 | struct flowi6 fl6; |
749 | int addr_len = msg->msg_namelen; | 747 | int addr_len = msg->msg_namelen; |
750 | int hlimit = -1; | 748 | int hlimit = -1; |
@@ -848,7 +846,9 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
848 | opt = ipv6_fixup_options(&opt_space, opt); | 846 | opt = ipv6_fixup_options(&opt_space, opt); |
849 | 847 | ||
850 | fl6.flowi6_proto = proto; | 848 | fl6.flowi6_proto = proto; |
851 | err = rawv6_probe_proto_opt(&fl6, msg); | 849 | rfv.msg = msg; |
850 | rfv.hlen = 0; | ||
851 | err = rawv6_probe_proto_opt(&rfv, &fl6); | ||
852 | if (err) | 852 | if (err) |
853 | goto out; | 853 | goto out; |
854 | 854 | ||
@@ -886,10 +886,11 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
886 | 886 | ||
887 | back_from_confirm: | 887 | back_from_confirm: |
888 | if (inet->hdrincl) | 888 | if (inet->hdrincl) |
889 | err = rawv6_send_hdrinc(sk, msg->msg_iov, len, &fl6, &dst, msg->msg_flags); | 889 | /* XXX: stripping const */ |
890 | err = rawv6_send_hdrinc(sk, (struct iovec *)msg->msg_iter.iov, len, &fl6, &dst, msg->msg_flags); | ||
890 | else { | 891 | else { |
891 | lock_sock(sk); | 892 | lock_sock(sk); |
892 | err = ip6_append_data(sk, ip_generic_getfrag, msg->msg_iov, | 893 | err = ip6_append_data(sk, raw6_getfrag, &rfv, |
893 | len, 0, hlimit, tclass, opt, &fl6, (struct rt6_info *)dst, | 894 | len, 0, hlimit, tclass, opt, &fl6, (struct rt6_info *)dst, |
894 | msg->msg_flags, dontfrag); | 895 | msg->msg_flags, dontfrag); |
895 | 896 | ||
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 7f96432292ce..189dc4ae3eca 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -1312,7 +1312,7 @@ do_append_data: | |||
1312 | dontfrag = np->dontfrag; | 1312 | dontfrag = np->dontfrag; |
1313 | up->len += ulen; | 1313 | up->len += ulen; |
1314 | getfrag = is_udplite ? udplite_getfrag : ip_generic_getfrag; | 1314 | getfrag = is_udplite ? udplite_getfrag : ip_generic_getfrag; |
1315 | err = ip6_append_data(sk, getfrag, msg->msg_iov, ulen, | 1315 | err = ip6_append_data(sk, getfrag, msg, ulen, |
1316 | sizeof(struct udphdr), hlimit, tclass, opt, &fl6, | 1316 | sizeof(struct udphdr), hlimit, tclass, opt, &fl6, |
1317 | (struct rt6_info *)dst, | 1317 | (struct rt6_info *)dst, |
1318 | corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags, dontfrag); | 1318 | corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags, dontfrag); |
diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c index 2177b960da87..8611f1b63141 100644 --- a/net/l2tp/l2tp_ip6.c +++ b/net/l2tp/l2tp_ip6.c | |||
@@ -619,7 +619,7 @@ static int l2tp_ip6_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
619 | 619 | ||
620 | back_from_confirm: | 620 | back_from_confirm: |
621 | lock_sock(sk); | 621 | lock_sock(sk); |
622 | err = ip6_append_data(sk, ip_generic_getfrag, msg->msg_iov, | 622 | err = ip6_append_data(sk, ip_generic_getfrag, msg, |
623 | ulen, transhdrlen, hlimit, tclass, opt, | 623 | ulen, transhdrlen, hlimit, tclass, opt, |
624 | &fl6, (struct rt6_info *)dst, | 624 | &fl6, (struct rt6_info *)dst, |
625 | msg->msg_flags, dontfrag); | 625 | msg->msg_flags, dontfrag); |
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 63aa5c8acf12..cc9bcf008b03 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
@@ -2305,7 +2305,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
2305 | } | 2305 | } |
2306 | 2306 | ||
2307 | if (netlink_tx_is_mmaped(sk) && | 2307 | if (netlink_tx_is_mmaped(sk) && |
2308 | msg->msg_iov->iov_base == NULL) { | 2308 | msg->msg_iter.iov->iov_base == NULL) { |
2309 | err = netlink_mmap_sendmsg(sk, msg, dst_portid, dst_group, | 2309 | err = netlink_mmap_sendmsg(sk, msg, dst_portid, dst_group, |
2310 | siocb); | 2310 | siocb); |
2311 | goto out; | 2311 | goto out; |
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index efa844501136..ed2e620b61df 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -2408,11 +2408,8 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) | |||
2408 | unsigned short gso_type = 0; | 2408 | unsigned short gso_type = 0; |
2409 | int hlen, tlen; | 2409 | int hlen, tlen; |
2410 | int extra_len = 0; | 2410 | int extra_len = 0; |
2411 | struct iov_iter from; | ||
2412 | ssize_t n; | 2411 | ssize_t n; |
2413 | 2412 | ||
2414 | iov_iter_init(&from, WRITE, msg->msg_iov, msg->msg_iovlen, len); | ||
2415 | |||
2416 | /* | 2413 | /* |
2417 | * Get and verify the address. | 2414 | * Get and verify the address. |
2418 | */ | 2415 | */ |
@@ -2451,7 +2448,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) | |||
2451 | len -= vnet_hdr_len; | 2448 | len -= vnet_hdr_len; |
2452 | 2449 | ||
2453 | err = -EFAULT; | 2450 | err = -EFAULT; |
2454 | n = copy_from_iter(&vnet_hdr, vnet_hdr_len, &from); | 2451 | n = copy_from_iter(&vnet_hdr, vnet_hdr_len, &msg->msg_iter); |
2455 | if (n != vnet_hdr_len) | 2452 | if (n != vnet_hdr_len) |
2456 | goto out_unlock; | 2453 | goto out_unlock; |
2457 | 2454 | ||
@@ -2522,7 +2519,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) | |||
2522 | } | 2519 | } |
2523 | 2520 | ||
2524 | /* Returns -EFAULT on error */ | 2521 | /* Returns -EFAULT on error */ |
2525 | err = skb_copy_datagram_from_iter(skb, offset, &from, len); | 2522 | err = skb_copy_datagram_from_iter(skb, offset, &msg->msg_iter, len); |
2526 | if (err) | 2523 | if (err) |
2527 | goto out_free; | 2524 | goto out_free; |
2528 | 2525 | ||
diff --git a/net/rds/recv.c b/net/rds/recv.c index 47d7b1029b33..f9ec1acd801c 100644 --- a/net/rds/recv.c +++ b/net/rds/recv.c | |||
@@ -404,7 +404,6 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, | |||
404 | int ret = 0, nonblock = msg_flags & MSG_DONTWAIT; | 404 | int ret = 0, nonblock = msg_flags & MSG_DONTWAIT; |
405 | DECLARE_SOCKADDR(struct sockaddr_in *, sin, msg->msg_name); | 405 | DECLARE_SOCKADDR(struct sockaddr_in *, sin, msg->msg_name); |
406 | struct rds_incoming *inc = NULL; | 406 | struct rds_incoming *inc = NULL; |
407 | struct iov_iter to; | ||
408 | 407 | ||
409 | /* udp_recvmsg()->sock_recvtimeo() gets away without locking too.. */ | 408 | /* udp_recvmsg()->sock_recvtimeo() gets away without locking too.. */ |
410 | timeo = sock_rcvtimeo(sk, nonblock); | 409 | timeo = sock_rcvtimeo(sk, nonblock); |
@@ -415,6 +414,7 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, | |||
415 | goto out; | 414 | goto out; |
416 | 415 | ||
417 | while (1) { | 416 | while (1) { |
417 | struct iov_iter save; | ||
418 | /* If there are pending notifications, do those - and nothing else */ | 418 | /* If there are pending notifications, do those - and nothing else */ |
419 | if (!list_empty(&rs->rs_notify_queue)) { | 419 | if (!list_empty(&rs->rs_notify_queue)) { |
420 | ret = rds_notify_queue_get(rs, msg); | 420 | ret = rds_notify_queue_get(rs, msg); |
@@ -450,8 +450,8 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, | |||
450 | rdsdebug("copying inc %p from %pI4:%u to user\n", inc, | 450 | rdsdebug("copying inc %p from %pI4:%u to user\n", inc, |
451 | &inc->i_conn->c_faddr, | 451 | &inc->i_conn->c_faddr, |
452 | ntohs(inc->i_hdr.h_sport)); | 452 | ntohs(inc->i_hdr.h_sport)); |
453 | iov_iter_init(&to, READ, msg->msg_iov, msg->msg_iovlen, size); | 453 | save = msg->msg_iter; |
454 | ret = inc->i_conn->c_trans->inc_copy_to_user(inc, &to); | 454 | ret = inc->i_conn->c_trans->inc_copy_to_user(inc, &msg->msg_iter); |
455 | if (ret < 0) | 455 | if (ret < 0) |
456 | break; | 456 | break; |
457 | 457 | ||
@@ -464,6 +464,7 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, | |||
464 | rds_inc_put(inc); | 464 | rds_inc_put(inc); |
465 | inc = NULL; | 465 | inc = NULL; |
466 | rds_stats_inc(s_recv_deliver_raced); | 466 | rds_stats_inc(s_recv_deliver_raced); |
467 | msg->msg_iter = save; | ||
467 | continue; | 468 | continue; |
468 | } | 469 | } |
469 | 470 | ||
diff --git a/net/rds/send.c b/net/rds/send.c index 4de62ead1c71..40a5629a0a13 100644 --- a/net/rds/send.c +++ b/net/rds/send.c | |||
@@ -934,9 +934,7 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, | |||
934 | int queued = 0, allocated_mr = 0; | 934 | int queued = 0, allocated_mr = 0; |
935 | int nonblock = msg->msg_flags & MSG_DONTWAIT; | 935 | int nonblock = msg->msg_flags & MSG_DONTWAIT; |
936 | long timeo = sock_sndtimeo(sk, nonblock); | 936 | long timeo = sock_sndtimeo(sk, nonblock); |
937 | struct iov_iter from; | ||
938 | 937 | ||
939 | iov_iter_init(&from, WRITE, msg->msg_iov, msg->msg_iovlen, payload_len); | ||
940 | /* Mirror Linux UDP mirror of BSD error message compatibility */ | 938 | /* Mirror Linux UDP mirror of BSD error message compatibility */ |
941 | /* XXX: Perhaps MSG_MORE someday */ | 939 | /* XXX: Perhaps MSG_MORE someday */ |
942 | if (msg->msg_flags & ~(MSG_DONTWAIT | MSG_CMSG_COMPAT)) { | 940 | 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, | |||
984 | ret = -ENOMEM; | 982 | ret = -ENOMEM; |
985 | goto out; | 983 | goto out; |
986 | } | 984 | } |
987 | ret = rds_message_copy_from_user(rm, &from); | 985 | ret = rds_message_copy_from_user(rm, &msg->msg_iter); |
988 | if (ret) | 986 | if (ret) |
989 | goto out; | 987 | goto out; |
990 | } | 988 | } |
diff --git a/net/rxrpc/ar-output.c b/net/rxrpc/ar-output.c index 0b4b9a79f5ab..86e0f10aa2c0 100644 --- a/net/rxrpc/ar-output.c +++ b/net/rxrpc/ar-output.c | |||
@@ -531,14 +531,12 @@ static int rxrpc_send_data(struct kiocb *iocb, | |||
531 | struct rxrpc_skb_priv *sp; | 531 | struct rxrpc_skb_priv *sp; |
532 | unsigned char __user *from; | 532 | unsigned char __user *from; |
533 | struct sk_buff *skb; | 533 | struct sk_buff *skb; |
534 | struct iovec *iov; | 534 | const struct iovec *iov; |
535 | struct sock *sk = &rx->sk; | 535 | struct sock *sk = &rx->sk; |
536 | long timeo; | 536 | long timeo; |
537 | bool more; | 537 | bool more; |
538 | int ret, ioc, segment, copied; | 538 | int ret, ioc, segment, copied; |
539 | 539 | ||
540 | _enter(",,,{%zu},%zu", msg->msg_iovlen, len); | ||
541 | |||
542 | timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT); | 540 | timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT); |
543 | 541 | ||
544 | /* this should be in poll */ | 542 | /* this should be in poll */ |
@@ -547,8 +545,8 @@ static int rxrpc_send_data(struct kiocb *iocb, | |||
547 | if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN)) | 545 | if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN)) |
548 | return -EPIPE; | 546 | return -EPIPE; |
549 | 547 | ||
550 | iov = msg->msg_iov; | 548 | iov = msg->msg_iter.iov; |
551 | ioc = msg->msg_iovlen - 1; | 549 | ioc = msg->msg_iter.nr_segs - 1; |
552 | from = iov->iov_base; | 550 | from = iov->iov_base; |
553 | segment = iov->iov_len; | 551 | segment = iov->iov_len; |
554 | iov++; | 552 | iov++; |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 0397ac9fd98c..c92f96cda699 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -1609,9 +1609,6 @@ static int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
1609 | __u16 sinfo_flags = 0; | 1609 | __u16 sinfo_flags = 0; |
1610 | long timeo; | 1610 | long timeo; |
1611 | int err; | 1611 | int err; |
1612 | struct iov_iter from; | ||
1613 | |||
1614 | iov_iter_init(&from, WRITE, msg->msg_iov, msg->msg_iovlen, msg_len); | ||
1615 | 1612 | ||
1616 | err = 0; | 1613 | err = 0; |
1617 | sp = sctp_sk(sk); | 1614 | sp = sctp_sk(sk); |
@@ -1950,7 +1947,7 @@ static int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
1950 | } | 1947 | } |
1951 | 1948 | ||
1952 | /* Break the message into multiple chunks of maximum size. */ | 1949 | /* Break the message into multiple chunks of maximum size. */ |
1953 | datamsg = sctp_datamsg_from_user(asoc, sinfo, &from); | 1950 | datamsg = sctp_datamsg_from_user(asoc, sinfo, &msg->msg_iter); |
1954 | if (IS_ERR(datamsg)) { | 1951 | if (IS_ERR(datamsg)) { |
1955 | err = PTR_ERR(datamsg); | 1952 | err = PTR_ERR(datamsg); |
1956 | goto out_free; | 1953 | goto out_free; |
diff --git a/net/socket.c b/net/socket.c index f676ac4a3701..8809afccf7fa 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -689,8 +689,7 @@ int kernel_sendmsg(struct socket *sock, struct msghdr *msg, | |||
689 | * the following is safe, since for compiler definitions of kvec and | 689 | * the following is safe, since for compiler definitions of kvec and |
690 | * iovec are identical, yielding the same in-core layout and alignment | 690 | * iovec are identical, yielding the same in-core layout and alignment |
691 | */ | 691 | */ |
692 | msg->msg_iov = (struct iovec *)vec; | 692 | iov_iter_init(&msg->msg_iter, WRITE, (struct iovec *)vec, num, size); |
693 | msg->msg_iovlen = num; | ||
694 | result = sock_sendmsg(sock, msg, size); | 693 | result = sock_sendmsg(sock, msg, size); |
695 | set_fs(oldfs); | 694 | set_fs(oldfs); |
696 | return result; | 695 | return result; |
@@ -853,7 +852,7 @@ int kernel_recvmsg(struct socket *sock, struct msghdr *msg, | |||
853 | * the following is safe, since for compiler definitions of kvec and | 852 | * the following is safe, since for compiler definitions of kvec and |
854 | * iovec are identical, yielding the same in-core layout and alignment | 853 | * iovec are identical, yielding the same in-core layout and alignment |
855 | */ | 854 | */ |
856 | msg->msg_iov = (struct iovec *)vec, msg->msg_iovlen = num; | 855 | iov_iter_init(&msg->msg_iter, READ, (struct iovec *)vec, num, size); |
857 | result = sock_recvmsg(sock, msg, size, flags); | 856 | result = sock_recvmsg(sock, msg, size, flags); |
858 | set_fs(oldfs); | 857 | set_fs(oldfs); |
859 | return result; | 858 | return result; |
@@ -913,8 +912,7 @@ static ssize_t do_sock_read(struct msghdr *msg, struct kiocb *iocb, | |||
913 | msg->msg_namelen = 0; | 912 | msg->msg_namelen = 0; |
914 | msg->msg_control = NULL; | 913 | msg->msg_control = NULL; |
915 | msg->msg_controllen = 0; | 914 | msg->msg_controllen = 0; |
916 | msg->msg_iov = (struct iovec *)iov; | 915 | iov_iter_init(&msg->msg_iter, READ, iov, nr_segs, size); |
917 | msg->msg_iovlen = nr_segs; | ||
918 | msg->msg_flags = (file->f_flags & O_NONBLOCK) ? MSG_DONTWAIT : 0; | 916 | msg->msg_flags = (file->f_flags & O_NONBLOCK) ? MSG_DONTWAIT : 0; |
919 | 917 | ||
920 | return __sock_recvmsg(iocb, sock, msg, size, msg->msg_flags); | 918 | 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, | |||
953 | msg->msg_namelen = 0; | 951 | msg->msg_namelen = 0; |
954 | msg->msg_control = NULL; | 952 | msg->msg_control = NULL; |
955 | msg->msg_controllen = 0; | 953 | msg->msg_controllen = 0; |
956 | msg->msg_iov = (struct iovec *)iov; | 954 | iov_iter_init(&msg->msg_iter, WRITE, iov, nr_segs, size); |
957 | msg->msg_iovlen = nr_segs; | ||
958 | msg->msg_flags = (file->f_flags & O_NONBLOCK) ? MSG_DONTWAIT : 0; | 955 | msg->msg_flags = (file->f_flags & O_NONBLOCK) ? MSG_DONTWAIT : 0; |
959 | if (sock->type == SOCK_SEQPACKET) | 956 | if (sock->type == SOCK_SEQPACKET) |
960 | msg->msg_flags |= MSG_EOR; | 957 | msg->msg_flags |= MSG_EOR; |
@@ -1798,8 +1795,7 @@ SYSCALL_DEFINE6(sendto, int, fd, void __user *, buff, size_t, len, | |||
1798 | iov.iov_base = buff; | 1795 | iov.iov_base = buff; |
1799 | iov.iov_len = len; | 1796 | iov.iov_len = len; |
1800 | msg.msg_name = NULL; | 1797 | msg.msg_name = NULL; |
1801 | msg.msg_iov = &iov; | 1798 | iov_iter_init(&msg.msg_iter, WRITE, &iov, 1, len); |
1802 | msg.msg_iovlen = 1; | ||
1803 | msg.msg_control = NULL; | 1799 | msg.msg_control = NULL; |
1804 | msg.msg_controllen = 0; | 1800 | msg.msg_controllen = 0; |
1805 | msg.msg_namelen = 0; | 1801 | msg.msg_namelen = 0; |
@@ -1856,10 +1852,9 @@ SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, ubuf, size_t, size, | |||
1856 | 1852 | ||
1857 | msg.msg_control = NULL; | 1853 | msg.msg_control = NULL; |
1858 | msg.msg_controllen = 0; | 1854 | msg.msg_controllen = 0; |
1859 | msg.msg_iovlen = 1; | ||
1860 | msg.msg_iov = &iov; | ||
1861 | iov.iov_len = size; | 1855 | iov.iov_len = size; |
1862 | iov.iov_base = ubuf; | 1856 | iov.iov_base = ubuf; |
1857 | iov_iter_init(&msg.msg_iter, READ, &iov, 1, size); | ||
1863 | /* Save some cycles and don't copy the address if not needed */ | 1858 | /* Save some cycles and don't copy the address if not needed */ |
1864 | msg.msg_name = addr ? (struct sockaddr *)&address : NULL; | 1859 | msg.msg_name = addr ? (struct sockaddr *)&address : NULL; |
1865 | /* We assume all kernel code knows the size of sockaddr_storage */ | 1860 | /* 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, | |||
1993 | { | 1988 | { |
1994 | struct sockaddr __user *uaddr; | 1989 | struct sockaddr __user *uaddr; |
1995 | struct iovec __user *uiov; | 1990 | struct iovec __user *uiov; |
1991 | size_t nr_segs; | ||
1996 | ssize_t err; | 1992 | ssize_t err; |
1997 | 1993 | ||
1998 | if (!access_ok(VERIFY_READ, umsg, sizeof(*umsg)) || | 1994 | if (!access_ok(VERIFY_READ, umsg, sizeof(*umsg)) || |
1999 | __get_user(uaddr, &umsg->msg_name) || | 1995 | __get_user(uaddr, &umsg->msg_name) || |
2000 | __get_user(kmsg->msg_namelen, &umsg->msg_namelen) || | 1996 | __get_user(kmsg->msg_namelen, &umsg->msg_namelen) || |
2001 | __get_user(uiov, &umsg->msg_iov) || | 1997 | __get_user(uiov, &umsg->msg_iov) || |
2002 | __get_user(kmsg->msg_iovlen, &umsg->msg_iovlen) || | 1998 | __get_user(nr_segs, &umsg->msg_iovlen) || |
2003 | __get_user(kmsg->msg_control, &umsg->msg_control) || | 1999 | __get_user(kmsg->msg_control, &umsg->msg_control) || |
2004 | __get_user(kmsg->msg_controllen, &umsg->msg_controllen) || | 2000 | __get_user(kmsg->msg_controllen, &umsg->msg_controllen) || |
2005 | __get_user(kmsg->msg_flags, &umsg->msg_flags)) | 2001 | __get_user(kmsg->msg_flags, &umsg->msg_flags)) |
@@ -2029,14 +2025,15 @@ static ssize_t copy_msghdr_from_user(struct msghdr *kmsg, | |||
2029 | kmsg->msg_namelen = 0; | 2025 | kmsg->msg_namelen = 0; |
2030 | } | 2026 | } |
2031 | 2027 | ||
2032 | if (kmsg->msg_iovlen > UIO_MAXIOV) | 2028 | if (nr_segs > UIO_MAXIOV) |
2033 | return -EMSGSIZE; | 2029 | return -EMSGSIZE; |
2034 | 2030 | ||
2035 | err = rw_copy_check_uvector(save_addr ? READ : WRITE, | 2031 | err = rw_copy_check_uvector(save_addr ? READ : WRITE, |
2036 | uiov, kmsg->msg_iovlen, | 2032 | uiov, nr_segs, |
2037 | UIO_FASTIOV, *iov, iov); | 2033 | UIO_FASTIOV, *iov, iov); |
2038 | if (err >= 0) | 2034 | if (err >= 0) |
2039 | kmsg->msg_iov = *iov; | 2035 | iov_iter_init(&kmsg->msg_iter, save_addr ? READ : WRITE, |
2036 | *iov, nr_segs, err); | ||
2040 | return err; | 2037 | return err; |
2041 | } | 2038 | } |
2042 | 2039 | ||
diff --git a/net/tipc/msg.c b/net/tipc/msg.c index 5b0659791c07..a687b30a699c 100644 --- a/net/tipc/msg.c +++ b/net/tipc/msg.c | |||
@@ -194,7 +194,7 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m, int offset, | |||
194 | __skb_queue_tail(list, skb); | 194 | __skb_queue_tail(list, skb); |
195 | skb_copy_to_linear_data(skb, mhdr, mhsz); | 195 | skb_copy_to_linear_data(skb, mhdr, mhsz); |
196 | pktpos = skb->data + mhsz; | 196 | pktpos = skb->data + mhsz; |
197 | if (!dsz || !memcpy_fromiovecend(pktpos, m->msg_iov, offset, | 197 | if (!dsz || !memcpy_fromiovecend(pktpos, m->msg_iter.iov, offset, |
198 | dsz)) | 198 | dsz)) |
199 | return dsz; | 199 | return dsz; |
200 | rc = -EFAULT; | 200 | rc = -EFAULT; |
@@ -224,7 +224,7 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m, int offset, | |||
224 | if (drem < pktrem) | 224 | if (drem < pktrem) |
225 | pktrem = drem; | 225 | pktrem = drem; |
226 | 226 | ||
227 | if (memcpy_fromiovecend(pktpos, m->msg_iov, offset, pktrem)) { | 227 | if (memcpy_fromiovecend(pktpos, m->msg_iter.iov, offset, pktrem)) { |
228 | rc = -EFAULT; | 228 | rc = -EFAULT; |
229 | goto error; | 229 | goto error; |
230 | } | 230 | } |
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 4450d6226602..8e1b10274b02 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
@@ -1459,9 +1459,6 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1459 | struct scm_cookie tmp_scm; | 1459 | struct scm_cookie tmp_scm; |
1460 | int max_level; | 1460 | int max_level; |
1461 | int data_len = 0; | 1461 | int data_len = 0; |
1462 | struct iov_iter from; | ||
1463 | |||
1464 | iov_iter_init(&from, WRITE, msg->msg_iov, msg->msg_iovlen, len); | ||
1465 | 1462 | ||
1466 | if (NULL == siocb->scm) | 1463 | if (NULL == siocb->scm) |
1467 | siocb->scm = &tmp_scm; | 1464 | siocb->scm = &tmp_scm; |
@@ -1519,7 +1516,7 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1519 | skb_put(skb, len - data_len); | 1516 | skb_put(skb, len - data_len); |
1520 | skb->data_len = data_len; | 1517 | skb->data_len = data_len; |
1521 | skb->len = len; | 1518 | skb->len = len; |
1522 | err = skb_copy_datagram_from_iter(skb, 0, &from, len); | 1519 | err = skb_copy_datagram_from_iter(skb, 0, &msg->msg_iter, len); |
1523 | if (err) | 1520 | if (err) |
1524 | goto out_free; | 1521 | goto out_free; |
1525 | 1522 | ||
@@ -1641,9 +1638,6 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1641 | bool fds_sent = false; | 1638 | bool fds_sent = false; |
1642 | int max_level; | 1639 | int max_level; |
1643 | int data_len; | 1640 | int data_len; |
1644 | struct iov_iter from; | ||
1645 | |||
1646 | iov_iter_init(&from, WRITE, msg->msg_iov, msg->msg_iovlen, len); | ||
1647 | 1641 | ||
1648 | if (NULL == siocb->scm) | 1642 | if (NULL == siocb->scm) |
1649 | siocb->scm = &tmp_scm; | 1643 | siocb->scm = &tmp_scm; |
@@ -1700,7 +1694,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1700 | skb_put(skb, size - data_len); | 1694 | skb_put(skb, size - data_len); |
1701 | skb->data_len = data_len; | 1695 | skb->data_len = data_len; |
1702 | skb->len = size; | 1696 | skb->len = size; |
1703 | err = skb_copy_datagram_from_iter(skb, 0, &from, size); | 1697 | err = skb_copy_datagram_from_iter(skb, 0, &msg->msg_iter, size); |
1704 | if (err) { | 1698 | if (err) { |
1705 | kfree_skb(skb); | 1699 | kfree_skb(skb); |
1706 | goto out_err; | 1700 | goto out_err; |
diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c index c1c038952973..02d2e5229240 100644 --- a/net/vmw_vsock/vmci_transport.c +++ b/net/vmw_vsock/vmci_transport.c | |||
@@ -1840,9 +1840,9 @@ static ssize_t vmci_transport_stream_dequeue( | |||
1840 | int flags) | 1840 | int flags) |
1841 | { | 1841 | { |
1842 | if (flags & MSG_PEEK) | 1842 | if (flags & MSG_PEEK) |
1843 | return vmci_qpair_peekv(vmci_trans(vsk)->qpair, msg->msg_iov, len, 0); | 1843 | return vmci_qpair_peekv(vmci_trans(vsk)->qpair, msg, len, 0); |
1844 | else | 1844 | else |
1845 | return vmci_qpair_dequev(vmci_trans(vsk)->qpair, msg->msg_iov, len, 0); | 1845 | return vmci_qpair_dequev(vmci_trans(vsk)->qpair, msg, len, 0); |
1846 | } | 1846 | } |
1847 | 1847 | ||
1848 | static ssize_t vmci_transport_stream_enqueue( | 1848 | static ssize_t vmci_transport_stream_enqueue( |
@@ -1850,7 +1850,8 @@ static ssize_t vmci_transport_stream_enqueue( | |||
1850 | struct msghdr *msg, | 1850 | struct msghdr *msg, |
1851 | size_t len) | 1851 | size_t len) |
1852 | { | 1852 | { |
1853 | return vmci_qpair_enquev(vmci_trans(vsk)->qpair, msg->msg_iov, len, 0); | 1853 | /* XXX: stripping const */ |
1854 | return vmci_qpair_enquev(vmci_trans(vsk)->qpair, (struct iovec *)msg->msg_iter.iov, len, 0); | ||
1854 | } | 1855 | } |
1855 | 1856 | ||
1856 | static s64 vmci_transport_stream_has_data(struct vsock_sock *vsk) | 1857 | static s64 vmci_transport_stream_has_data(struct vsock_sock *vsk) |