* [PATCH v2 RESEND 1/2] RDMA/srp: refuse a target that cannot receive an SRP_RSP
2026-10-26 5:54 [PATCH v2 RESEND 0/2] RDMA/srp: bound the receive IU the target asks for Yehyeong Lee
@ 2026-10-26 5:54 ` Yehyeong Lee
2026-10-26 9:00 ` sashiko-bot
2026-10-26 5:54 ` [PATCH v2 RESEND 2/2] RDMA/srp: do not DMA-sync a receive IU past its mapped length Yehyeong Lee
2026-10-26 17:16 ` [PATCH v2 RESEND 0/2] RDMA/srp: bound the receive IU the target asks for Bart Van Assche
2 siblings, 1 reply; 6+ messages in thread
From: Yehyeong Lee @ 2026-10-26 5:54 UTC (permalink / raw)
To: Bart Van Assche
Cc: Leon Romanovsky, Jason Gunthorpe, linux-rdma, linux-kernel,
stable, yhlee
srp_cm_rep_handler() takes max_ti_iu_len straight from the target's
SRP_LOGIN_RSP and srp_alloc_iu_bufs() then sizes every receive IU with it,
so the target alone decides how large the initiator's receive buffers are.
Nothing enforces a lower bound.
The initiator parses a 36 byte header out of those buffers. A target that
reports a smaller max_ti_iu_len gets undersized buffers, and the header
reads in srp_process_rsp() then run past the allocation. A report of zero
is worse, because kzalloc() answers it with ZERO_SIZE_PTR, and on a
transport that maps addresses virtually ib_dma_map_single() returns that
pointer without looking at the length and ib_dma_mapping_error() reports
success, so the buffer reaches srp_recv_done() and the read of the opcode
is already out of bounds.
BUG: KASAN: slab-out-of-bounds in srp_process_rsp+0x757/0xbe0
Read of size 4 at addr ffff88800243f120 by task kunit_try_catch/42
CPU: 0 UID: 0 PID: 42 Comm: kunit_try_catch Tainted: G N 7.3.0-13249-gcea86339412a-dirty #2 PREEMPT(lazy)
Tainted: [N]=TEST
Call Trace:
<TASK>
dump_stack_lvl+0x3f/0x50
print_report+0xcd/0x620
? vprintk_emit+0x21d/0x380
? srp_process_rsp+0x757/0xbe0
kasan_report+0xde/0x110
? srp_process_rsp+0x757/0xbe0
srp_process_rsp+0x757/0xbe0
srp_oob33_test+0x305/0x700
? __pfx_srp_oob33_test+0x10/0x10
? __set_cpus_allowed_ptr+0x181/0x240
? __pfx_read_tsc+0x10/0x10
? ktime_get_ts64+0x192/0x250
kunit_try_run_case+0x1ca/0x4b0
? __pfx_kunit_try_run_case+0x10/0x10
? kthread_affine_node+0x24b/0x370
? __pfx_kthread_affine_node+0x10/0x10
? __pfx_kunit_try_run_case+0x10/0x10
? __pfx_kunit_generic_run_threadfn_adapter+0x10/0x10
kunit_generic_run_threadfn_adapter+0x7b/0xe0
kthread+0x36e/0x500
? __pfx_kthread+0x10/0x10
ret_from_fork+0x34d/0x620
? __pfx_ret_from_fork+0x10/0x10
? __switch_to+0x22/0xdd0
? __pfx_kthread+0x10/0x10
ret_from_fork_asm+0x19/0x30
</TASK>
Allocated by task 42:
kasan_save_stack+0x33/0x60
kasan_save_track+0x14/0x30
__kasan_kmalloc+0x8f/0xa0
__kmalloc_noprof+0x179/0x3b0
srp_alloc_iu.constprop.0+0x69/0x5c0
srp_cm_rep_handler+0xc2e/0x1bb0
srp_test_login+0xc8/0x630
srp_oob33_test+0xaa/0x700
kunit_try_run_case+0x1ca/0x4b0
kunit_generic_run_threadfn_adapter+0x7b/0xe0
kthread+0x36e/0x500
ret_from_fork+0x34d/0x620
ret_from_fork_asm+0x19/0x30
The buggy address belongs to the object at ffff88800243f100
which belongs to the cache kmalloc-64 of size 64
The buggy address is located 32 bytes inside of
allocated 33-byte region [ffff88800243f100, ffff88800243f121)
The KUnit harness that forces this is not part of this patch.
Refuse the login instead. Both the largest messages the initiator parses,
SRP_RSP and SRP_AER_REQ, are 36 bytes, and a target that cannot send one
cannot speak the protocol, so nothing that works today is turned away.
Fixes: aef9ec39c47f ("IB: Add SCSI RDMA Protocol (SRP) initiator")
Cc: stable@vger.kernel.org
Signed-off-by: Yehyeong Lee <yhlee@isslab.korea.ac.kr>
---
drivers/infiniband/ulp/srp/ib_srp.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index 5811f02df9805..a85d28b95306a 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -2379,6 +2379,13 @@ static void srp_cm_rep_handler(struct ib_cm_id *cm_id,
if (lrsp->opcode == SRP_LOGIN_RSP) {
ch->max_ti_iu_len = be32_to_cpu(lrsp->max_ti_iu_len);
+ if (ch->max_ti_iu_len < sizeof(struct srp_rsp)) {
+ shost_printk(KERN_ERR, target->scsi_host, PFX
+ "Target reported max_ti_iu_len %u, too small for a %zu byte SRP_RSP\n",
+ ch->max_ti_iu_len, sizeof(struct srp_rsp));
+ ret = -ECONNRESET;
+ goto error;
+ }
ch->req_lim = be32_to_cpu(lrsp->req_lim_delta);
ch->use_imm_data = srp_use_imm_data &&
(lrsp->rsp_flags & SRP_LOGIN_RSP_IMMED_SUPP);
^ permalink raw reply related [flat|nested] 6+ messages in thread* Re: [PATCH v2 RESEND 1/2] RDMA/srp: refuse a target that cannot receive an SRP_RSP
2026-10-26 5:54 ` [PATCH v2 RESEND 1/2] RDMA/srp: refuse a target that cannot receive an SRP_RSP Yehyeong Lee
@ 2026-10-26 9:00 ` sashiko-bot
0 siblings, 0 replies; 6+ messages in thread
From: sashiko-bot @ 2026-10-26 9:00 UTC (permalink / raw)
To: Yehyeong Lee; +Cc: linux-rdma
> srp_cm_rep_handler() takes max_ti_iu_len straight from the target's
> SRP_LOGIN_RSP and srp_alloc_iu_bufs() then sizes every receive IU with it,
> so the target alone decides how large the initiator's receive buffers are.
> Nothing enforces a lower bound.
>
> The initiator parses a 36 byte header out of those buffers. A target that
> reports a smaller max_ti_iu_len gets undersized buffers, and the header
> reads in srp_process_rsp() then run past the allocation. A report of zero
> is worse, because kzalloc() answers it with ZERO_SIZE_PTR, and on a
> transport that maps addresses virtually ib_dma_map_single() returns that
> pointer without looking at the length and ib_dma_mapping_error() reports
> success, so the buffer reaches srp_recv_done() and the read of the opcode
> is already out of bounds.
>
> BUG: KASAN: slab-out-of-bounds in srp_process_rsp+0x757/0xbe0
> [ ... ]
> cannot speak the protocol, so nothing that works today is turned away.
>
> Fixes: aef9ec39c47f ("IB: Add SCSI RDMA Protocol (SRP) initiator")
> Cc: stable@vger.kernel.org
> Signed-off-by: Yehyeong Lee <yhlee@isslab.korea.ac.kr>
Sashiko has reviewed this patch and found no issues.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261026055430.406487-1-yhlee@isslab.korea.ac.kr?part=1
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v2 RESEND 2/2] RDMA/srp: do not DMA-sync a receive IU past its mapped length
2026-10-26 5:54 [PATCH v2 RESEND 0/2] RDMA/srp: bound the receive IU the target asks for Yehyeong Lee
2026-10-26 5:54 ` [PATCH v2 RESEND 1/2] RDMA/srp: refuse a target that cannot receive an SRP_RSP Yehyeong Lee
@ 2026-10-26 5:54 ` Yehyeong Lee
2026-10-26 9:08 ` sashiko-bot
2026-10-26 17:16 ` [PATCH v2 RESEND 0/2] RDMA/srp: bound the receive IU the target asks for Bart Van Assche
2 siblings, 1 reply; 6+ messages in thread
From: Yehyeong Lee @ 2026-10-26 5:54 UTC (permalink / raw)
To: Bart Van Assche
Cc: Leon Romanovsky, Jason Gunthorpe, linux-rdma, linux-kernel,
stable, yhlee
srp_recv_done() syncs the receive IU with ch->max_ti_iu_len, but the IU
was mapped with iu->size. Those are the same value only until the first
reconnect. srp_cm_rep_handler() takes ch->max_ti_iu_len from every
SRP_LOGIN_RSP while it allocates the receive ring only when there is none,
and srp_rport_reconnect() keeps the ring across a reconnect, so a target
that reports a larger max_ti_iu_len the second time around makes both
ib_dma_sync_single_for_cpu() and ib_dma_sync_single_for_device() run past
the end of the mapping, which breaks the DMA API rules.
The HCA itself cannot overrun the buffer, because srp_post_recv() posts
iu->size, so sync the length that was actually mapped.
Suggested-by: Bart Van Assche <bvanassche@acm.org>
Fixes: aef9ec39c47f ("IB: Add SCSI RDMA Protocol (SRP) initiator")
Cc: stable@vger.kernel.org
Signed-off-by: Yehyeong Lee <yhlee@isslab.korea.ac.kr>
---
drivers/infiniband/ulp/srp/ib_srp.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index a85d28b95306a..159d6b6aa93e3 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -2111,7 +2111,7 @@ static void srp_recv_done(struct ib_cq *cq, struct ib_wc *wc)
return;
}
- ib_dma_sync_single_for_cpu(dev, iu->dma, ch->max_ti_iu_len,
+ ib_dma_sync_single_for_cpu(dev, iu->dma, iu->size,
DMA_FROM_DEVICE);
opcode = *(u8 *) iu->buf;
@@ -2148,7 +2148,7 @@ static void srp_recv_done(struct ib_cq *cq, struct ib_wc *wc)
break;
}
- ib_dma_sync_single_for_device(dev, iu->dma, ch->max_ti_iu_len,
+ ib_dma_sync_single_for_device(dev, iu->dma, iu->size,
DMA_FROM_DEVICE);
res = srp_post_recv(ch, iu);
^ permalink raw reply related [flat|nested] 6+ messages in thread* Re: [PATCH v2 RESEND 2/2] RDMA/srp: do not DMA-sync a receive IU past its mapped length
2026-10-26 5:54 ` [PATCH v2 RESEND 2/2] RDMA/srp: do not DMA-sync a receive IU past its mapped length Yehyeong Lee
@ 2026-10-26 9:08 ` sashiko-bot
0 siblings, 0 replies; 6+ messages in thread
From: sashiko-bot @ 2026-10-26 9:08 UTC (permalink / raw)
To: Yehyeong Lee; +Cc: linux-rdma
> srp_recv_done() syncs the receive IU with ch->max_ti_iu_len, but the IU
> was mapped with iu->size. Those are the same value only until the first
> reconnect. srp_cm_rep_handler() takes ch->max_ti_iu_len from every
> SRP_LOGIN_RSP while it allocates the receive ring only when there is none,
> and srp_rport_reconnect() keeps the ring across a reconnect, so a target
> that reports a larger max_ti_iu_len the second time around makes both
> ib_dma_sync_single_for_cpu() and ib_dma_sync_single_for_device() run past
> the end of the mapping, which breaks the DMA API rules.
>
> The HCA itself cannot overrun the buffer, because srp_post_recv() posts
> iu->size, so sync the length that was actually mapped.
>
> Suggested-by: Bart Van Assche <bvanassche@acm.org>
> Fixes: aef9ec39c47f ("IB: Add SCSI RDMA Protocol (SRP) initiator")
> Cc: stable@vger.kernel.org
> Signed-off-by: Yehyeong Lee <yhlee@isslab.korea.ac.kr>
Sashiko has reviewed this patch and found no issues.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261026055430.406487-1-yhlee@isslab.korea.ac.kr?part=2
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 RESEND 0/2] RDMA/srp: bound the receive IU the target asks for
2026-10-26 5:54 [PATCH v2 RESEND 0/2] RDMA/srp: bound the receive IU the target asks for Yehyeong Lee
2026-10-26 5:54 ` [PATCH v2 RESEND 1/2] RDMA/srp: refuse a target that cannot receive an SRP_RSP Yehyeong Lee
2026-10-26 5:54 ` [PATCH v2 RESEND 2/2] RDMA/srp: do not DMA-sync a receive IU past its mapped length Yehyeong Lee
@ 2026-10-26 17:16 ` Bart Van Assche
2 siblings, 0 replies; 6+ messages in thread
From: Bart Van Assche @ 2026-10-26 17:16 UTC (permalink / raw)
To: Yehyeong Lee
Cc: Leon Romanovsky, Jason Gunthorpe, linux-rdma, linux-kernel,
stable
On 10/25/26 10:54 PM, Yehyeong Lee wrote:
> Resending as a standalone thread; the v2 I sent earlier went out
> In-Reply-To v1 by mistake. No code changes. Apologies for the noise.
We are in the middle of the merge window so this is not the best time to
post or resend patches. Please repost after the merge window has closed.
Thanks,
Bart.
^ permalink raw reply [flat|nested] 6+ messages in thread