DragonFlyBSD Kernel Audit
DF-0932 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/vfs/ntfs/ntfs_compr.c b/sys/vfs/ntfs/ntfs_compr.c
--- a/sys/vfs/ntfs/ntfs_compr.c
+++ b/sys/vfs/ntfs/ntfs_compr.c
@@ -78,6 +78,23 @@
 				}
 				boff = -1 - (GET_UINT16(cbuf + cpos) >> dshift);
 				blen = 3 + (GET_UINT16(cbuf + cpos) & lmask);
+				/*
+				 * DF-0932: reject malformed back-references whose displacement
+				 * would read before the start of the output buffer.  Without
+				 * this check a crafted LZNT1 stream can drive pos + boff < 0,
+				 * causing buf[pos + boff] to read kernel heap memory preceding
+				 * the buf (uup) allocation; the bytes are then copied into uup
+				 * and shipped to the reader via uiomove (ntfs_subr.c:1723) --
+				 * an unprivileged kernel heap info leak reachable by any reader
+				 * of a mounted NTFS compressed file.
+				 *
+				 * Returning 0 here signals "malformed block" to ntfs_uncompunit
+				 * (the only caller), which already maps new == 0 to EINVAL.
+				 * ntfs_uncompblock otherwise returns len + 3 (>= 3), so 0 is an
+				 * unambiguous error sentinel.
+				 */
+				if (pos + boff < 0)
+					return (0);
 				for (j = 0; (j < blen) && (pos < NTFS_COMPBLOCK_SIZE); j++) {
 					buf[pos] = buf[pos + boff];
 					pos++;