⬢ DragonFlyBSD Kernel Audit
DF-4554 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/drm/amd/amdgpu/amdgpu_debugfs.c
+++ b/sys/dev/drm/amd/amdgpu/amdgpu_debugfs.c
@@ -715,14 +715,23 @@
 	mutex_lock(&adev->grbm_idx_mutex);
 	amdgpu_gfx_select_se_sh(adev, se, sh, cu);
 
-	if (bank == 0) {
-		if (adev->gfx.funcs->read_wave_vgprs)
-			adev->gfx.funcs->read_wave_vgprs(adev, simd, wave, thread, offset, size>>2, data);
-	} else {
-		if (adev->gfx.funcs->read_wave_sgprs)
-			adev->gfx.funcs->read_wave_sgprs(adev, simd, wave, offset, size>>2, data);
+	/* DF-4554: never copy out an unfilled buffer - a missing bank
+	 * callback must fail the read instead of disclosing uninitialized
+	 * heap. */
+	if ((bank == 0 && !adev->gfx.funcs->read_wave_vgprs) ||
+	    (bank != 0 && !adev->gfx.funcs->read_wave_sgprs)) {
+		amdgpu_gfx_select_se_sh(adev, 0xFFFFFFFF, 0xFFFFFFFF,
+					0xFFFFFFFF);
+		mutex_unlock(&adev->grbm_idx_mutex);
+		kfree(data);
+		return -EINVAL;
 	}
 
+	if (bank == 0)
+		adev->gfx.funcs->read_wave_vgprs(adev, simd, wave, thread, offset, size>>2, data);
+	else
+		adev->gfx.funcs->read_wave_sgprs(adev, simd, wave, offset, size>>2, data);
+
 	amdgpu_gfx_select_se_sh(adev, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
 	mutex_unlock(&adev->grbm_idx_mutex);