RDMA/rtrs-srv: Fix integer underflow in process_read and process_write
Subsystems (2)
PATCH 1/1 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.
--- drivers/infiniband/ulp/rtrs/rtrs-srv.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
drivers/infiniband/ulp/rtrs/rtrs-srv.c +10 -2
@@ -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,
Signature · 1 line
2.43.0
Quoted 8 lines · Aurelien DESBRIERES
usr_lenis read from a network-supplied message field (le16_to_cpu) and used to computedata_len= off -usr_lenwithout validating thatusr_len<= off. A malicious RDMA client can sendusr_len> off causing an integer underflow, resulting indata_lenwrapping to a hugesize_tvalue which is then passed to therdma_evcallback as a memory length, leading to out-of-bounds memory access.
Quoted 8 lines
Fix by reading and validating
usr_len<= off beforertrs_srv_get_ops_ids()in bothprocess_read()andprocess_write(), ensuring the early return path acquires no reference and has no resource leak.Reported-by Aurelien DESBRIERES <[email protected]>Reviewed-by Md Haris Iqbal <[email protected]>Signed-off-by Aurelien DESBRIERES <[email protected]>Assisted-by Claude <claude-sonnet-4-6>
Quoted 51 lines
--- drivers/infiniband/ulp/rtrs/rtrs-srv.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)drivers/infiniband/ulp/rtrs/rtrs-srv.c +10
-3@@ -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, --2.43.0
Quoted 11 lines · Aurelien DESBRIERES
usr_lenis read from a network-supplied message field (le16_to_cpu) and used to computedata_len= off -usr_lenwithout validating thatusr_len<= off. A malicious RDMA client can sendusr_len> off causing an integer underflow, resulting indata_lenwrapping to a hugesize_tvalue which is then passed to therdma_evcallback as a memory length, leading to out-of-bounds memory access.Fix by reading and validating
usr_len<= off beforertrs_srv_get_ops_ids()in bothprocess_read()andprocess_write(), ensuring the early return path acquires no reference and has no resource leak.
Quoted 8 lines
Reported-by Aurelien DESBRIERES <[email protected]>Reviewed-by Md Haris Iqbal <[email protected]>Signed-off-by Aurelien DESBRIERES <[email protected]>Assisted-by Claude <claude-sonnet-4-6>Acked-by Md Haris Iqbal <[email protected]>--- drivers/infiniband/ulp/rtrs/rtrs-srv.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
Applied, thanks
Jason