From: Leon Romanovsky <leon@kernel.org>
To: Zhu Yanjun <yanjun.zhu@linux.dev>
Cc: Michael Bommarito <michael.bommarito@gmail.com>,
security@kernel.org,
RDMA mailing list <linux-rdma@vger.kernel.org>,
Zhu Yanjun <zyjzyj2000@gmail.com>, Jason Gunthorpe <jgg@ziepe.ca>,
hkbinbin <hkbinbinbin@gmail.com>
Subject: Re: [PATCH] RDMA/rxe: Reject unknown opcodes before ICRC processing
Date: Tue, 14 Apr 2026 12:07:53 +0300 [thread overview]
Message-ID: <20260414090753.GS21470@unreal> (raw)
In-Reply-To: <e71fe83d-3e15-4bf2-89bf-4e0e42cbe2b5@linux.dev>
On Mon, Apr 13, 2026 at 10:23:55PM -0700, Zhu Yanjun wrote:
>
> 在 2026/4/13 18:17, Michael Bommarito 写道:
> > Even after applying commit 7244491dab34 ("RDMA/rxe: Validate pad and ICRC
> > before payload_size() in rxe_rcv"), a single unauthenticated UDP packet
> > can still trigger panic. That patch handled payload_size() underflow
> > only for valid opcodes with short packets, not for packets carrying an
> > unknown opcode. The unknown-opcode OOB read described below
> > predates that commit and reaches back to the initial Soft RoCE driver.
> >
> > The check added there reads
> >
> > pkt->paylen < header_size(pkt) + bth_pad(pkt) + RXE_ICRC_SIZE
> >
> > where header_size(pkt) expands to rxe_opcode[pkt->opcode].length. The
> > rxe_opcode[] array has 256 entries but is only populated for defined IB
> > opcodes; any other entry (for example opcode 0xff) is zero-initialized,
> > so length == 0 and the check degenerates to
> >
> > pkt->paylen < 0 + bth_pad(pkt) + RXE_ICRC_SIZE
> >
> > which does not constrain pkt->paylen enough. rxe_icrc_hdr() then
> > computes
> >
> > rxe_opcode[pkt->opcode].length - RXE_BTH_BYTES
> >
> > which underflows when length == 0 and passes a huge value to
> > rxe_crc32(), causing an out-of-bounds read of the skb payload.
> >
> > Reproduced on v7.0-rc7 with that fix applied, QEMU/KVM with
> > CONFIG_RDMA_RXE=y and CONFIG_KASAN=y, after
> >
> > rdma link add rxe0 type rxe netdev eth0
> >
> > A single 48-byte UDP packet to port 4791 with BTH opcode=0xff and
> > QPN=IB_MULTICAST_QPN triggers:
> >
> > BUG: KASAN: slab-out-of-bounds in crc32_le+0x115/0x170
> > Read of size 1 at addr ...
> > The buggy address is located 0 bytes to the right of
> > allocated 704-byte region
> > Call Trace:
> > crc32_le+0x115/0x170
> > rxe_icrc_hdr.isra.0+0x226/0x300
> > rxe_icrc_check+0x13f/0x3a0
> > rxe_rcv+0x6e1/0x16e0
> > rxe_udp_encap_recv+0x20a/0x320
> > udp_queue_rcv_one_skb+0x7ed/0x12c0
> >
> > Subsequent packets with the same shape fault on unmapped memory and
> > panic the kernel. The trigger requires only module load and
> > "rdma link add"; no QP, no connection, and no authentication.
> >
> > Fix this by rejecting packets whose opcode has no rxe_opcode[] entry,
> > detected via the zero mask, before any length arithmetic runs.
> >
> > Fixes: 8700e3e7c485 ("Soft RoCE driver")
> > Cc:stable@vger.kernel.org
> > Assisted-by: Claude:claude-opus-4-6
> > Signed-off-by: Michael Bommarito<michael.bommarito@gmail.com>
> > ---
> > drivers/infiniband/sw/rxe/rxe_recv.c | 9 +++++++++
> > 1 file changed, 9 insertions(+)
> >
> > diff --git a/drivers/infiniband/sw/rxe/rxe_recv.c b/drivers/infiniband/sw/rxe/rxe_recv.c
> > index f79214738c2b..413e1e954ce0 100644
> > --- a/drivers/infiniband/sw/rxe/rxe_recv.c
> > +++ b/drivers/infiniband/sw/rxe/rxe_recv.c
> > @@ -330,6 +330,15 @@ void rxe_rcv(struct sk_buff *skb)
> > pkt->qp = NULL;
> > pkt->mask |= rxe_opcode[pkt->opcode].mask;
> > + /*
> > + * Unknown opcodes have a zeroed rxe_opcode[] entry (mask == 0 and
> > + * length == 0). Reject them before any length math: rxe_icrc_hdr()
> > + * would otherwise compute length - RXE_BTH_BYTES and pass the
> > + * underflowed value to rxe_crc32(), producing an out-of-bounds read.
> > + */
> > + if (unlikely(rxe_opcode[pkt->opcode].mask == 0))
>
> Add rdma maillist.
>
> if (unlikely(!rxe_opcode[pkt->opcode].mask &&
> !rxe_opcode[pkt->opcode].length))
>
> I am not sure if "rxe_opcode[pkt->opcode].length == 0" should also be taken
> into account.
>
> Reviewed-by: Zhu Yanjun <yanjun.zhu@linux.dev>
We need patch to be sent to the ML, so we can merge it.
Thanks
>
> Zhu Yanjun
>
> > + goto drop;
> > +
> > if (unlikely(pkt->paylen < header_size(pkt) + bth_pad(pkt) +
> > RXE_ICRC_SIZE))
> > goto drop;
>
> --
> Best Regards,
> Yanjun.Zhu
parent reply other threads:[~2026-04-14 9:07 UTC|newest]
Thread overview: expand[flat|nested] mbox.gz Atom feed
[parent not found: <e71fe83d-3e15-4bf2-89bf-4e0e42cbe2b5@linux.dev>]
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=20260414090753.GS21470@unreal \
--to=leon@kernel.org \
--cc=hkbinbinbin@gmail.com \
--cc=jgg@ziepe.ca \
--cc=linux-rdma@vger.kernel.org \
--cc=michael.bommarito@gmail.com \
--cc=security@kernel.org \
--cc=yanjun.zhu@linux.dev \
--cc=zyjzyj2000@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.