All of lore.kernel.org
 help / color / mirror / Atom feed
From: Daniel Borkmann <daniel@iogearbox.net>
To: Dongseok Yi <dseok.yi@samsung.com>,
	"David S. Miller" <davem@davemloft.net>,
	Willem de Bruijn <willemb@google.com>
Cc: Jakub Kicinski <kuba@kernel.org>,
	Miaohe Lin <linmiaohe@huawei.com>,
	Paolo Abeni <pabeni@redhat.com>, Florian Westphal <fw@strlen.de>,
	Al Viro <viro@zeniv.linux.org.uk>,
	Guillaume Nault <gnault@redhat.com>,
	Yunsheng Lin <linyunsheng@huawei.com>,
	Steffen Klassert <steffen.klassert@secunet.com>,
	Yadu Kishore <kyk.segfault@gmail.com>,
	Marco Elver <elver@google.com>,
	netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
	namkyu78.kim@samsung.com
Subject: Re: [PATCH net v2] net: fix use-after-free when UDP GRO with shared fraglist
Date: Thu, 7 Jan 2021 12:05:36 +0100	[thread overview]
Message-ID: <83a2b288-c0b2-ed98-9479-61e1cbe25519@iogearbox.net> (raw)
In-Reply-To: <1609979953-181868-1-git-send-email-dseok.yi@samsung.com>

On 1/7/21 1:39 AM, Dongseok Yi wrote:
> skbs in fraglist could be shared by a BPF filter loaded at TC. It
> triggers skb_ensure_writable -> pskb_expand_head ->
> skb_clone_fraglist -> skb_get on each skb in the fraglist.
> 
> While tcpdump, sk_receive_queue of PF_PACKET has the original fraglist.
> But the same fraglist is queued to PF_INET (or PF_INET6) as the fraglist
> chain made by skb_segment_list.
> 
> If the new skb (not fraglist) is queued to one of the sk_receive_queue,
> multiple ptypes can see this. The skb could be released by ptypes and
> it causes use-after-free.
> 
> [ 4443.426215] ------------[ cut here ]------------
> [ 4443.426222] refcount_t: underflow; use-after-free.
> [ 4443.426291] WARNING: CPU: 7 PID: 28161 at lib/refcount.c:190
> refcount_dec_and_test_checked+0xa4/0xc8
> [ 4443.426726] pstate: 60400005 (nZCv daif +PAN -UAO)
> [ 4443.426732] pc : refcount_dec_and_test_checked+0xa4/0xc8
> [ 4443.426737] lr : refcount_dec_and_test_checked+0xa0/0xc8
> [ 4443.426808] Call trace:
> [ 4443.426813]  refcount_dec_and_test_checked+0xa4/0xc8
> [ 4443.426823]  skb_release_data+0x144/0x264
> [ 4443.426828]  kfree_skb+0x58/0xc4
> [ 4443.426832]  skb_queue_purge+0x64/0x9c
> [ 4443.426844]  packet_set_ring+0x5f0/0x820
> [ 4443.426849]  packet_setsockopt+0x5a4/0xcd0
> [ 4443.426853]  __sys_setsockopt+0x188/0x278
> [ 4443.426858]  __arm64_sys_setsockopt+0x28/0x38
> [ 4443.426869]  el0_svc_common+0xf0/0x1d0
> [ 4443.426873]  el0_svc_handler+0x74/0x98
> [ 4443.426880]  el0_svc+0x8/0xc
> 
> Fixes: 3a1296a38d0c (net: Support GRO/GSO fraglist chaining.)
> Signed-off-by: Dongseok Yi <dseok.yi@samsung.com>
> Acked-by: Willem de Bruijn <willemb@google.com>
> ---
>   net/core/skbuff.c | 20 +++++++++++++++++++-
>   1 file changed, 19 insertions(+), 1 deletion(-)
> 
> v2: Expand the commit message to clarify a BPF filter loaded
> 
> diff --git a/net/core/skbuff.c b/net/core/skbuff.c
> index f62cae3..1dcbda8 100644
> --- a/net/core/skbuff.c
> +++ b/net/core/skbuff.c
> @@ -3655,7 +3655,8 @@ struct sk_buff *skb_segment_list(struct sk_buff *skb,
>   	unsigned int delta_truesize = 0;
>   	unsigned int delta_len = 0;
>   	struct sk_buff *tail = NULL;
> -	struct sk_buff *nskb;
> +	struct sk_buff *nskb, *tmp;
> +	int err;
>   
>   	skb_push(skb, -skb_network_offset(skb) + offset);
>   
> @@ -3665,11 +3666,28 @@ struct sk_buff *skb_segment_list(struct sk_buff *skb,
>   		nskb = list_skb;
>   		list_skb = list_skb->next;
>   
> +		err = 0;
> +		if (skb_shared(nskb)) {
> +			tmp = skb_clone(nskb, GFP_ATOMIC);
> +			if (tmp) {
> +				kfree_skb(nskb);

Should use consume_skb() to not trigger skb:kfree_skb tracepoint when looking
for drops in the stack.

> +				nskb = tmp;
> +				err = skb_unclone(nskb, GFP_ATOMIC);

Could you elaborate why you also need to unclone? This looks odd here. tc layer
(independent of BPF) from ingress & egress side generally assumes unshared skb,
so above clone + dropping ref of nskb looks okay to make the main skb struct private
for mangling attributes (e.g. mark) & should suffice. What is the exact purpose of
the additional skb_unclone() in this context?

> +			} else {
> +				err = -ENOMEM;
> +			}
> +		}
> +
>   		if (!tail)
>   			skb->next = nskb;
>   		else
>   			tail->next = nskb;
>   
> +		if (unlikely(err)) {
> +			nskb->next = list_skb;
> +			goto err_linearize;
> +		}
> +
>   		tail = nskb;
>   
>   		delta_len += nskb->len;
> 


  reply	other threads:[~2021-01-07 11:07 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <CGME20210104085750epcas2p1a5b22559d87df61ef3c8215ae0b470b5@epcas2p1.samsung.com>
2021-01-04  8:46 ` [PATCH net] net: fix use-after-free when UDP GRO with shared fraglist Dongseok Yi
2021-01-04 21:03   ` Willem de Bruijn
2021-01-06  1:29     ` Dongseok Yi
2021-01-06  3:07       ` Willem de Bruijn
2021-01-06  3:32         ` Dongseok Yi
2021-01-06 17:13           ` Willem de Bruijn
2021-04-17  3:44           ` Yunsheng Lin
2021-04-19  0:35             ` Dongseok Yi
2021-04-21  9:42               ` Yunsheng Lin
2021-04-21 11:04                 ` Dongseok Yi
     [not found]   ` <CGME20210107005028epcas2p35dfa745fd92e31400024874f54243556@epcas2p3.samsung.com>
2021-01-07  0:39     ` [PATCH net v2] " Dongseok Yi
2021-01-07 11:05       ` Daniel Borkmann [this message]
2021-01-07 11:40         ` Dongseok Yi
2021-01-07 12:49           ` Daniel Borkmann
2021-01-07 13:05             ` Willem de Bruijn
2021-01-07 13:33               ` Daniel Borkmann
2021-01-07 14:44                 ` Willem de Bruijn
2021-01-08 10:32                   ` Daniel Borkmann
     [not found]       ` <CGME20210108024017epcas2p455fe96b8483880f9b7a654dbcf600b20@epcas2p4.samsung.com>
2021-01-08  2:28         ` [PATCH net v3] " Dongseok Yi
2021-01-08 10:18           ` Daniel Borkmann
2021-01-09  3:14             ` Jakub Kicinski

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=83a2b288-c0b2-ed98-9479-61e1cbe25519@iogearbox.net \
    --to=daniel@iogearbox.net \
    --cc=davem@davemloft.net \
    --cc=dseok.yi@samsung.com \
    --cc=elver@google.com \
    --cc=fw@strlen.de \
    --cc=gnault@redhat.com \
    --cc=kuba@kernel.org \
    --cc=kyk.segfault@gmail.com \
    --cc=linmiaohe@huawei.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linyunsheng@huawei.com \
    --cc=namkyu78.kim@samsung.com \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=steffen.klassert@secunet.com \
    --cc=viro@zeniv.linux.org.uk \
    --cc=willemb@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.