DF-2398 / fix.diff
--- a/sys/dev/agp/agp.c +++ b/sys/dev/agp/agp.c @@ -516,16 +516,21 @@ return EINVAL; } - /* Do some sanity checks first. */ - if (offset < 0 - || (offset & (AGP_PAGE_SIZE - 1)) != 0 - || offset + mem->am_size > AGP_GET_APERTURE(dev)) { - device_printf(dev, "binding memory at bad offset %#x,%#x,%#x\n", - (int) offset, (int)mem->am_size, - (int)AGP_GET_APERTURE(dev)); - kprintf("Check BIOS's aperature size vs X\n"); - lockmgr(&sc->as_lock, LK_RELEASE); - return EINVAL; + /* Do some sanity checks first. Subtractive form so + * offset + am_size cannot wrap around 64 bits (DF-2398). */ + { + u_int32_t aperture = AGP_GET_APERTURE(dev); + + if ((offset & (AGP_PAGE_SIZE - 1)) != 0 + || mem->am_size > aperture + || offset > aperture - mem->am_size) { + device_printf(dev, "binding memory at bad offset %#jx,%#x,%#x\n", + (uintmax_t)offset, (int)mem->am_size, + (int)aperture); + kprintf("Check BIOS's aperature size vs X\n"); + lockmgr(&sc->as_lock, LK_RELEASE); + return EINVAL; + } } /* |