mirror of
https://github.com/torvalds/linux.git
synced 2026-07-28 10:09:10 +02:00
RDMA/rtrs-srv: Fix integer underflow in process_read and process_write
usr_len is read from a network-supplied message field (le16_to_cpu) and used to compute data_len = off - usr_len without validating that usr_len <= off. A malicious RDMA client can send usr_len > off causing an integer underflow, resulting in data_len wrapping to a huge size_t value which is then passed to the rdma_ev callback as a memory length, leading to out-of-bounds memory access. Fix by reading and validating usr_len <= off before rtrs_srv_get_ops_ids() in both process_read() and process_write(), ensuring the early return path acquires no reference and has no resource leak. Link: https://patch.msgid.link/r/20260608134802.5019-1-aurelien@hackers.camp Reported-by: Aurelien DESBRIERES <aurelien@hackers.camp> Reviewed-by: Md Haris Iqbal <haris.iqbal@ionos.com> Signed-off-by: Aurelien DESBRIERES <aurelien@hackers.camp> Assisted-by: Claude <claude-sonnet-4-6> Acked-by: Md Haris Iqbal <haris.iqbal@ionos.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
This commit is contained in:
parent
c9bf47d205
commit
54bf38b27a
|
|
@ -1059,6 +1059,11 @@ static void process_read(struct rtrs_srv_con *con,
|
|||
"Processing read request failed, invalid message\n");
|
||||
return;
|
||||
}
|
||||
usr_len = le16_to_cpu(msg->usr_len);
|
||||
if (usr_len > off) {
|
||||
pr_debug("rtrs-srv: Invalid usr_len %zu > off %u\n", usr_len, off);
|
||||
return;
|
||||
}
|
||||
rtrs_srv_get_ops_ids(srv_path);
|
||||
rtrs_srv_update_rdma_stats(srv_path->stats, off, READ);
|
||||
id = srv_path->ops_ids[buf_id];
|
||||
|
|
@ -1066,7 +1071,6 @@ static void process_read(struct rtrs_srv_con *con,
|
|||
id->dir = READ;
|
||||
id->msg_id = buf_id;
|
||||
id->rd_msg = msg;
|
||||
usr_len = le16_to_cpu(msg->usr_len);
|
||||
data_len = off - usr_len;
|
||||
data = page_address(srv->chunks[buf_id]);
|
||||
ret = ctx->ops.rdma_ev(srv->priv, id, data, data_len,
|
||||
|
|
@ -1112,6 +1116,11 @@ static void process_write(struct rtrs_srv_con *con,
|
|||
rtrs_srv_state_str(srv_path->state));
|
||||
return;
|
||||
}
|
||||
usr_len = le16_to_cpu(req->usr_len);
|
||||
if (usr_len > off) {
|
||||
pr_debug("rtrs-srv: Invalid usr_len %zu > off %u\n", usr_len, off);
|
||||
return;
|
||||
}
|
||||
rtrs_srv_get_ops_ids(srv_path);
|
||||
rtrs_srv_update_rdma_stats(srv_path->stats, off, WRITE);
|
||||
id = srv_path->ops_ids[buf_id];
|
||||
|
|
@ -1119,7 +1128,6 @@ static void process_write(struct rtrs_srv_con *con,
|
|||
id->dir = WRITE;
|
||||
id->msg_id = buf_id;
|
||||
|
||||
usr_len = le16_to_cpu(req->usr_len);
|
||||
data_len = off - usr_len;
|
||||
data = page_address(srv->chunks[buf_id]);
|
||||
ret = ctx->ops.rdma_ev(srv->priv, id, data, data_len,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user