Skip to contentSkip to conversation

Patch "skbuff: in skb_copy_ubufs unclone before releasing zerocopy" has been added to the 4.14-stable tree

PATCH [email protected] 1 participant 1 message Dec 31, 2017

Subsystems (2)
lore
Share & tools
lore

[email protected]

author maintainer Applied
#0 lore raw

This is a note to let you know that I've just added the patch titled

skbuff: in skb_copy_ubufs unclone before releasing zerocopy

to the 4.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
skbuff-in-skb_copy_ubufs-unclone-before-releasing-zerocopy.patch
and it can be found in the queue-4.14 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.

Quoted 1 line

From foo@baz Sun Dec 31 11:12:48 CET 2017

From: Willem de Bruijn <[email protected]>
Date: Thu, 28 Dec 2017 12:38:13 -0500
Subject: skbuff: in skb_copy_ubufs unclone before releasing zerocopy

From: Willem de Bruijn <[email protected]>

skb_copy_ubufs must unclone before it is safe to modify its skb_shared_info with skb_zcopy_clear.

Commit b90ddd568792 ("skbuff: skb_copy_ubufs must release uarg even without user frags") ensures that all skbs release their zerocopy state, even those without frags.

But I forgot an edge case where such an skb arrives that is cloned.

The stack does not build such packets. Vhost/tun skbs have their frags orphaned before cloning. TCP skbs only attach zerocopy state when a frag is added.

But if TCP packets can be trimmed or linearized, this might occur. Tracing the code I found no instance so far (e.g., skb_linearize ends up calling skb_zcopy_clear if !skb->data_len).

Still, it is non-obvious that no path exists. And it is fragile to rely on this.

Fixes b90ddd568792 ("skbuff: skb_copy_ubufs must release uarg even without user frags")
---
 net/core/skbuff.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
net/core/skbuff.c +3 -3
@@ -1181,12 +1181,12 @@ int skb_copy_ubufs(struct sk_buff *skb,
 	int i, new_frags;
 	u32 d_off;
 
-	if (!num_frags)
-		goto release;
-
 	if (skb_shared(skb) || skb_unclone(skb, gfp_mask))
 		return -EINVAL;
 
+	if (!num_frags)
+		goto release;
+
 	new_frags = (__skb_pagelen(skb) + PAGE_SIZE - 1) >> PAGE_SHIFT;
 	for (i = 0; i < new_frags; i++) {
 		page = alloc_page(gfp_mask);

Patches currently in stable-queue which might be from [email protected] are

queue-4.14/skbuff-skb_copy_ubufs-must-release-uarg-even-without-user-frags.patch queue-4.14/sock-free-skb-in-skb_complete_tx_timestamp-on-error.patch queue-4.14/skbuff-orphan-frags-before-zerocopy-clone.patch queue-4.14/skbuff-in-skb_copy_ubufs-unclone-before-releasing-zerocopy.patch