On 4/19/2024 9:14 PM, Srinivasan Shanmugam wrote: > This commit addresses buffer overflow in the smu_v14_0_init_microcode > function. The issue was about the snprintf function writing more bytes > into the fw_name buffer than it can hold. > > The line of code is: > > snprintf(fw_name, sizeof(fw_name), "amdgpu/%s.bin", ucode_prefix); > > Here, snprintf is used to write a formatted string into fw_name. The > format is "amdgpu/%s.bin", where %s is a placeholder for the string > ucode_prefix. The sizeof(fw_name) argument tells snprintf the maximum > number of bytes it can write into fw_name, including the > null-terminating character. In the original code, fw_name is an array of > 30 characters. > > The string "amdgpu/%s.bin" could be up to 41 bytes long, which exceeds > the 30 bytes allocated for fw_name. This is because %s could be replaced > by ucode_prefix, which can be up to 29 characters long. Adding the 12 > characters from "amdgpu/" and ".bin", the total length could be 41 > characters. > > To address this, the size of ucode_prefix has been reduced to 15 > characters. This ensures that the maximum length of the string written > into fw_name does not exceed its capacity. > > As smu_13/14 etc. don't follow legacy scheme ie., > amdgpu_ucode_legacy_naming > > Fixes the below with gcc W=1: > drivers/gpu/drm/amd/amdgpu/../pm/swsmu/smu14/smu_v14_0.c: In function ‘smu_v14_0_init_microcode’: > drivers/gpu/drm/amd/amdgpu/../pm/swsmu/smu14/smu_v14_0.c:80:52: warning: ‘%s’ directive output may be truncated writing up to 29 bytes into a region of size 23 [-Wformat-truncation=] > 80 | snprintf(fw_name, sizeof(fw_name), "amdgpu/%s.bin", ucode_prefix); > | ^~ ~~~~~~~~~~~~ > drivers/gpu/drm/amd/amdgpu/../pm/swsmu/smu14/smu_v14_0.c:80:9: note: ‘snprintf’ output between 12 and 41 bytes into a destination of size 30 > 80 | snprintf(fw_name, sizeof(fw_name), "amdgpu/%s.bin", ucode_prefix); > | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > Fixes: fe6cd9152464 ("drm/amd/swsmu: add smu14 ip support") > Cc: Li Ma <li.ma@xxxxxxx> > Cc: Likun Gao <Likun.Gao@xxxxxxx> > Cc: Lijo Lazar <lijo.lazar@xxxxxxx> > Cc: Kenneth Feng <kenneth.feng@xxxxxxx> > Cc: Alex Deucher <alexander.deucher@xxxxxxx> > Cc: Christian König <christian.koenig@xxxxxxx> > Signed-off-by: Srinivasan Shanmugam <srinivasan.shanmugam@xxxxxxx> Reviewed-by: Lijo Lazar <lijo.lazar@xxxxxxx> Thanks, Lijo > --- > v4: > - Reduced ucode_prefix to 15 instead of fw_name size increasing as > smu_13/14 etc. don't follow legacy scheme ie., > amdgpu_ucode_legacy_naming (Lijo) > > drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0.c > index 7d2055b9d19f..68b9bf822e8d 100644 > --- a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0.c > +++ b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0.c > @@ -65,7 +65,7 @@ int smu_v14_0_init_microcode(struct smu_context *smu) > { > struct amdgpu_device *adev = smu->adev; > char fw_name[30]; > - char ucode_prefix[30]; > + char ucode_prefix[15]; > int err = 0; > const struct smc_firmware_header_v1_0 *hdr; > const struct common_firmware_header *header;