All of lore.kernel.org
 help / color / mirror / Atom feed
From: Bernard Metzler <bernard.metzler@linux.dev>
To: Michael Bommarito <michael.bommarito@gmail.com>,
	Jason Gunthorpe <jgg@ziepe.ca>, Leon Romanovsky <leon@kernel.org>,
	linux-rdma@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Subject: Re: [PATCH 1/2] RDMA/siw: reject MPA FPDU length underflow before signed receive math
Date: Thu, 14 May 2026 19:10:54 +0200	[thread overview]
Message-ID: <fcbc4f0c-7dfb-4e8f-9788-f8d6daa37149@linux.dev> (raw)
In-Reply-To: <20260513175325.2042630-2-michael.bommarito@gmail.com>

On 13.05.2026 19:53, Michael Bommarito wrote:
> A malicious connected siw peer can send an iWARP FPDU whose MPA length
> field (c_hdr->mpa_len, 16 bit big-endian, peer-controlled) is smaller
> than the fixed DDP/RDMAP header for the announced opcode. Soft-iWARP
> parses the full header in siw_get_hdr() based on iwarp_pktinfo[opcode]
> .hdr_len, but never compares mpa_len against that header length.
> 
> siw_tcp_rx_data() then derives
> 
>      srx->fpdu_part_rem = be16_to_cpu(mpa_len) - fpdu_part_rcvd
>                           + MPA_HDR_SIZE;
> 
> where fpdu_part_rcvd equals iwarp_pktinfo[opcode].hdr_len at this
> point. For a tagged WRITE (hdr_len 16, MPA_HDR_SIZE 2) the smallest
> on-wire mpa_len of 0 yields fpdu_part_rem = -14, and any mpa_len below
> hdr_len - MPA_HDR_SIZE underflows to a negative int.
> 
> The signed value then flows into siw_proc_write()/siw_proc_rresp() as
> 
>      bytes = min(srx->fpdu_part_rem, srx->skb_new);
> 
> is handed to siw_check_mem() as an int len (whose interval check
> addr + len > mem->va + mem->len is satisfied for a valid base when
> len is negative), and reaches siw_rx_data() -> siw_rx_kva() /
> siw_rx_umem() -> skb_copy_bits() as a signed copy length. The header
> copy branch in skb_copy_bits() promotes that to size_t, producing a
> multi-gigabyte read.
> 
> KASAN under a KUnit harness that drives the real kernel TCP receive
> path -- a loopback AF_INET socketpair, the malformed FPDU written via
> kernel_sendmsg, sk_data_ready firing in softirq, tcp_read_sock
> dispatching to siw_tcp_rx_data -- reports:
> 
>      BUG: KASAN: use-after-free in skb_copy_bits+0x284/0x480
>      Read of size 4294967295 at addr ffff888...
>      Call Trace:
>       skb_copy_bits
>       siw_rx_kva
>       siw_rx_data
>       siw_check_mem
>       siw_proc_write
>       siw_tcp_rx_data
>       __tcp_read_sock
>       siw_qp_llp_data_ready
>       tcp_data_ready
>       tcp_data_queue
> 
> Add the missing invariant at the earliest point where the peer header
> is fully assembled. iwarp_pktinfo[*].hdr_len - MPA_HDR_SIZE is exactly
> the value the siw transmitter uses as the minimum mpa_len for each
> opcode (drivers/infiniband/sw/siw/siw_qp.c:33), so this matches the
> protocol contract. Out-of-range FPDUs terminate the connection with
> TERM_ERROR_LAYER_LLP / LLP_ETYPE_MPA / LLP_ECODE_FPDU_START -- which
> is RFC 5044 Section 8 error code 3 ("Marker and ULPDU Length fields
> do not agree on the start of an FPDU"), the correct framing-error
> class for this inconsistency.
> 
> Fixes: 8b6a361b8c48 ("rdma/siw: receive path")
> Cc: stable@vger.kernel.org
> Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
> Assisted-by: Claude:claude-opus-4-7
> ---
> See cover letter for full root cause, series rationale, and test
> summary.  [2/2] adds the KUnit regression harness used to validate
> this fix.
> 
>   drivers/infiniband/sw/siw/siw_qp_rx.c | 15 +++++++++++++++
>   1 file changed, 15 insertions(+)
> 
> diff --git a/drivers/infiniband/sw/siw/siw_qp_rx.c b/drivers/infiniband/sw/siw/siw_qp_rx.c
> index e8a88b378d51..34d03584160c 100644
> --- a/drivers/infiniband/sw/siw/siw_qp_rx.c
> +++ b/drivers/infiniband/sw/siw/siw_qp_rx.c
> @@ -1081,6 +1081,21 @@ static int siw_get_hdr(struct siw_rx_stream *srx)
>   			return -EAGAIN;
>   	}
>   
> +	/*
> +	 * Peer-controlled mpa_len must not underflow srx->fpdu_part_rem
> +	 * in siw_tcp_rx_data(); a negative value flows as a signed copy
> +	 * length into siw_check_mem() and skb_copy_bits().
> +	 */

Excellent finding. This was an open gateway for all evil.


> +	if (unlikely(be16_to_cpu(c_hdr->mpa_len) + MPA_HDR_SIZE <
> +		     iwarp_pktinfo[opcode].hdr_len)) {
> +		pr_warn_ratelimited("siw: short mpa_len %u for opcode %u (hdr_len %u)\n",

I think we shall stay with 80 chars per line. So let's
wrap the above line.

Otherwise
Acked-by: Bernard Metzler <bernard.metzler@linux.dev>


> +				    be16_to_cpu(c_hdr->mpa_len), opcode,
> +				    iwarp_pktinfo[opcode].hdr_len);
> +		siw_init_terminate(rx_qp(srx), TERM_ERROR_LAYER_LLP,
> +				   LLP_ETYPE_MPA, LLP_ECODE_FPDU_START, 0);
> +		return -EINVAL;
> +	}
> +
>   	/*
>   	 * DDP/RDMAP header receive completed. Check if the current
>   	 * DDP segment starts a new RDMAP message or continues a previously


  reply	other threads:[~2026-05-14 17:11 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-13 17:53 [PATCH 0/2] RDMA/siw: fix MPA FPDU length underflow + add KUnit coverage Michael Bommarito
2026-05-13 17:53 ` [PATCH 1/2] RDMA/siw: reject MPA FPDU length underflow before signed receive math Michael Bommarito
2026-05-14 17:10   ` Bernard Metzler [this message]
2026-05-14 21:24   ` Jason Gunthorpe
2026-05-13 17:53 ` [PATCH 2/2] RDMA/siw: add KUnit tests for MPA receive parsing Michael Bommarito
2026-05-15 10:39   ` Bernard Metzler

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=fcbc4f0c-7dfb-4e8f-9788-f8d6daa37149@linux.dev \
    --to=bernard.metzler@linux.dev \
    --cc=jgg@ziepe.ca \
    --cc=leon@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-rdma@vger.kernel.org \
    --cc=michael.bommarito@gmail.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.