DragonFlyBSD Kernel Audit
DF-1676 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/dev/disk/nvme/nvme.c b/sys/dev/disk/nvme/nvme.c
--- a/sys/dev/disk/nvme/nvme.c
+++ b/sys/dev/disk/nvme/nvme.c
@@ -710,8 +710,24 @@
 		 * queue can have only one completion queue, so we can
 		 * update subq_head without locking the submission queue.
 		 */
+		if (res->tail.subq_id >= NVME_MAX_QUEUES ||
+		    sc->subqueues[res->tail.subq_id].nqe == 0) {
+			kprintf("nvme: bad subq_id %u in completion, dropping\n",
+			    res->tail.subq_id);
+			break;
+		}
 		subq = &sc->subqueues[res->tail.subq_id];
+		if (res->tail.subq_head_ptr >= subq->nqe) {
+			kprintf("nvme: bad subq_head %u in completion\n",
+			    res->tail.subq_head_ptr);
+			break;
+		}
 		subq->subq_head = res->tail.subq_head_ptr;
+		if (res->tail.cmd_id >= subq->nqe) {
+			kprintf("nvme: bad cmd_id %u in completion\n",
+			    res->tail.cmd_id);
+			break;
+		}
 		req = &subq->reqary[res->tail.cmd_id];
 
 		/*