diff --git a/sys/dev/raid/mps/mps_user.c b/sys/dev/raid/mps/mps_user.c --- a/sys/dev/raid/mps/mps_user.c 2026-09-17 14:20:44.346607432 +0000 +++ b/sys/dev/raid/mps/mps_user.c 2026-09-17 14:20:44.362607228 +0000 @@ -1959,6 +1959,20 @@ mps_user_reg_access(struct mps_softc *sc, mps_reg_access_t *data) { int status = 0; + u_long regs_size; + + /* + * DF-4012: RegOffset arrives straight from userspace (u32) and was + * previously passed unvalidated into mps_regread()/mps_regwrite(), + * which are plain volatile loads/stores at bhandle+offset on the + * x86_64 memory bus space. A member of group operator could thus + * read and write any kernel memory in the 4 GiB window above the + * register BAR (and panic the kernel on unmapped offsets). Bound + * the offset by the actual size of the mapped register aperture. + */ + regs_size = rman_get_size(sc->mps_regs_resource); + if (data->RegOffset >= regs_size) + return (EINVAL); switch (data->Command) { /*