diff --git a/sys/bus/mmc/mmc_subr.c b/sys/bus/mmc/mmc_subr.c index a41ce59..358a7c5 100644 --- a/sys/bus/mmc/mmc_subr.c +++ b/sys/bus/mmc/mmc_subr.c @@ -155,7 +155,14 @@ mmc_switch(device_t brdev, device_t reqdev, uint16_t rca, uint8_t set, struct mmc_command cmd; int err; - KASSERT(timeout != 0, ("%s: no timeout", __func__)); + /* + * The timeout originates from card-controlled EXT_CSD data + * (EXT_CSD[EXT_CSD_GEN_CMD6_TIME], see mmc.c) and must not be + * trusted: a crafted or mis-programmed card reporting 0 must not + * take an INVARIANTS kernel down at enumeration time. + */ + if (timeout == 0) + timeout = 500 * 1000; /* 500 ms, as defaulted in mmc.c */ memset(&cmd, 0, sizeof(cmd)); cmd.opcode = MMC_SWITCH_FUNC; @@ -184,7 +191,14 @@ mmc_switch_status(device_t brdev, device_t reqdev, uint16_t rca, u_int timeout) int err; uint32_t status; - KASSERT(timeout != 0, ("%s: no timeout", __func__)); + /* + * The timeout originates from card-controlled EXT_CSD data + * (EXT_CSD[EXT_CSD_GEN_CMD6_TIME], see mmc.c) and must not be + * trusted: a crafted or mis-programmed card reporting 0 must not + * take an INVARIANTS kernel down at enumeration time. + */ + if (timeout == 0) + timeout = 500 * 1000; /* 500 ms, as defaulted in mmc.c */ /* * Note that when using a R1B response in mmc_switch(), bridges of diff --git a/sys/bus/mmc/mmc.c b/sys/bus/mmc/mmc.c index cf05140..d0dc879 100644 --- a/sys/bus/mmc/mmc.c +++ b/sys/bus/mmc/mmc.c @@ -1662,6 +1662,8 @@ mmc_discover_cards(struct mmc_softc *sc) if (ivar->csd.spec_vers >= 6) { ivar->cmd6_time = 10 * ivar->raw_ext_csd[EXT_CSD_GEN_CMD6_TIME]; + if (ivar->cmd6_time == 0) + ivar->cmd6_time = 500 * 1000; } /* Find max supported bus width. */ ivar->bus_width = mmc_test_bus_width(sc);