hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/infiniband/sw/siw/siw_cq.c
....@@ -56,8 +56,6 @@
5656 if (READ_ONCE(cqe->flags) & SIW_WQE_VALID) {
5757 memset(wc, 0, sizeof(*wc));
5858 wc->wr_id = cqe->id;
59
- wc->status = map_cqe_status[cqe->status].ib;
60
- wc->opcode = map_wc_opcode[cqe->opcode];
6159 wc->byte_len = cqe->bytes;
6260
6361 /*
....@@ -71,10 +69,32 @@
7169 wc->wc_flags = IB_WC_WITH_INVALIDATE;
7270 }
7371 wc->qp = cqe->base_qp;
72
+ wc->opcode = map_wc_opcode[cqe->opcode];
73
+ wc->status = map_cqe_status[cqe->status].ib;
7474 siw_dbg_cq(cq,
7575 "idx %u, type %d, flags %2x, id 0x%pK\n",
7676 cq->cq_get % cq->num_cqe, cqe->opcode,
7777 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
+
7898 }
7999 WRITE_ONCE(cqe->flags, 0);
80100 cq->cq_get++;