DragonFlyBSD Kernel Audit
DF-0790 / 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
@@ -194,6 +194,25 @@
 	nextaalp = NULL;
 
 	for(; len > 0; aalp = nextaalp) {
+		/* DF-0790: validate the entry before dereferencing any field
+		 * or advancing the walk. A crafted $ATTRIBUTE_LIST can have
+		 * reclen == 0 (infinite loop, since len never decreases and
+		 * NTFS_NEXTREC returns the same pointer) or reclen > len
+		 * (size_t underflow on `len -= reclen`, then the next
+		 * iteration dereferences nextaalp == NULL -> panic).
+		 * Require the fixed entry header to fit in the remaining
+		 * buffer and reclen to be sane. The minimum entry size is
+		 * the fixed header without the variable name tail
+		 * (al_name[1] is a flexible-array placeholder). */
+		if (len < sizeof(struct attr_attrlist) - sizeof(u_int16_t) ||
+		    aalp->reclen < sizeof(struct attr_attrlist) - sizeof(u_int16_t) ||
+		    aalp->reclen > len) {
+			error = EINVAL;
+			kprintf("ntfs_ntvattrget: malformed attrlist entry "
+			       "(reclen %u, len %zu)\n", aalp->reclen, len);
+			goto out;
+		}
+
 		dprintf(("ntfs_ntvattrget: " \
 			 "attrlist: ino: %d, attr: 0x%x, vcn: %d\n", \
 			 aalp->al_inumber, aalp->al_type, \