⬢ DragonFlyBSD Kernel Audit
DF-3333 / fix.diff
← back to finding ↓ download raw
--- a/sys/net/netmap/netmap.c
+++ b/sys/net/netmap/netmap.c
@@ -907,7 +907,9 @@
 	/* skip past packets that userspace has released */
 	j = kring->nr_hwcur;
 	if (resvd > 0) {
-		if (resvd + ring->avail >= lim + 1) {
+		/* DF-3333: reject out-of-range values instead of a sum that
+		 * wraps (resvd=0xffffffff, avail=1 used to pass this check) */
+		if (resvd > lim || ring->avail > lim) {
 			D("XXX invalid reserve/avail %d %d", resvd, ring->avail);
 			ring->reserved = resvd = 0; // XXX panic...
 		}
--- a/sys/net/netmap/netmap_kern.h
+++ b/sys/net/netmap/netmap_kern.h
@@ -543,6 +543,9 @@
 	uint32_t pos = k->nr_hwcur + k->nr_hwavail;
 	if (pos >= k->nkr_num_slots)
 		pos -= k->nkr_num_slots;
+	if (pos >= k->nkr_num_slots)	/* DF-3333: corrupted hwcur/hwavail
+					 * can make one subtract not enough */
+		pos %= k->nkr_num_slots;
 #if 0
 	if (pos >= k->nkr_num_slots ||
 		k->nkr_hwlease >= k->nkr_num_slots ||