⬢ DragonFlyBSD Kernel Audit
DF-5128 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/drm/include/linux/scatterlist.h
+++ b/sys/dev/drm/include/linux/scatterlist.h
@@ -259,10 +259,24 @@
 
 	++iter->sg_pgoffset;
 	while (iter->sg_pgoffset >= pgcount) {
+		/*
+		 * Hard-stop once the caller's entry budget (nents) is
+		 * exhausted.  The old `--maxents ... == 0' test left
+		 * iter->sg pointing at the out-of-budget entry and then
+		 * underflowed the unsigned counter to UINT_MAX, permanently
+		 * disarming the budget: iteration then ran to the physical
+		 * SG_END of the table (across chained chunks), processing
+		 * entries the caller never declared.  Linux semantics
+		 * (__sg_page_iter_next) stop at nents.
+		 */
+		if (iter->maxents <= 1) {
+			iter->sg = NULL;
+			return;
+		}
 		iter->sg_pgoffset -= pgcount;
 		sg = sg_next(sg);
 		--iter->maxents;
-		if (sg == NULL || iter->maxents == 0)
+		if (sg == NULL)
 			break;
 		pgcount = (sg->offset + sg->length + PAGE_MASK) >> PAGE_SHIFT;
 	}