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 | } |
