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