DF-1040 / fix.diff
diff --git a/sys/bus/pccard/pccard_cis.c b/sys/bus/pccard/pccard_cis.c --- a/sys/bus/pccard/pccard_cis.c +++ b/sys/bus/pccard/pccard_cis.c @@ -409,6 +409,27 @@ goto done; } + /* + * Validate the link target before dereferencing it. + * longlink_addr and mfc[].addr are full 32-bit card-supplied + * values; without this check a malicious card makes us + * bus_space_read_1() at mult*ptr far outside the CIS mapping + * and page-faults the kernel (DF-1040). Compare ptr against + * the window size in index units to avoid multiplication + * overflow on 32-bit platforms (where mult*ptr could wrap to + * ~0). The coarse first check also catches ptr values so + * large that ptr+4 would itself wrap a 32-bit unsigned. + * We need room for the 5-byte LINKTARGET header + * (code, length, "C","I","S"). + */ + if (tuple.ptr >= PCCARD_CIS_SIZE || + tuple.ptr + 4 >= PCCARD_CIS_SIZE / tuple.mult) { + device_printf(dev, "CIS longlink/MFC target %lx " + "out of bounds (mult=%lx)\n", (u_long)tuple.ptr, + (u_long)tuple.mult); + continue; + } + /* make sure that the link is valid */ tuple.code = pccard_cis_read_1(&tuple, tuple.ptr); if (tuple.code != CISTPL_LINKTARGET) { |