lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Wed,  5 May 2021 17:35:01 +0200
From:   Paolo Abeni <pabeni@...hat.com>
To:     netdev@...r.kernel.org
Cc:     "David S. Miller" <davem@...emloft.net>,
        Jakub Kicinski <kuba@...nel.org>,
        Steffen Klassert <steffen.klassert@...unet.com>,
        Willem de Bruijn <willemb@...gle.com>,
        Miaohe Lin <linmiaohe@...wei.com>
Subject: [PATCH net 1/4] net: fix double-free on fraglist GSO skbs

While segmenting a SKB_GSO_FRAGLIST GSO packet, if the destructor
callback is available, the skb destructor is invoked on each
aggregated packet via skb_release_head_state().

Such field (and the pairer skb->sk) is left untouched, so the same
destructor is invoked again when the segmented skbs are freed, leading
to double-free/UaF of the relevant socket.

The problem is observable since commit c75fb320d482 ("veth: use
skb_orphan_partial instead of skb_orphan"), which allowed non orphaned
skbs to enter the GRO engine, but the root cause is there since the
introduction of GSO fraglist

This change addresses the above issue explixitly clearing the segmented
skb destructor after the skb_release_head_state() call.

Fixes: c75fb320d482 ("veth: use skb_orphan_partial instead of skb_orphan")
Fixes: 3a1296a38d0c ("net: Support GRO/GSO fraglist chaining.")
Signed-off-by: Paolo Abeni <pabeni@...hat.com>
---
 net/core/skbuff.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 3ad22870298c..75f3e70f8cd5 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -3818,6 +3818,12 @@ struct sk_buff *skb_segment_list(struct sk_buff *skb,
 		skb_release_head_state(nskb);
 		 __copy_skb_header(nskb, skb);
 
+		/* __copy_skb_header() does not initialize the sk-related fields,
+		 * and skb_release_head_state() already orphaned nskb
+		 */
+		nskb->sk = NULL;
+		nskb->destructor = NULL;
+
 		skb_headers_offset_update(nskb, skb_headroom(nskb) - skb_headroom(skb));
 		skb_copy_from_linear_data_offset(skb, -tnl_hlen,
 						 nskb->data - tnl_hlen,
-- 
2.26.2

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ