⬢ DragonFlyBSD Kernel Audit
DF-5024 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/dev/netif/ath/ath_dfs/null/dfs_null.c b/sys/dev/netif/ath/ath_dfs/null/dfs_null.c
--- a/sys/dev/netif/ath/ath_dfs/null/dfs_null.c
+++ b/sys/dev/netif/ath/ath_dfs/null/dfs_null.c
@@ -275,10 +275,22 @@
 		default:
 			error = EINVAL;
 	}
-	if (outsize < ad->ad_out_size)
-		ad->ad_out_size = outsize;
-	if (outdata && copyout(outdata, ad->ad_out_data, ad->ad_out_size))
-		error = EFAULT;
+	/*
+	 * Only publish the result buffer when the command actually
+	 * succeeded.  On the error paths (unknown id -> default:, or a
+	 * short DFS_SET_THRESH input) outdata is an UNINITIALIZED M_TEMP
+	 * allocation and must never be copied out -- otherwise the full
+	 * attacker-sized uninitialized kernel heap block is disclosed to
+	 * userspace.  Mirrors the guard in ath_ioctl_diag()
+	 * (if_ath_ioctl.c:214-222).
+	 */
+	if (error == 0) {
+		if (outsize < ad->ad_out_size)
+			ad->ad_out_size = outsize;
+		if (outdata && copyout(outdata, ad->ad_out_data,
+		    ad->ad_out_size))
+			error = EFAULT;
+	}
 bad:
 	if ((ad->ad_id & ATH_DIAG_IN) && indata != NULL)
 		kfree(indata, M_TEMP);