When generating an RDMA READ response (SIW_OP_READ_RESPONSE), siw_check_sgl_tx() unconditionally passes 0 as the required permission mask: /* Reference memory to be tx'd w/o checking access for LOCAL_READ */ rv = siw_check_sgl_tx(qp->pd, wqe, 0); Because perms is 0, siw_check_mem()'s authorization test: if ((mem->perms & perms) < perms) evaluates to (mem->perms & 0) < 0, which is always false. Consequently, an untrusted remote peer can issue an RDMA Read targeting any valid STag in the Protection Domain, even if the memory was registered strictly as write-only (IB_ACCESS_REMOTE_WRITE) without IB_ACCESS_REMOTE_READ. Enforce that the target memory region was granted IB_ACCESS_REMOTE_READ when answering SIW_OP_READ_RESPONSE work queue entries, while preserving perms = 0 for standard local sends. Fixes: b9be6f18cf9e ("rdma/siw: transmit path") Cc: stable@vger.kernel.org Signed-off-by: Haitam Lazaar --- drivers/infiniband/sw/siw/siw_qp_tx.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/infiniband/sw/siw/siw_qp_tx.c b/drivers/infiniband/sw/siw/siw_qp_tx.c index f7dd32c6e5ba..9e652585f904 100644 --- a/drivers/infiniband/sw/siw/siw_qp_tx.c +++ b/drivers/infiniband/sw/siw/siw_qp_tx.c @@ -810,12 +810,17 @@ static int siw_qp_sq_proc_tx(struct siw_qp *qp, struct siw_wqe *wqe) if (tx_type(wqe) != SIW_OP_READ && tx_type(wqe) != SIW_OP_READ_LOCAL_INV) { + enum ib_access_flags perms = 0; + /* - * Reference memory to be tx'd w/o checking - * access for LOCAL_READ permission, since - * not defined in RDMA core. + * Local READ permission doesn't exist in RDMA core. + * A READ RESPONSE source is read by the remote peer, + * so it must be checked for REMOTE_READ permission. */ - rv = siw_check_sgl_tx(qp->pd, wqe, 0); + if (tx_type(wqe) == SIW_OP_READ_RESPONSE) + perms = IB_ACCESS_REMOTE_READ; + + rv = siw_check_sgl_tx(qp->pd, wqe, perms); if (rv < 0) { if (tx_type(wqe) == SIW_OP_READ_RESPONSE) --