diff options
author | Ding Tianhong <dingtianhong@huawei.com> | 2017-04-28 22:38:48 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-05-20 08:28:38 -0400 |
commit | 377178321690105cd4d42b33486881843ea6f8e8 (patch) | |
tree | f0089d172dd41207859eb11e3e9b83645bfdea75 /net | |
parent | 9f43f70dcc56ac294aeb8c0b29766a7a1cb1aec0 (diff) |
iov_iter: don't revert iov buffer if csum error
commit a6a5993243550b09f620941dea741b7421fdf79c upstream.
The patch 327868212381 (make skb_copy_datagram_msg() et.al. preserve
->msg_iter on error) will revert the iov buffer if copy to iter
failed, but it didn't copy any datagram if the skb_checksum_complete
error, so no need to revert any data at this place.
v2: Sabrina notice that return -EFAULT when checksum error is not correct
here, it would confuse the caller about the return value, so fix it.
Fixes: 327868212381 ("make skb_copy_datagram_msg() et.al. preserve->msg_iter on error")
Signed-off-by: Ding Tianhong <dingtianhong@huawei.com>
Acked-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'net')
-rw-r--r-- | net/core/datagram.c | 13 |
1 files changed, 7 insertions, 6 deletions
diff --git a/net/core/datagram.c b/net/core/datagram.c index 963732e775df..58dfa23d12ca 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c | |||
@@ -740,7 +740,7 @@ int skb_copy_and_csum_datagram_msg(struct sk_buff *skb, | |||
740 | 740 | ||
741 | if (msg_data_left(msg) < chunk) { | 741 | if (msg_data_left(msg) < chunk) { |
742 | if (__skb_checksum_complete(skb)) | 742 | if (__skb_checksum_complete(skb)) |
743 | goto csum_error; | 743 | return -EINVAL; |
744 | if (skb_copy_datagram_msg(skb, hlen, msg, chunk)) | 744 | if (skb_copy_datagram_msg(skb, hlen, msg, chunk)) |
745 | goto fault; | 745 | goto fault; |
746 | } else { | 746 | } else { |
@@ -748,15 +748,16 @@ int skb_copy_and_csum_datagram_msg(struct sk_buff *skb, | |||
748 | if (skb_copy_and_csum_datagram(skb, hlen, &msg->msg_iter, | 748 | if (skb_copy_and_csum_datagram(skb, hlen, &msg->msg_iter, |
749 | chunk, &csum)) | 749 | chunk, &csum)) |
750 | goto fault; | 750 | goto fault; |
751 | if (csum_fold(csum)) | 751 | |
752 | goto csum_error; | 752 | if (csum_fold(csum)) { |
753 | iov_iter_revert(&msg->msg_iter, chunk); | ||
754 | return -EINVAL; | ||
755 | } | ||
756 | |||
753 | if (unlikely(skb->ip_summed == CHECKSUM_COMPLETE)) | 757 | if (unlikely(skb->ip_summed == CHECKSUM_COMPLETE)) |
754 | netdev_rx_csum_fault(skb->dev); | 758 | netdev_rx_csum_fault(skb->dev); |
755 | } | 759 | } |
756 | return 0; | 760 | return 0; |
757 | csum_error: | ||
758 | iov_iter_revert(&msg->msg_iter, chunk); | ||
759 | return -EINVAL; | ||
760 | fault: | 761 | fault: |
761 | return -EFAULT; | 762 | return -EFAULT; |
762 | } | 763 | } |