DF-5024 / fix.diff
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); |