All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sabrina Dubroca <sd@queasysnail.net>
To: Bruno Produit <bruno.produit@trailofbits.com>
Cc: Steffen Klassert <steffen.klassert@secunet.com>,
	Herbert Xu <herbert@gondor.apana.org.au>,
	"David S . Miller" <davem@davemloft.net>,
	netdev@vger.kernel.org, Kyle Zeng <kylebot@openai.com>,
	linux-kernel@vger.kernel.org,
	Dominik Czarnota <dominik.czarnota@trailofbits.com>,
	stable@vger.kernel.org
Subject: Re: [PATCH] xfrm: espintcp: build sk_msg locally before publishing
Date: Wed, 23 Sep 2026 12:02:01 +0200	[thread overview]
Message-ID: <arOjmbAt_ctmnB9S@krikkit> (raw)
In-Reply-To: <20260922145335.2016559-1-bruno.produit@trailofbits.com>

2026-09-22, 16:53:35 +0200, Bruno Produit wrote:
> From: Kyle Zeng <kylebot@openai.com>
> 
> espintcp_sendmsg() builds a new message directly in ctx->partial. If
> allocation fails, sk_stream_wait_memory() drops the socket lock while
> the shared sk_msg remains unpublished with emsg->len equal to zero. A
> concurrent sender can then reuse the same slot. If the first sender is

Could we add an ->owned flag to emsg to make the other sender
wait/abort when the flag is set (whether the emsg has been fully set
up or not)?

If not, comments below.

> interrupted, its failure path frees state now owned by the second sender
> while TCP may still be consuming it, causing a use-after-free.
> 
> Construct the message in a call-local sk_msg instead.


> After allocation
> and any lock-dropping wait, recheck that the shared partial slot is still
> free, then transfer the completed message into it. Failure cleanup
> consequently releases only state owned by the current call.

Please don't describe what the patch does. We can read the code.

> The recheck
> also covers packets submitted through the common IPv4 and IPv6
> espintcp_push_skb() path.

I have no idea what this means.


> diff --git a/net/xfrm/espintcp.c b/net/xfrm/espintcp.c
> index 674aedc..1642b34 100644
> --- a/net/xfrm/espintcp.c
> +++ b/net/xfrm/espintcp.c
> @@ -311,6 +311,7 @@ static int espintcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)
>  	struct espintcp_msg *emsg = &ctx->partial;
>  	struct iov_iter pfx_iter;
>  	struct kvec pfx_iov = {};
> +	struct sk_msg *skmsg;

nit: reverse xmas tree ordering

>  	size_t msglen = size + 2;
>  	char buf[2] = {0};
>  	int err, end;
> @@ -324,6 +325,11 @@ static int espintcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)
>  	if (msg->msg_controllen)
>  		return -EOPNOTSUPP;
>  
> +	skmsg = kmalloc_obj(*skmsg);
> +	if (!skmsg)
> +		return -ENOMEM;
> +	sk_msg_init(skmsg);

Why do that before trying (and possibly failing) to push the pending
message?

>  	lock_sock(sk);
>  
>  	err = espintcp_push_msgs(sk, msg->msg_flags & MSG_DONTWAIT);
> @@ -337,10 +343,9 @@ static int espintcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)
>  		goto unlock;
>  	}
>  
> -	sk_msg_init(&emsg->skmsg);
>  	while (1) {
>  		/* only -ENOMEM is possible since we don't coalesce */
> -		err = sk_msg_alloc(sk, &emsg->skmsg, msglen, 0);
> +		err = sk_msg_alloc(sk, skmsg, msglen, 0);
>  		if (!err)
>  			break;
>  
> @@ -348,25 +353,30 @@ static int espintcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)
>  		if (err)
>  			goto fail;
>  	}
> +	if (emsg->len) {
> +		err = -ENOBUFS;
> +		goto fail;
> +	}

Do another espintcp_push_msgs before giving up?

And there should be a comment here to explain why we need to recheck
emsg->len even though we already did at the top (something like "we
may have dropped the lock in sk_stream_wait_memory, check if someone
else used the emsg").

-- 
Sabrina

      reply	other threads:[~2026-09-23 10:02 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-22 14:53 [PATCH] xfrm: espintcp: build sk_msg locally before publishing Bruno Produit
2026-09-23 10:02 ` Sabrina Dubroca [this message]

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=arOjmbAt_ctmnB9S@krikkit \
    --to=sd@queasysnail.net \
    --cc=bruno.produit@trailofbits.com \
    --cc=davem@davemloft.net \
    --cc=dominik.czarnota@trailofbits.com \
    --cc=herbert@gondor.apana.org.au \
    --cc=kylebot@openai.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=steffen.klassert@secunet.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.