DragonFlyBSD Kernel Audit
DF-3037 / fix.diff
← back to finding ↓ download raw
--- a/sys/vfs/msdosfs/msdosfs_lookup.c
+++ b/sys/vfs/msdosfs/msdosfs_lookup.c
@@ -798,6 +798,7 @@
 	struct denode *dep;
 	struct buf *bp = NULL;
 	int error = 0;
+	int depth = 0;
 
 	dep = target;
 	if ((target->de_Attributes & ATTR_DIRECTORY) == 0 ||
@@ -820,6 +821,19 @@
 		goto out;
 
 	for (;;) {
+		/*
+		 * DF-3037: a corrupt or crafted filesystem may contain a
+		 * cycle in the ".." chain.  Without a bound this walk
+		 * spins forever on cached buffers/denodes and wedges
+		 * rename(2) (and the whole system) until reboot.  A
+		 * legitimate ancestor chain is bounded by the
+		 * namei-reachable path depth (PATH_MAX components), far
+		 * below this cap.
+		 */
+		if (++depth > 4096) {
+			error = EINVAL;
+			break;
+		}
 		if ((dep->de_Attributes & ATTR_DIRECTORY) == 0) {
 			error = ENOTDIR;
 			break;