DragonFlyBSD Kernel Audit
DF-0795 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/vfs/msdosfs/msdosfs_conv.c b/sys/vfs/msdosfs/msdosfs_conv.c
--- a/sys/vfs/msdosfs/msdosfs_conv.c
+++ b/sys/vfs/msdosfs/msdosfs_conv.c
@@ -1058,6 +1058,18 @@
 		memmove(slot + count, slot + WIN_CHARS, nbp->nb_len);
 	}
 
+	/*
+	 * Bound the absolute write position: the slot offset (id * WIN_CHARS)
+	 * plus the substring length (count) must not exceed the buffer size.
+	 * Without this, a malicious Win95 entry with weCnt&WIN_CNT == 20 (id=19)
+	 * and all 13 name positions non-null makes us memcpy 13 bytes at
+	 * nb_buf[247], overflowing nb_buf[256] by 4 bytes (ASCII) or 17 bytes
+	 * (KICONV).  The cumulative check above only bounds nb_len+count, not
+	 * the absolute slot offset.
+	 */
+	if (id * WIN_CHARS + count > sizeof(nbp->nb_buf))
+		return (ENAMETOOLONG);
+
 	/* Copy in the substring to its slot and update length so far. */
 	memcpy(slot, name, count);
 	nbp->nb_len = newlen;