⬢ DragonFlyBSD Kernel Audit
DF-5571 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/platform/vkernel64/x86_64/db_interface.c b/sys/platform/vkernel64/x86_64/db_interface.c
index 86c1bbd..2d55f05 100644
--- a/sys/platform/vkernel64/x86_64/db_interface.c
+++ b/sys/platform/vkernel64/x86_64/db_interface.c
@@ -166,7 +166,18 @@ kdb_trap(int type, int code, struct x86_64_saved_state *regs)
 
 	setjmp(db_global_jmpbuf);
 	db_global_jmpbuf_valid = TRUE;
-	db_active++;
+	/*
+	 * DF-5571 (twin of DF-5561 on pc64): count only the first entry.
+	 * A nested trap taken while this session is live longjmps back to
+	 * the setjmp above and would re-execute the increment, while the
+	 * abandoned outer invocation's db_active-- never runs: db_active
+	 * would leak nonzero forever and user_trap()/kern_trap()
+	 * (trap.c:366, trap.c:605) would then route *every* trap -
+	 * including ordinary user-mode traps - into trap_fatal()/
+	 * kdb_trap(), wedging the whole vkernel in ddb.
+	 */
+	if (db_active == 0)
+		db_active++;
 	vcons_set_mode(1);
 	if (ddb_mode) {
 	    cndbctl(TRUE);