Commit b90ddd56 authored by Willem de Bruijn's avatar Willem de Bruijn Committed by David S. Miller

skbuff: skb_copy_ubufs must release uarg even without user frags

skb_copy_ubufs creates a private copy of frags[] to release its hold
on user frags, then calls uarg->callback to notify the owner.

Call uarg->callback even when no frags exist. This edge case can
happen when zerocopy_sg_from_iter finds enough room in skb_headlen
to copy all the data.

Fixes: 3ece7826 ("sock: skb_copy_ubufs support for compound pages")
Signed-off-by: default avatarWillem de Bruijn <willemb@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 268b7906
...@@ -1178,7 +1178,7 @@ int skb_copy_ubufs(struct sk_buff *skb, gfp_t gfp_mask) ...@@ -1178,7 +1178,7 @@ int skb_copy_ubufs(struct sk_buff *skb, gfp_t gfp_mask)
u32 d_off; u32 d_off;
if (!num_frags) if (!num_frags)
return 0; goto release;
if (skb_shared(skb) || skb_unclone(skb, gfp_mask)) if (skb_shared(skb) || skb_unclone(skb, gfp_mask))
return -EINVAL; return -EINVAL;
...@@ -1238,6 +1238,7 @@ int skb_copy_ubufs(struct sk_buff *skb, gfp_t gfp_mask) ...@@ -1238,6 +1238,7 @@ int skb_copy_ubufs(struct sk_buff *skb, gfp_t gfp_mask)
__skb_fill_page_desc(skb, new_frags - 1, head, 0, d_off); __skb_fill_page_desc(skb, new_frags - 1, head, 0, d_off);
skb_shinfo(skb)->nr_frags = new_frags; skb_shinfo(skb)->nr_frags = new_frags;
release:
skb_zcopy_clear(skb, false); skb_zcopy_clear(skb, false);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment