netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Kuniyuki Iwashima <kuniyu@amazon.com>
To: <dmantipov@yandex.ru>
Cc: <dccp@vger.kernel.org>, <kuniyu@amazon.com>,
	<netdev@vger.kernel.org>,
	<syzbot+554ccde221001ab5479a@syzkaller.appspotmail.com>
Subject: Re: KASAN: use-after-free Read in ccid2_hc_tx_packet_recv
Date: Wed, 23 Oct 2024 10:51:21 -0700	[thread overview]
Message-ID: <20241023175121.36351-1-kuniyu@amazon.com> (raw)
In-Reply-To: <938106e0-269a-4d5a-995f-2314fecedb3a@yandex.ru>

From: Dmitry Antipov <dmantipov@yandex.ru>
Date: Wed, 23 Oct 2024 15:09:59 +0300
> Looking through https://syzkaller.appspot.com/bug?extid=554ccde221001ab5479a,
> I've found the problem which may be illustrated with the following patch:
> 
> diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
> index 5926159a6f20..eb551872170c 100644
> --- a/net/dccp/ipv4.c
> +++ b/net/dccp/ipv4.c
> @@ -678,6 +678,7 @@ int dccp_v4_do_rcv(struct sock *sk, struct sk_buff *skb)
> 
>          if (sk->sk_state == DCCP_OPEN) { /* Fast path */
>                  if (dccp_rcv_established(sk, skb, dh, skb->len))
> +                       /* Go to reset here */
>                          goto reset;
>                  return 0;
>          }
> @@ -712,6 +713,7 @@ int dccp_v4_do_rcv(struct sock *sk, struct sk_buff *skb)
> 
>   reset:
>          dccp_v4_ctl_send_reset(sk, skb, SK_RST_REASON_NOT_SPECIFIED);
> +       /* Freeing skb may leave dangling pointers in ack vectors */
>          kfree_skb(skb);
>          return 0;
>   }
> 
> I'm not an expert with DCCP protocol innards and have no idea whether ack
> vectors still needs to be processed after sending reset. But if it is so,
> the solution might be to copy all of the data from the relevant skbs instead
> of just saving the pointers, e.g.:
> 
> diff --git a/net/dccp/ackvec.c b/net/dccp/ackvec.c
> index 1cba001bb4c8..24c6ad06d896 100644
> --- a/net/dccp/ackvec.c
> +++ b/net/dccp/ackvec.c
> @@ -347,17 +347,18 @@ void dccp_ackvec_clear_state(struct dccp_ackvec *av, const u64 ackno)
>   }
> 
>   /*
> - *	Routines to keep track of Ack Vectors received in an skb
> + *	Routines to keep track of Ack Vectors copied from the received skb
>    */
>   int dccp_ackvec_parsed_add(struct list_head *head, u8 *vec, u8 len, u8 nonce)
>   {
> -	struct dccp_ackvec_parsed *new = kmalloc(sizeof(*new), GFP_ATOMIC);
> -
> +	struct dccp_ackvec_parsed *new = kmalloc(struct_size(new, vec, len),
> +						 GFP_ATOMIC);
>   	if (new == NULL)
>   		return -ENOBUFS;
> -	new->vec   = vec;
> -	new->len   = len;
> +
> +	new->len = len;
>   	new->nonce = nonce;
> +	memcpy(new->vec, vec, len);
> 
>   	list_add_tail(&new->node, head);
>   	return 0;
> diff --git a/net/dccp/ackvec.h b/net/dccp/ackvec.h
> index d2c4220fb377..491fd587de90 100644
> --- a/net/dccp/ackvec.h
> +++ b/net/dccp/ackvec.h
> @@ -117,18 +117,18 @@ static inline bool dccp_ackvec_is_empty(const struct dccp_ackvec *av)
> 
>   /**
>    * struct dccp_ackvec_parsed  -  Record offsets of Ack Vectors in skb
> - * @vec:	start of vector (offset into skb)
> + * @vec:	contents of ack vector (copied from skb)
>    * @len:	length of @vec
>    * @nonce:	whether @vec had an ECN nonce of 0 or 1
>    * @node:	FIFO - arranged in descending order of ack_ackno
>    *
> - * This structure is used by CCIDs to access Ack Vectors in a received skb.
> + * This structure is used by CCIDs to access Ack Vectors from the received skb.
>    */
>   struct dccp_ackvec_parsed {
> -	u8		 *vec,
> -			 len,
> -			 nonce:1;
>   	struct list_head node;
> +	u8 len;
> +	u8 nonce:1;
> +	u8 vec[] __counted_by(len);
>   };
> 
>   int dccp_ackvec_parsed_add(struct list_head *head, u8 *vec, u8 len, u8 nonce);
> diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c
> index d6b30700af67..a1f2da3c4fa9 100644
> --- a/net/dccp/ccids/ccid2.c
> +++ b/net/dccp/ccids/ccid2.c
> @@ -589,14 +589,15 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
>   	/* go through all ack vectors */
>   	list_for_each_entry(avp, &hc->tx_av_chunks, node) {
>   		/* go through this ack vector */
> -		for (; avp->len--; avp->vec++) {
> +		u8 *v;
> +		for (v = avp->vec; v < avp->vec + avp->len--; v++) {
>   			u64 ackno_end_rl = SUB48(ackno,
> -						 dccp_ackvec_runlen(avp->vec));
> +						 dccp_ackvec_runlen(v));
> 
>   			ccid2_pr_debug("ackvec %llu |%u,%u|\n",
>   				       (unsigned long long)ackno,
> -				       dccp_ackvec_state(avp->vec) >> 6,
> -				       dccp_ackvec_runlen(avp->vec));
> +				       dccp_ackvec_state(v) >> 6,
> +				       dccp_ackvec_runlen(v));
>   			/* if the seqno we are analyzing is larger than the
>   			 * current ackno, then move towards the tail of our
>   			 * seqnos.
> @@ -615,7 +616,7 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
>   			 * run length
>   			 */
>   			while (between48(seqp->ccid2s_seq,ackno_end_rl,ackno)) {
> -				const u8 state = dccp_ackvec_state(avp->vec);
> +				const u8 state = dccp_ackvec_state(v);
> 
>   				/* new packet received or marked */
>   				if (state != DCCPAV_NOT_RECEIVED &&
> 
> Comments are highly appreciated.

I wouldn't touch DCCP anymore unless the change is required for TCP.
(see b144fcaf46d43)

  reply	other threads:[~2024-10-23 17:51 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-10-23 12:09 KASAN: use-after-free Read in ccid2_hc_tx_packet_recv Dmitry Antipov
2024-10-23 17:51 ` Kuniyuki Iwashima [this message]
  -- strict thread matches above, loose matches on Subject: below --
2018-04-02  9:20 syzbot
2018-05-25 13:52 ` syzbot
2019-11-28 10:30 ` syzbot

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=20241023175121.36351-1-kuniyu@amazon.com \
    --to=kuniyu@amazon.com \
    --cc=dccp@vger.kernel.org \
    --cc=dmantipov@yandex.ru \
    --cc=netdev@vger.kernel.org \
    --cc=syzbot+554ccde221001ab5479a@syzkaller.appspotmail.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).