Re: [PATCH] RDMA/rtrs-clt: Reject a zero queue_depth in the connection response
From: Jinpu Wang
Date: Tue Sep 29 2026 - 03:17:41 EST
Hi Yehyeong,
Thx for your patch, there is a fix reviewed already:
https://lore.kernel.org/linux-rdma/CAMGffEkQ8tZZcrLp2Sc7UyZoqAyBoYMdkPhGvHX7RGqrwSmJzg@xxxxxxxxxxxxxx/
On Tue, Sep 29, 2026 at 7:43 AM Yehyeong Lee <yhlee@xxxxxxxxxxxxxxxxxx> wrote:
>
> rtrs_rdma_conn_established() stores the queue_depth the server advertises
> in its cid 0 connection response without checking that it is usable. The
> only bound it ever had was an upper one, dropped in commit 0e8558476faf
> ("RDMA/rtrs: Avoid Wtautological-constant-out-of-range-compare") because
> it cannot fail for a u16; a lower bound was never there. A server that
> reports zero therefore leaves clt_path->queue_depth at 0, and setting up
> the first I/O connection trips
>
> if (WARN_ON(!clt_path->queue_depth))
>
> in create_con_cq_qp(). The connect is aborted, but the peer has already
> tainted the kernel, and on a kernel built with panic_on_warn it panics
> outright -- all from one field in the response to a connect.
>
> The rbufs array is sized from the same value one statement earlier, so it
> is also allocated with zero elements, which kzalloc_objs() returns as
> ZERO_SIZE_PTR. Nothing dereferences it: the WARN aborts the connect
> before any buffer is registered and the path is then freed, and a path
> that already carries a nonzero depth is caught on reconnect by the
> existing "queue depth changed" test. The WARN is the whole of the damage.
>
> The in-tree server never sends zero -- check_module_params() rejects
> sess_queue_depth < 1 -- so this needs a hostile or broken server, but the
> client should not rely on the peer for that. Reject it before rbufs is
> sized from it and before it is stored, but after the existing "queue depth
> changed" test, so that a server which drops a nonzero depth to zero across
> a reconnect still takes that path and still disables auto-reconnect.
>
> Reproduced with rnbd-client over soft-RoCE against an rtrs-server patched
> to advertise queue_depth = 0:
>
> WARNING: drivers/infiniband/ulp/rtrs/rtrs-clt.c:1688 at
> rtrs_clt_rdma_cm_handler+0x1b27/0x29f0, CPU#0: kworker/u8:5/56
> Modules linked in:
> CPU: 0 UID: 0 PID: 56 Comm: kworker/u8:5 Not tainted
> 7.3.0-rc5-nvmerdma-atk-g72d3fcf802c4-dirty #23 PREEMPT(lazy)
> Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps fix,
> 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
> Workqueue: ib_addr process_one_req
> RIP: 0010:rtrs_clt_rdma_cm_handler+0x1b27/0x29f0
> Call Trace:
> <TASK>
> ? arch_stack_walk+0x94/0xf0
> ? __pfx_rtrs_clt_rdma_cm_handler+0x10/0x10
> ? ret_from_fork_asm+0x1a/0x30
> ? process_one_work+0x6b4/0x10e0
> ? stack_trace_save+0x8e/0xc0
> ? __pfx_stack_trace_save+0x10/0x10
> ? __kasan_slab_free+0x43/0x70
> ? stack_depot_save_flags+0x29/0x7e0
> ? worker_thread+0x45b/0xd10
> ? kthread+0x2c8/0x3b0
> ? ret_from_fork+0x36e/0x5a0
> ? _raw_spin_lock_irqsave+0x86/0xe0
> cma_cm_event_handler+0x3e/0x240
> addr_handler+0x1e0/0x300
> ? __pfx_addr_handler+0x10/0x10
> ? pick_task_fair+0x46f/0x1a60
> process_one_req+0x10d/0x510
> ? finish_task_switch.isra.0+0x1d9/0xa70
> ? __pfx_process_one_req+0x10/0x10
> process_one_work+0x6b4/0x10e0
> ? __pfx___schedule+0x10/0x10
> ? __pfx_process_one_work+0x10/0x10
> ? _raw_spin_lock_irq+0x81/0xe0
> ? __pfx_process_one_req+0x10/0x10
> ? assign_work+0x11d/0x370
> worker_thread+0x45b/0xd10
> ? __pfx_worker_thread+0x10/0x10
> ? __pfx_worker_thread+0x10/0x10
> kthread+0x2c8/0x3b0
> ? recalc_sigpending+0x15c/0x1e0
> ? __pfx_kthread+0x10/0x10
> ret_from_fork+0x36e/0x5a0
> ? __pfx_ret_from_fork+0x10/0x10
> ? __switch_to+0x572/0xdd0
> ? __pfx_kthread+0x10/0x10
> ret_from_fork_asm+0x1a/0x30
> </TASK>
> ---[ end trace 0000000000000000 ]---
>
> rtrs_client L2644: <s1>: init_conns() failed: err=-EINVAL
> path=<invalid address family>@ip:10.0.0.1 [rxe0:1]
>
> With the check in place the same server is refused without a splat, and an
> honest server is unaffected:
>
> rtrs_client L1870: <s1>: Invalid RTRS message: queue_depth is 0
> rtrs_client L2649: <s1>: init_conns() failed: err=-ECONNRESET
> path=<invalid address family>@ip:10.0.0.1 [:0]
>
> Fixes: 6a98d71daea1 ("RDMA/rtrs: client: main functionality")
> Reported-by: Farhad Alemi <farhad.alemi@xxxxxxxxxxxx>
> Closes: https://lore.kernel.org/linux-rdma/CA+0ovCg_sG8gaZXXj9zmOrpxRt=8+-x9wvycVNUKwWmMbr6-Yg@xxxxxxxxxxxxxx/
> Cc: stable@xxxxxxxxxxxxxxx
> Signed-off-by: Yehyeong Lee <yhlee@xxxxxxxxxxxxxxxxxx>
> ---
> drivers/infiniband/ulp/rtrs/rtrs-clt.c | 5 +++++
> 1 file changed, 5 insertions(+)
>
> diff --git a/drivers/infiniband/ulp/rtrs/rtrs-clt.c b/drivers/infiniband/ulp/rtrs/rtrs-clt.c
> index eac38b57b00d7..5c2c65c15a65a 100644
> --- a/drivers/infiniband/ulp/rtrs/rtrs-clt.c
> +++ b/drivers/infiniband/ulp/rtrs/rtrs-clt.c
> @@ -1866,6 +1866,11 @@ static int rtrs_rdma_conn_established(struct rtrs_clt_con *con,
> return -ECONNRESET;
> }
>
> + if (!queue_depth) {
> + rtrs_err(clt, "Invalid RTRS message: queue_depth is 0\n");
> + return -ECONNRESET;
> + }
> +
> if (!clt_path->rbufs) {
> clt_path->rbufs = kzalloc_objs(*clt_path->rbufs,
> queue_depth);
> --
> 2.43.0
>