fix.diff — DF-4980 (authored after verification; never applied to sys/) 1) Clamp the untrusted VBIOS-driven scratch size to the driver's own default. 2) Stop ignoring the allocation error in amdgpu_atombios_init() (both the atomfirmware and legacy variants). diff --git a/sys/dev/drm/amd/amdgpu/amdgpu_atomfirmware.c b/sys/dev/drm/amd/amdgpu/amdgpu_atomfirmware.c --- a/sys/dev/drm/amd/amdgpu/amdgpu_atomfirmware.c +++ b/sys/dev/drm/amd/amdgpu/amdgpu_atomfirmware.c @@ -100,6 +100,15 @@ int amdgpu_atomfirmware_allocate_fb_scratch(struct amdgpu_device *adev) usage_bytes = le16_to_cpu(firmware_usage->used_by_driver_in_kb) << 10; } } + /* + * used_by_driver_in_kb is untrusted VBIOS data. Don't let a garbage + * table drive a huge kernel allocation (and, on allocators that can + * return NULL, don't leave ctx->scratch NULL with the error ignored + * by the caller). Anything beyond the driver's own 20 KB default is + * nonsense. + */ + if (usage_bytes > 20 * 1024) + usage_bytes = 20 * 1024; ctx->scratch_size_bytes = 0; if (usage_bytes == 0) usage_bytes = 20 * 1024; diff --git a/sys/dev/drm/amd/amdgpu/amdgpu_atombios.c b/sys/dev/drm/amd/amdgpu/amdgpu_atombios.c --- a/sys/dev/drm/amd/amdgpu/amdgpu_atombios.c +++ b/sys/dev/drm/amd/amdgpu/amdgpu_atombios.c @@ -2008,6 +2008,7 @@ int amdgpu_atombios_init(struct amdgpu_device *adev) { struct card_info *atom_card_info = kzalloc(sizeof(struct card_info), GFP_KERNEL); + int r; #if 0 int ret; #endif @@ -2042,10 +2043,14 @@ int amdgpu_atombios_init(struct amdgpu_device *adev) lockinit(&adev->mode_info.atom_context->mutex, "agmiacm", 0, LK_CANRECURSE); if (adev->is_atom_fw) { amdgpu_atomfirmware_scratch_regs_init(adev); - amdgpu_atomfirmware_allocate_fb_scratch(adev); + r = amdgpu_atomfirmware_allocate_fb_scratch(adev); } else { amdgpu_atombios_scratch_regs_init(adev); - amdgpu_atombios_allocate_fb_scratch(adev); + r = amdgpu_atombios_allocate_fb_scratch(adev); + } + if (r) { + amdgpu_atombios_fini(adev); + return r; } #if 0