diff --git a/net/core/datagram.c b/net/core/datagram.c index c285c6465923..db253fd890d7 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c @@ -636,6 +636,8 @@ int zerocopy_fill_skb_from_iter(struct sk_buff *skb, struct iov_iter *from, size_t length) { int frag = skb_shinfo(skb)->nr_frags; + int err; + size_t len = length; if (!skb_frags_readable(skb)) return -EFAULT; @@ -647,13 +649,17 @@ int zerocopy_fill_skb_from_iter(struct sk_buff *skb, size_t start; ssize_t copied; - if (frag == MAX_SKB_FRAGS) - return -EMSGSIZE; + if (frag == MAX_SKB_FRAGS) { + err = -EMSGSIZE; + goto fault; + } copied = iov_iter_get_pages2(from, pages, length, MAX_SKB_FRAGS - frag, &start); - if (copied < 0) - return -EFAULT; + if (copied < 0) { + err = -EFAULT; + goto fault; + } length -= copied; @@ -701,6 +707,9 @@ int zerocopy_fill_skb_from_iter(struct sk_buff *skb, page_ref_sub(last_head, refs); } return 0; +fault: + iov_iter_revert(from, len - length); + return err; } static int