[PATCH 1/2] RDMA/srp: refuse a target that cannot receive an SRP_RSP

From: Yehyeong Lee

Date: Sun Oct 25 2026 - 07:42:43 EST


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@xxxxxxxxxxxxxxx
Signed-off-by: Yehyeong Lee <yhlee@xxxxxxxxxxxxxxxxxx>
---
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);
--
2.43.0