The function amdgpu_virt_get_dynamic_data_info() writes a 64-bit size
value. In two places (amdgpu_bios.c and amdgpu_discovery.c), the code
passed the address of a smaller variable by casting it to u64 *, which
is unsafe.
This could make the function write more bytes than the smaller variable
can hold, possibly overwriting nearby memory. Reported by static
analysis tools.
Fix it by using a local u64 variable (tmp_size) to store the size, then
assign it to the smaller destination field.
Fixes: ae92010fb321 ("drm/amdgpu: Add logic for VF ipd and VF bios to init from
dynamic crit_region offsets")
Reported by: Dan Carpenter <[email protected]>
Cc: Ellen Pan <[email protected]>
Cc: Christian König <[email protected]>
Cc: Alex Deucher <[email protected]>
Signed-off-by: Srinivasan Shanmugam <[email protected]>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c | 4 +++-
drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 4 +++-
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
index db705bf723f1..eb7ba7c593bf 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
@@ -104,6 +104,7 @@ static bool amdgpu_read_bios_from_vram(struct amdgpu_device
*adev)
uint8_t __iomem *bios = NULL;
resource_size_t vram_base;
resource_size_t size = 256 * 1024; /* ??? */
+ u64 tmp_size = 0;
if (!(adev->flags & AMD_IS_APU))
if (amdgpu_device_need_post(adev))
@@ -126,10 +127,11 @@ static bool amdgpu_read_bios_from_vram(struct
amdgpu_device *adev)
*/
if (amdgpu_sriov_vf(adev) && adev->virt.is_dynamic_crit_regn_enabled) {
if (amdgpu_virt_get_dynamic_data_info(adev,
- AMD_SRIOV_MSG_VBIOS_IMG_TABLE_ID, adev->bios,
(uint64_t *)&size)) {
+ AMD_SRIOV_MSG_VBIOS_IMG_TABLE_ID, adev->bios,
&tmp_size)) {
amdgpu_bios_release(adev);
return false;
}
+ adev->bios_size = (resource_size_t)tmp_size;
} else {
bios = ioremap_wc(vram_base, size);
if (!bios) {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
index a7cb4665f485..87f024f72a59 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
@@ -275,6 +275,7 @@ static int amdgpu_discovery_read_binary_from_mem(struct
amdgpu_device *adev,
uint64_t vram_size;
int i, ret = 0;
u32 msg;
+ u64 tmp_size = 0;
if (!amdgpu_sriov_vf(adev)) {
/* It can take up to two second for IFWI init to complete on
some dGPUs,
@@ -311,12 +312,13 @@ static int amdgpu_discovery_read_binary_from_mem(struct
amdgpu_device *adev,
*/
if (amdgpu_virt_get_dynamic_data_info(adev,
AMD_SRIOV_MSG_IPD_TABLE_ID,
binary,
- (uint64_t
*)&adev->discovery.size)) {
+ &tmp_size)) {
dev_err(adev->dev,
"failed to read discovery info
from dynamic critical region.");
ret = -EINVAL;
goto exit;
}
+ adev->discovery.size = (u32)tmp_size;
} else {
uint64_t pos = vram_size - DISCOVERY_TMR_OFFSET;
--
2.34.1