All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] RDMA/rtrs-clt: Reject a zero queue_depth in the connection response
@ 2026-09-29  5:42 Yehyeong Lee
  2026-09-29  5:55 ` sashiko-bot
  2026-09-29  7:16 ` Jinpu Wang
  0 siblings, 2 replies; 3+ messages in thread
From: Yehyeong Lee @ 2026-09-29  5:42 UTC (permalink / raw)
  To: haris.iqbal, jinpu.wang
  Cc: Jason Gunthorpe, Leon Romanovsky, Farhad Alemi, linux-rdma,
	linux-kernel, Yehyeong Lee, stable

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@berkeley.edu>
Closes: https://lore.kernel.org/linux-rdma/CA+0ovCg_sG8gaZXXj9zmOrpxRt=8+-x9wvycVNUKwWmMbr6-Yg@mail.gmail.com/
Cc: stable@vger.kernel.org
Signed-off-by: Yehyeong Lee <yhlee@isslab.korea.ac.kr>
---
 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


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] RDMA/rtrs-clt: Reject a zero queue_depth in the connection response
  2026-09-29  5:42 [PATCH] RDMA/rtrs-clt: Reject a zero queue_depth in the connection response Yehyeong Lee
@ 2026-09-29  5:55 ` sashiko-bot
  2026-09-29  7:16 ` Jinpu Wang
  1 sibling, 0 replies; 3+ messages in thread
From: sashiko-bot @ 2026-09-29  5:55 UTC (permalink / raw)
  To: Yehyeong Lee; +Cc: linux-rdma

> 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
> [ ... ]
> Fixes: 6a98d71daea1 ("RDMA/rtrs: client: main functionality")
> Reported-by: Farhad Alemi <farhad.alemi@berkeley.edu>
> Closes: https://lore.kernel.org/linux-rdma/CA+0ovCg_sG8gaZXXj9zmOrpxRt=8+-x9wvycVNUKwWmMbr6-Yg@mail.gmail.com/
> Cc: stable@vger.kernel.org
> Signed-off-by: Yehyeong Lee <yhlee@isslab.korea.ac.kr>

Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260929054222.1576877-1-yhlee@isslab.korea.ac.kr?part=1


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] RDMA/rtrs-clt: Reject a zero queue_depth in the connection response
  2026-09-29  5:42 [PATCH] RDMA/rtrs-clt: Reject a zero queue_depth in the connection response Yehyeong Lee
  2026-09-29  5:55 ` sashiko-bot
@ 2026-09-29  7:16 ` Jinpu Wang
  1 sibling, 0 replies; 3+ messages in thread
From: Jinpu Wang @ 2026-09-29  7:16 UTC (permalink / raw)
  To: Yehyeong Lee
  Cc: haris.iqbal, Jason Gunthorpe, Leon Romanovsky, Farhad Alemi,
	linux-rdma, linux-kernel, stable

Hi Yehyeong,

Thx for your patch, there is a fix reviewed already:
https://lore.kernel.org/linux-rdma/CAMGffEkQ8tZZcrLp2Sc7UyZoqAyBoYMdkPhGvHX7RGqrwSmJzg@mail.gmail.com/

On Tue, Sep 29, 2026 at 7:43 AM Yehyeong Lee <yhlee@isslab.korea.ac.kr> 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@berkeley.edu>
> Closes: https://lore.kernel.org/linux-rdma/CA+0ovCg_sG8gaZXXj9zmOrpxRt=8+-x9wvycVNUKwWmMbr6-Yg@mail.gmail.com/
> Cc: stable@vger.kernel.org
> Signed-off-by: Yehyeong Lee <yhlee@isslab.korea.ac.kr>
> ---
>  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
>

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-09-29  7:16 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-29  5:42 [PATCH] RDMA/rtrs-clt: Reject a zero queue_depth in the connection response Yehyeong Lee
2026-09-29  5:55 ` sashiko-bot
2026-09-29  7:16 ` Jinpu Wang

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.