public inbox for passt-dev@passt.top
 help / color / mirror / code / Atom feed
From: Stefano Brivio <sbrivio@redhat.com>
To: Anshu Kumari <anskuma@redhat.com>
Cc: passt-dev@passt.top
Subject: Re: [PATCH] tcp: Avoid division by zero with small MSS values
Date: Wed, 21 Oct 2026 02:11:13 +0200 (CEST)	[thread overview]
Message-ID: <20261021021112.385ea997@elisabeth> (raw)
In-Reply-To: <20261016112811.4176811-1-anskuma@redhat.com>

On Fri, 16 Oct 2026 16:58:11 +0530
Anshu Kumari <anskuma@redhat.com> wrote:

> Fuzz testing with AFL++ persistent mode found a crash

Yay, that's quite an achievement!

> in
> tcp_buf_data_from_sock(), SIGFPE (signal 8) from division
> by zero at:
> 
>   fill_bufs = DIV_ROUND_UP(wnd_scaled - already_sent, mss);
> 
> when we split buffers on MSS boundaries, if the MSS is small
> enough (less than four, rounded down to 0).
> 
> A guest advertising such a small MSS indicates unusual
> behaviour because the minimum usable MSS is
> MTU - IP header - TCP header (28 bytes for the minimum
> IPv4 MTU of 68). To improve robustness:
> 
>   - Fix MSS_SET() to round up when MSS is between 1 and 3,
>     storing tap_mss as 1 (recovered as 4 by MSS_GET()).

This introduces a subtle problem though: if the MSS is between 1 and 3
(silly but I guess legitimate), we would overflow it now.

I think we should rather adjust MSS_GET() as well, to always use 1 for
values 0 < x < 4.

>   - In case of zero MSS, don't send data: tcp_buf_data_from_sock()
>     now returns early.
> 
> This is not a security issue: the effect of a zero MSS from
> a guest input was a clean process termination (SIGFPE), not
> memory corruption or data leakage.

And, actually, a rather convenient termination because the guest might
be doing something nasty here, so much that an assert() could also be a
reasonable choice instead (even though I still think that trying to be
robust against this condition makes more sense).

Anyway, now that we continue, we should really make sure we're not
introducing actual issues. Maybe it would be good to keep fuzzing for a
while with this change, and see what else (if anything) a zero or very
low MSS can actually trigger.

> 
> Signed-off-by: Anshu Kumari <anskuma@redhat.com>
> ---
>  tcp_buf.c  | 3 +++
>  tcp_conn.h | 3 ++-
>  2 files changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/tcp_buf.c b/tcp_buf.c
> index 72c45412..ee8c7ce8 100644
> --- a/tcp_buf.c
> +++ b/tcp_buf.c
> @@ -335,6 +335,9 @@ int tcp_buf_data_from_sock(const struct ctx *c, struct tcp_tap_conn *conn,
>  	struct iovec *iov;
>  	uint32_t seq;
>  
> +	if (!mss)
> +		return 0;
> +
>  	/* Set up buffer descriptors we'll fill completely and partially. */
>  	fill_bufs = DIV_ROUND_UP(wnd_scaled - already_sent, mss);
>  	if (fill_bufs > TCP_FRAMES) {
> diff --git a/tcp_conn.h b/tcp_conn.h
> index e3c55341..3f5ad28b 100644
> --- a/tcp_conn.h
> +++ b/tcp_conn.h
> @@ -51,7 +51,8 @@ struct tcp_tap_conn {
>  
>  #define TCP_MSS_BITS			14
>  	unsigned int	tap_mss		:TCP_MSS_BITS;
> -#define MSS_SET(conn, mss)	(conn->tap_mss = (mss >> (16 - TCP_MSS_BITS)))
> +#define MSS_SET(conn, mss)						\
> +	(conn->tap_mss = (mss) ? MAX(1, (mss) >> (16 - TCP_MSS_BITS)) : 0)

I think this would deserve a comment at this point (above the define),
clearly explaining that we are use 1 just to avoid rounding to zero for
values less than 4.

And, I guess (untested):

>  #define MSS_GET(conn)		(conn->tap_mss << (16 - TCP_MSS_BITS))

#define MSS_GET(conn)							\
	((conn->tap_mss == 1) ? 1 : (conn->tap_mss << (16 - TCP_MSS_BITS)))

...with another comment explaining that tap_mss is stored as 1 for
any non-zero MSS value <= 4.

>  
>  #define RTT_EXP_BITS			4

-- 
Stefano


  reply	other threads:[~2026-10-21  0:11 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-16 11:28 Anshu Kumari
2026-10-21  0:11 ` Stefano Brivio [this message]
2026-10-21  1:38   ` David Gibson

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=20261021021112.385ea997@elisabeth \
    --to=sbrivio@redhat.com \
    --cc=anskuma@redhat.com \
    --cc=passt-dev@passt.top \
    /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.
Code repositories for project(s) associated with this public inbox

	https://passt.top/passt

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 IMAP folder(s).