DF-1243 / fix.diff
diff --git a/sys/dev/raid/mrsas/mrsas.c b/sys/dev/raid/mrsas/mrsas.c index 38a2742c..ee7168bb 100644 --- a/sys/dev/raid/mrsas/mrsas.c +++ b/sys/dev/raid/mrsas/mrsas.c @@ -3307,6 +3307,20 @@ static int mrsas_get_pd_list(struct mrsas_softc *sc) if (retcode == 0 && pd_list_mem->count < pd_count) { memset(sc->local_pd_list, 0, MRSAS_MAX_PD * sizeof(struct mrsas_pd_list)); for (pd_index = 0; pd_index < pd_list_mem->count; pd_index++) { + /* + * deviceId is a firmware-supplied u16 (0..65535) but + * local_pd_list has only MRSAS_MAX_PD (256) entries. An + * unchecked deviceId >= 256 corrupts ld_ids, the ev_tq + * taskqueue pointer, reset_flags, and load_balance_info + * that follow in the softc. Skip out-of-range devices. + */ + if (pd_addr->deviceId >= MRSAS_MAX_PD) { + device_printf(sc->mrsas_dev, + "PD deviceId %u out of range (max %d), skipping\n", + pd_addr->deviceId, MRSAS_MAX_PD); + pd_addr++; + continue; + } sc->local_pd_list[pd_addr->deviceId].tid = pd_addr->deviceId; sc->local_pd_list[pd_addr->deviceId].driveType = pd_addr->scsiDevType; sc->local_pd_list[pd_addr->deviceId].driveState = MR_PD_STATE_SYSTEM; |