DragonFlyBSD Kernel Audit
DF-1358 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/dev/raid/amr/amr.c b/sys/dev/raid/amr/amr.c
--- a/sys/dev/raid/amr/amr.c
+++ b/sys/dev/raid/amr/amr.c
@@ -2092,7 +2092,7 @@
     int		worked, i;
     u_int32_t	outd;
     u_int8_t	nstatus;
-    u_int8_t	completed[46];
+    u_int8_t	completed[AMR_MSG_MAX_COMPLETIONS];
 
     debug_called(3);
 
@@ -2108,6 +2108,11 @@
 	    DELAY(1);
 	sc->amr_mailbox->mb_nstatus = 0xff;
 
+	/* Defend against buggy or hostile firmware reporting more completions
+	 * than the mailbox can hold (mb_completed[] has 46 entries). */
+	if (nstatus > AMR_MSG_MAX_COMPLETIONS)
+	    nstatus = AMR_MSG_MAX_COMPLETIONS;
+
 	/* wait until fw wrote out all completions */
 	for (i = 0; i < nstatus; i++) {
 	    while ((completed[i] = sc->amr_mailbox->mb_completed[i]) == 0xff)

diff --git a/sys/dev/raid/amr/amrreg.h b/sys/dev/raid/amr/amrreg.h
--- a/sys/dev/raid/amr/amrreg.h
+++ b/sys/dev/raid/amr/amrreg.h
@@ -79,6 +79,7 @@
 #define AMR_NSEG		26
 
 #define AMR_MAXCMD		255		/* ident = 0 not allowed */
+#define AMR_MSG_MAX_COMPLETIONS	46		/* max completions in mailbox */
 #define AMR_LIMITCMD		120		/* maximum count of outstanding commands */
 #define AMR_MAXLD      		40