⬢ DragonFlyBSD Kernel Audit
DF-5678 / fix.diff
← back to finding ↓ download raw
--- a/sys/libprop/prop_array.c
+++ b/sys/libprop/prop_array.c
@@ -645,7 +645,15 @@
 		goto out;
 	}
 
-	_PROP_ASSERT(idx < pa->pa_count);
+	/*
+	 * Real bounds check, not just an INVARIANTS-only assert: with the
+	 * assert compiled out (kernel built without INVARIANTS), an
+	 * idx > pa->pa_count used to fall through to an out-of-bounds
+	 * read/write of pa_array[] plus prop_object_release() of the OOB
+	 * value.  prop_array_get() already real-checks; mirror it here.
+	 */
+	if (idx > pa->pa_count)
+		goto out;
 
 	opo = pa->pa_array[idx];
 	_PROP_ASSERT(opo != NULL);
@@ -698,7 +706,16 @@
 
 	_PROP_RWLOCK_WRLOCK(pa->pa_rwlock);
 
-	_PROP_ASSERT(idx < pa->pa_count);
+	/*
+	 * Same as prop_array_set(): enforce the index bound for real --
+	 * the old assert-only check left an OOB read of pa_array[idx]
+	 * followed by prop_object_release() of the garbage pointer on
+	 * kernels built without INVARIANTS.
+	 */
+	if (idx >= pa->pa_count) {
+		_PROP_RWLOCK_UNLOCK(pa->pa_rwlock);
+		return;
+	}
 
 	/* XXX Should this be a _PROP_ASSERT()? */
 	if (prop_array_is_immutable(pa)) {