.. | .. |
---|
56 | 56 | if (READ_ONCE(cqe->flags) & SIW_WQE_VALID) { |
---|
57 | 57 | memset(wc, 0, sizeof(*wc)); |
---|
58 | 58 | wc->wr_id = cqe->id; |
---|
59 | | - wc->status = map_cqe_status[cqe->status].ib; |
---|
60 | | - wc->opcode = map_wc_opcode[cqe->opcode]; |
---|
61 | 59 | wc->byte_len = cqe->bytes; |
---|
62 | 60 | |
---|
63 | 61 | /* |
---|
.. | .. |
---|
71 | 69 | wc->wc_flags = IB_WC_WITH_INVALIDATE; |
---|
72 | 70 | } |
---|
73 | 71 | wc->qp = cqe->base_qp; |
---|
| 72 | + wc->opcode = map_wc_opcode[cqe->opcode]; |
---|
| 73 | + wc->status = map_cqe_status[cqe->status].ib; |
---|
74 | 74 | siw_dbg_cq(cq, |
---|
75 | 75 | "idx %u, type %d, flags %2x, id 0x%pK\n", |
---|
76 | 76 | cq->cq_get % cq->num_cqe, cqe->opcode, |
---|
77 | 77 | cqe->flags, (void *)(uintptr_t)cqe->id); |
---|
| 78 | + } else { |
---|
| 79 | + /* |
---|
| 80 | + * A malicious user may set invalid opcode or |
---|
| 81 | + * status in the user mmapped CQE array. |
---|
| 82 | + * Sanity check and correct values in that case |
---|
| 83 | + * to avoid out-of-bounds access to global arrays |
---|
| 84 | + * for opcode and status mapping. |
---|
| 85 | + */ |
---|
| 86 | + u8 opcode = cqe->opcode; |
---|
| 87 | + u16 status = cqe->status; |
---|
| 88 | + |
---|
| 89 | + if (opcode >= SIW_NUM_OPCODES) { |
---|
| 90 | + opcode = 0; |
---|
| 91 | + status = SIW_WC_GENERAL_ERR; |
---|
| 92 | + } else if (status >= SIW_NUM_WC_STATUS) { |
---|
| 93 | + status = SIW_WC_GENERAL_ERR; |
---|
| 94 | + } |
---|
| 95 | + wc->opcode = map_wc_opcode[opcode]; |
---|
| 96 | + wc->status = map_cqe_status[status].ib; |
---|
| 97 | + |
---|
78 | 98 | } |
---|
79 | 99 | WRITE_ONCE(cqe->flags, 0); |
---|
80 | 100 | cq->cq_get++; |
---|