diff mbox series

[net] net: correct udp zerocopy refcnt also when zerocopy only on append

Message ID 20190607215748.146484-1-willemdebruijn.kernel@gmail.com
State Accepted
Delegated to: David Miller
Headers show
Series [net] net: correct udp zerocopy refcnt also when zerocopy only on append | expand

Commit Message

Willem de Bruijn June 7, 2019, 9:57 p.m. UTC
From: Willem de Bruijn <willemb@google.com>

The below patch fixes an incorrect zerocopy refcnt increment when
appending with MSG_MORE to an existing zerocopy udp skb.

  send(.., MSG_ZEROCOPY | MSG_MORE);	// refcnt 1
  send(.., MSG_ZEROCOPY | MSG_MORE);	// refcnt still 1 (bar frags)

But it missed that zerocopy need not be passed at the first send. The
right test whether the uarg is newly allocated and thus has extra
refcnt 1 is not !skb, but !skb_zcopy.

  send(.., MSG_MORE);			// <no uarg>
  send(.., MSG_ZEROCOPY);		// refcnt 1

Fixes: 100f6d8e09905 ("net: correct zerocopy refcnt with udp MSG_MORE")
Reported-by: syzbot <syzkaller@googlegroups.com>
Signed-off-by: Willem de Bruijn <willemb@google.com>
---
 net/ipv4/ip_output.c  | 2 +-
 net/ipv6/ip6_output.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

Comments

David Miller June 11, 2019, 6:44 p.m. UTC | #1
From: Willem de Bruijn <willemdebruijn.kernel@gmail.com>
Date: Fri,  7 Jun 2019 17:57:48 -0400

> From: Willem de Bruijn <willemb@google.com>
> 
> The below patch fixes an incorrect zerocopy refcnt increment when
> appending with MSG_MORE to an existing zerocopy udp skb.
> 
>   send(.., MSG_ZEROCOPY | MSG_MORE);	// refcnt 1
>   send(.., MSG_ZEROCOPY | MSG_MORE);	// refcnt still 1 (bar frags)
> 
> But it missed that zerocopy need not be passed at the first send. The
> right test whether the uarg is newly allocated and thus has extra
> refcnt 1 is not !skb, but !skb_zcopy.
> 
>   send(.., MSG_MORE);			// <no uarg>
>   send(.., MSG_ZEROCOPY);		// refcnt 1
> 
> Fixes: 100f6d8e09905 ("net: correct zerocopy refcnt with udp MSG_MORE")
> Reported-by: syzbot <syzkaller@googlegroups.com>
> Signed-off-by: Willem de Bruijn <willemb@google.com>

Applied, thanks Willem.
diff mbox series

Patch

diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 8c9189a41b136..16f9159234a20 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -918,7 +918,7 @@  static int __ip_append_data(struct sock *sk,
 		uarg = sock_zerocopy_realloc(sk, length, skb_zcopy(skb));
 		if (!uarg)
 			return -ENOBUFS;
-		extra_uref = !skb;	/* only extra ref if !MSG_MORE */
+		extra_uref = !skb_zcopy(skb);	/* only ref on new uarg */
 		if (rt->dst.dev->features & NETIF_F_SG &&
 		    csummode == CHECKSUM_PARTIAL) {
 			paged = true;
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 934c88f128abb..834475717110e 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1340,7 +1340,7 @@  static int __ip6_append_data(struct sock *sk,
 		uarg = sock_zerocopy_realloc(sk, length, skb_zcopy(skb));
 		if (!uarg)
 			return -ENOBUFS;
-		extra_uref = !skb;	/* only extra ref if !MSG_MORE */
+		extra_uref = !skb_zcopy(skb);	/* only ref on new uarg */
 		if (rt->dst.dev->features & NETIF_F_SG &&
 		    csummode == CHECKSUM_PARTIAL) {
 			paged = true;