⬢ DragonFlyBSD Kernel Audit
DF-3818 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/raid/mpr/mpr.c
+++ b/sys/dev/raid/mpr/mpr.c
@@ -2714,8 +2714,15 @@
 	 * possible NVMe QDepth.
 	 */
 	prp_page_info = mpr_alloc_prp_page(sc);
-	KASSERT(prp_page_info != NULL, ("%s: There are no PRP Pages left to be "
-	    "used for building a native NVMe SGL.\n", __func__));
+	if (prp_page_info == NULL) {
+		/* Pool exhausted (num_reqs can exceed NVME_QDEPTH).
+		 * Do not dereference NULL; the firmware will reject the
+		 * malformed request.  Proper fix: return int and fail the
+		 * command up the stack. */
+		mpr_dprint(sc, MPR_ERROR, "%s: no PRP pages left\n",
+		    __func__);
+		return;
+	}
 	prp_page = (uint64_t *)prp_page_info->prp_page;
 	prp_page_phys = (uint64_t *)(uintptr_t)prp_page_info->prp_page_busaddr;
 
@@ -2986,8 +2993,12 @@
 	 * possible NVMe QDepth.
 	 */
 	prp_page_info = mpr_alloc_prp_page(sc);
-	KASSERT(prp_page_info != NULL, ("%s: There are no PRP Pages left to be "
-	    "used for building a native NVMe SGL.\n", __func__));
+	if (prp_page_info == NULL) {
+		/* Fall back to a normal IEEE SGL instead of panicking. */
+		mpr_dprint(sc, MPR_ERROR, "%s: no PRP pages left, using "
+		    "IEEE SGL\n", __func__);
+		return (1);
+	}
 	curr_buff = (uint32_t *)prp_page_info->prp_page;
 	msg_phys = (uint64_t *)(uintptr_t)prp_page_info->prp_page_busaddr;