All of lore.kernel.org
 help / color / mirror / Atom feed
From: Simon Horman <horms@kernel.org>
To: "Ricardo Cañuelo Navarro" <rcn@igalia.com>
Cc: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>,
	Xin Long <lucien.xin@gmail.com>,
	"David S. Miller" <davem@davemloft.net>,
	Eric Dumazet <edumazet@google.com>,
	Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
	kernel-dev@igalia.com, linux-sctp@vger.kernel.org,
	netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
	stable@vger.kernel.org
Subject: Re: [PATCH] sctp: check transport existence before processing a send primitive
Date: Wed, 2 Apr 2025 14:21:41 +0100	[thread overview]
Message-ID: <20250402132141.GO214849@horms.kernel.org> (raw)
In-Reply-To: <20250402-kasan_slab-use-after-free_read_in_sctp_outq_select_transport-v1-1-da6f5f00f286@igalia.com>

On Wed, Apr 02, 2025 at 12:25:36PM +0200, Ricardo Cañuelo Navarro wrote:
> sctp_sendmsg() re-uses associations and transports when possible by
> doing a lookup based on the socket endpoint and the message destination
> address, and then sctp_sendmsg_to_asoc() sets the selected transport in
> all the message chunks to be sent.
> 
> There's a possible race condition if another thread triggers the removal
> of that selected transport, for instance, by explicitly unbinding an
> address with setsockopt(SCTP_SOCKOPT_BINDX_REM), after the chunks have
> been set up and before the message is sent. This causes the access to
> the transport data in sctp_outq_select_transport(), when the association
> outqueue is flushed, to do a use-after-free read.
> 
> This patch addresses this scenario by checking if the transport still
> exists right after the chunks to be sent are set up to use it and before
> proceeding to sending them. If the transport was freed since it was
> found, the send is aborted. The reason to add the check here is that
> once the transport is assigned to the chunks, deleting that transport
> is safe, since it will also set chunk->transport to NULL in the affected
> chunks. This scenario is correctly handled already, see Fixes below.
> 
> The bug was found by a private syzbot instance (see the error report [1]
> and the C reproducer that triggers it [2]).
> 
> Link: https://people.igalia.com/rcn/kernel_logs/20250402__KASAN_slab-use-after-free_Read_in_sctp_outq_select_transport.txt [1]
> Link: https://people.igalia.com/rcn/kernel_logs/20250402__KASAN_slab-use-after-free_Read_in_sctp_outq_select_transport__repro.c [2]
> Cc: stable@vger.kernel.org
> Fixes: df132eff4638 ("sctp: clear the transport of some out_chunk_list chunks in sctp_assoc_rm_peer")
> Signed-off-by: Ricardo Cañuelo Navarro <rcn@igalia.com>
> ---
>  net/sctp/socket.c | 16 ++++++++++++++++
>  1 file changed, 16 insertions(+)
> 
> diff --git a/net/sctp/socket.c b/net/sctp/socket.c
> index 36ee34f483d703ffcfe5ca9e6cc554fba24c75ef..9c5ff44fa73cae6a6a04790800cc33dfa08a8da9 100644
> --- a/net/sctp/socket.c
> +++ b/net/sctp/socket.c
> @@ -1787,17 +1787,24 @@ static int sctp_sendmsg_check_sflags(struct sctp_association *asoc,
>  	return 1;
>  }
>  
> +static union sctp_addr *sctp_sendmsg_get_daddr(struct sock *sk,
> +					       const struct msghdr *msg,
> +					       struct sctp_cmsgs *cmsgs);
> +
>  static int sctp_sendmsg_to_asoc(struct sctp_association *asoc,
>  				struct msghdr *msg, size_t msg_len,
>  				struct sctp_transport *transport,
>  				struct sctp_sndrcvinfo *sinfo)
>  {
> +	struct sctp_transport *aux_transport = NULL;
>  	struct sock *sk = asoc->base.sk;
> +	struct sctp_endpoint *ep = sctp_sk(sk)->ep;
>  	struct sctp_sock *sp = sctp_sk(sk);
>  	struct net *net = sock_net(sk);
>  	struct sctp_datamsg *datamsg;
>  	bool wait_connect = false;
>  	struct sctp_chunk *chunk;
> +	union sctp_addr *daddr;
>  	long timeo;
>  	int err;
>  
> @@ -1869,6 +1876,15 @@ static int sctp_sendmsg_to_asoc(struct sctp_association *asoc,
>  		sctp_set_owner_w(chunk);
>  		chunk->transport = transport;
>  	}
> +	/* Fail if transport was deleted after lookup in sctp_sendmsg() */
> +	daddr = sctp_sendmsg_get_daddr(sk, msg, NULL);
> +	if (daddr) {
> +		sctp_endpoint_lookup_assoc(ep, daddr, &aux_transport);
> +		if (!aux_transport || aux_transport != transport) {
> +			sctp_datamsg_free(datamsg);
> +			goto err;

Hi Ricardo,

This is not a full review, and I would suggest waiting for one from others.
But this will result in the local variable err being used uninitialised.

Flagged by Smatch.

> +		}
> +	}
>  
>  	err = sctp_primitive_SEND(net, asoc, datamsg);
>  	if (err) {

-- 
pw-bot: changes-requested

  reply	other threads:[~2025-04-02 13:21 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-04-02 10:25 [PATCH] sctp: check transport existence before processing a send primitive Ricardo Cañuelo Navarro
2025-04-02 13:21 ` Simon Horman [this message]
2025-04-02 13:37   ` Ricardo Cañuelo Navarro
2025-04-02 14:03     ` Ricardo Cañuelo Navarro
2025-04-02 19:40 ` Xin Long
2025-04-03  9:58   ` Ricardo Cañuelo Navarro
2025-04-03 14:42     ` Xin Long
2025-04-03 18:44       ` Xin Long
2025-04-04 10:04         ` Ricardo Cañuelo Navarro
2025-04-04 14:22           ` Xin Long
2025-04-07  7:37             ` Ricardo Cañuelo Navarro

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=20250402132141.GO214849@horms.kernel.org \
    --to=horms@kernel.org \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=kernel-dev@igalia.com \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-sctp@vger.kernel.org \
    --cc=lucien.xin@gmail.com \
    --cc=marcelo.leitner@gmail.com \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=rcn@igalia.com \
    --cc=stable@vger.kernel.org \
    /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.