DragonFlyBSD Kernel Audit
DF-1126 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/dev/disk/isp/isp.c b/sys/dev/disk/isp/isp.c
--- a/sys/dev/disk/isp/isp.c
+++ b/sys/dev/disk/isp/isp.c
@@ -5114,11 +5114,15 @@
 			if (r < 0) {
 				goto read_again;
 			}
-			/*
-			 * If somebody updated the output pointer, then reset
-			 * optr to be one more than the updated amount.
-			 */
-			while (tsto != oop) {
+		/*
+		 * If somebody updated the output pointer, then reset
+		 * optr to be one more than the updated amount. Use 'if'
+		 * (not 'while') because the body never modifies tsto or
+		 * oop -- a 'while' here is an infinite loop whenever
+		 * isp_target_notify advanced tsto via a long-IU
+		 * continuation (isp_target.c long-IU path).
+		 */
+			if (tsto != oop) {
 				optr = ISP_NXT_QENTRY(tsto,
 				    RESULT_QUEUE_LEN(isp));
 			}