diff options
author | Ding Tianhong <dingtianhong@huawei.com> | 2017-04-28 22:38:48 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2017-05-01 14:49:53 -0400 |
commit | a6a5993243550b09f620941dea741b7421fdf79c (patch) | |
tree | 6fe5747d0ba55ff5d431d850e172ef1bc43b3336 /net | |
parent | 5ecda13711b3bd4a750b5740897bf13d1720de7c (diff) |
iov_iter: don't revert iov buffer if csum error
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")
Cc: stable@vger.kernel.org # v4.11
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>
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 f4947e737f34..d797baa69e43 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c | |||
@@ -760,7 +760,7 @@ int skb_copy_and_csum_datagram_msg(struct sk_buff *skb, | |||
760 | 760 | ||
761 | if (msg_data_left(msg) < chunk) { | 761 | if (msg_data_left(msg) < chunk) { |
762 | if (__skb_checksum_complete(skb)) | 762 | if (__skb_checksum_complete(skb)) |
763 | goto csum_error; | 763 | return -EINVAL; |
764 | if (skb_copy_datagram_msg(skb, hlen, msg, chunk)) | 764 | if (skb_copy_datagram_msg(skb, hlen, msg, chunk)) |
765 | goto fault; | 765 | goto fault; |
766 | } else { | 766 | } else { |
@@ -768,15 +768,16 @@ int skb_copy_and_csum_datagram_msg(struct sk_buff *skb, | |||
768 | if (skb_copy_and_csum_datagram(skb, hlen, &msg->msg_iter, | 768 | if (skb_copy_and_csum_datagram(skb, hlen, &msg->msg_iter, |
769 | chunk, &csum)) | 769 | chunk, &csum)) |
770 | goto fault; | 770 | goto fault; |
771 | if (csum_fold(csum)) | 771 | |
772 | goto csum_error; | 772 | if (csum_fold(csum)) { |
773 | iov_iter_revert(&msg->msg_iter, chunk); | ||
774 | return -EINVAL; | ||
775 | } | ||
776 | |||
773 | if (unlikely(skb->ip_summed == CHECKSUM_COMPLETE)) | 777 | if (unlikely(skb->ip_summed == CHECKSUM_COMPLETE)) |
774 | netdev_rx_csum_fault(skb->dev); | 778 | netdev_rx_csum_fault(skb->dev); |
775 | } | 779 | } |
776 | return 0; | 780 | return 0; |
777 | csum_error: | ||
778 | iov_iter_revert(&msg->msg_iter, chunk); | ||
779 | return -EINVAL; | ||
780 | fault: | 781 | fault: |
781 | return -EFAULT; | 782 | return -EFAULT; |
782 | } | 783 | } |