⬢ DragonFlyBSD Kernel Audit
DF-4020 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/dev/raid/mpr/mpr_user.c b/sys/dev/raid/mpr/mpr_user.c
index 767a4a1a..711f3641 100644
--- a/sys/dev/raid/mpr/mpr_user.c
+++ b/sys/dev/raid/mpr/mpr_user.c
@@ -2178,6 +2178,21 @@ static int
 mpr_user_reg_access(struct mpr_softc *sc, mpr_reg_access_t *data)
 {
 	int	status = 0;
+	u_long	regs_size;
+
+	/*
+	 * DF-4020 (twin of DF-4012 on mps): RegOffset arrives straight from
+	 * userspace (u32, mpr_ioctl.h:343) and was previously passed
+	 * unvalidated into mpr_regread()/mpr_regwrite(), which are plain
+	 * volatile loads/stores at bhandle+offset on the x86_64 memory bus
+	 * space (mprvar.h:496-506).  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->mpr_regs_resource);
+	if (data->RegOffset >= regs_size)
+		return (EINVAL);
 
 	switch (data->Command) {
 		/*