Skip to content

Commit 00b14ce

Browse files
Luben Tuikovalexdeucher
Luben Tuikov
authored andcommitted
drm/amdgpu: Prevent random memory access in FRU code
Prevent random memory access in the FRU EEPROM code by passing the size of the destination buffer to the reading routine, and reading no more than the size of the buffer. Cc: Kent Russell <[email protected]> Cc: Alex Deucher <[email protected]> Signed-off-by: Luben Tuikov <[email protected]> Acked-by: Harish Kasiviswanathan <[email protected]> Reviewed-by: Kent Russell <[email protected]> Signed-off-by: Alex Deucher <[email protected]>
1 parent 3f3a24a commit 00b14ce

File tree

1 file changed

+12
-10
lines changed

1 file changed

+12
-10
lines changed

drivers/gpu/drm/amd/amdgpu/amdgpu_fru_eeprom.c

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
#include "amdgpu_eeprom.h"
3131

3232
#define FRU_EEPROM_MADDR 0x60000
33-
#define I2C_PRODUCT_INFO_OFFSET 0xC0
3433

3534
static bool is_fru_eeprom_supported(struct amdgpu_device *adev)
3635
{
@@ -77,9 +76,10 @@ static bool is_fru_eeprom_supported(struct amdgpu_device *adev)
7776
}
7877

7978
static int amdgpu_fru_read_eeprom(struct amdgpu_device *adev, uint32_t addrptr,
80-
unsigned char *buf)
79+
unsigned char *buf, size_t buf_size)
8180
{
82-
int ret, size;
81+
int ret;
82+
u8 size;
8383

8484
ret = amdgpu_eeprom_read(adev->pm.fru_eeprom_i2c_bus, addrptr, buf, 1);
8585
if (ret < 1) {
@@ -90,9 +90,11 @@ static int amdgpu_fru_read_eeprom(struct amdgpu_device *adev, uint32_t addrptr,
9090
/* The size returned by the i2c requires subtraction of 0xC0 since the
9191
* size apparently always reports as 0xC0+actual size.
9292
*/
93-
size = buf[0] - I2C_PRODUCT_INFO_OFFSET;
93+
size = buf[0] & 0x3F;
94+
size = min_t(size_t, size, buf_size);
9495

95-
ret = amdgpu_eeprom_read(adev->pm.fru_eeprom_i2c_bus, addrptr + 1, buf, size);
96+
ret = amdgpu_eeprom_read(adev->pm.fru_eeprom_i2c_bus, addrptr + 1,
97+
buf, size);
9698
if (ret < 1) {
9799
DRM_WARN("FRU: Failed to get data field");
98100
return ret;
@@ -129,7 +131,7 @@ int amdgpu_fru_get_product_info(struct amdgpu_device *adev)
129131
* and the language field, so just start from 0xb, manufacturer size
130132
*/
131133
addrptr = FRU_EEPROM_MADDR + 0xb;
132-
size = amdgpu_fru_read_eeprom(adev, addrptr, buf);
134+
size = amdgpu_fru_read_eeprom(adev, addrptr, buf, sizeof(buf));
133135
if (size < 1) {
134136
DRM_ERROR("Failed to read FRU Manufacturer, ret:%d", size);
135137
return -EINVAL;
@@ -139,7 +141,7 @@ int amdgpu_fru_get_product_info(struct amdgpu_device *adev)
139141
* size field being 1 byte. This pattern continues below.
140142
*/
141143
addrptr += size + 1;
142-
size = amdgpu_fru_read_eeprom(adev, addrptr, buf);
144+
size = amdgpu_fru_read_eeprom(adev, addrptr, buf, sizeof(buf));
143145
if (size < 1) {
144146
DRM_ERROR("Failed to read FRU product name, ret:%d", size);
145147
return -EINVAL;
@@ -155,7 +157,7 @@ int amdgpu_fru_get_product_info(struct amdgpu_device *adev)
155157
adev->product_name[len] = '\0';
156158

157159
addrptr += size + 1;
158-
size = amdgpu_fru_read_eeprom(adev, addrptr, buf);
160+
size = amdgpu_fru_read_eeprom(adev, addrptr, buf, sizeof(buf));
159161
if (size < 1) {
160162
DRM_ERROR("Failed to read FRU product number, ret:%d", size);
161163
return -EINVAL;
@@ -173,15 +175,15 @@ int amdgpu_fru_get_product_info(struct amdgpu_device *adev)
173175
adev->product_number[len] = '\0';
174176

175177
addrptr += size + 1;
176-
size = amdgpu_fru_read_eeprom(adev, addrptr, buf);
178+
size = amdgpu_fru_read_eeprom(adev, addrptr, buf, sizeof(buf));
177179

178180
if (size < 1) {
179181
DRM_ERROR("Failed to read FRU product version, ret:%d", size);
180182
return -EINVAL;
181183
}
182184

183185
addrptr += size + 1;
184-
size = amdgpu_fru_read_eeprom(adev, addrptr, buf);
186+
size = amdgpu_fru_read_eeprom(adev, addrptr, buf, sizeof(buf));
185187

186188
if (size < 1) {
187189
DRM_ERROR("Failed to read FRU serial number, ret:%d", size);

0 commit comments

Comments
 (0)