DragonFlyBSD Kernel Audit
DF-0864 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/vfs/hpfs/hpfs_subr.c b/sys/vfs/hpfs/hpfs_subr.c
--- a/sys/vfs/hpfs/hpfs_subr.c
+++ b/sys/vfs/hpfs/hpfs_subr.c
@@ -176,6 +176,16 @@
 {
 	int i, res;
 
+	/*
+	 * DF-0864: cp (dep->de_cpid) is an unchecked u_int8_t read verbatim
+	 * from the on-disk directory entry.  hpm_cpdblk has sp_cpinum entries
+	 * (allocated in hpfs_cpinit); an out-of-range cp drives an OOB read
+	 * in the hpfs_toupper macro (sys/vfs/hpfs/hpfs_subr.h).  Clamp to the
+	 * valid range before the comparison loop.
+	 */
+	if (cp >= hpmp->hpm_sp.sp_cpinum)
+		cp = 0;
+
 	for (i = 0; i < ulen && i < dlen; i++) {
 		res = hpfs_toupper(hpmp, hpfs_u2d(hpmp, uname[i]), cp) - 
 		      hpfs_toupper(hpmp, dname[i], cp);
@@ -197,6 +207,12 @@
 {
 	int i, res;
 
+	/* DF-0864: same bounds check as hpfs_cmpfname for str1cp / str2cp. */
+	if (str1cp >= hpmp->hpm_sp.sp_cpinum)
+		str1cp = 0;
+	if (str2cp >= hpmp->hpm_sp.sp_cpinum)
+		str2cp = 0;
+
 	for (i = 0; i < str1len && i < str2len; i++) {
 		res = (int)hpfs_toupper(hpmp, ((u_char *)str1)[i], str1cp) - 
 		      (int)hpfs_toupper(hpmp, ((u_char *)str2)[i], str2cp);