DragonFlyBSD Kernel Audit
DF-0791 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/vfs/ntfs/ntfs_subr.c b/sys/vfs/ntfs/ntfs_subr.c
--- a/sys/vfs/ntfs/ntfs_subr.c
+++ b/sys/vfs/ntfs/ntfs_subr.c
@@ -1007,6 +1007,24 @@
 		if (iep->ie_flag & NTFS_IEFLAG_SUBNODE) {
 			dprintf(("ntfs_ntlookupfile: diving\n"));
 
+			/*
+			 * DF-0791: the subnode VCN lives in the last
+			 * sizeof(cn_t) bytes of the index entry.  Validate
+			 * that the entry (and thus the trailing VCN) actually
+			 * fits inside the valid data region before dereferencing
+			 * it, otherwise a malformed image with a bogus reclen
+			 * makes us read 8 bytes off the end of rdbuf.
+			 */
+			if (iep->reclen < sizeof(cn_t) ||
+			    aoff > rdsize ||
+			    (u_int32_t)iep->reclen > rdsize - aoff) {
+				kprintf("ntfs_ntlookupfile: malformed index "
+					"entry (reclen %u, aoff %u, rdsize %u)\n",
+					iep->reclen, aoff, rdsize);
+				error = EINVAL;
+				goto fail;
+			}
+
 			cn = *(cn_t *) (rdbuf + aoff +
 					iep->reclen - sizeof(cn_t));
 			rdsize = blsize;