Nico Huber has submitted this change. ( https://review.coreboot.org/c/coreboot/+/35558 )
Change subject: device/dram/ddr4: Check spd_bytes_total and spd_bytes_used values ......................................................................
device/dram/ddr4: Check spd_bytes_total and spd_bytes_used values
The value stored to 'spd_bytes_total' is never read. Now it is fixed. This is spotted using clang-tool v9. Also add a check if spd_bytes_used and/or spd_bytes_total are reserved and make sure that spd_bytes_used is not greater than spd_bytes_total.
Change-Id: I426a7e64cc4c0bcced91d03387e02c8d965a21dc Signed-off-by: Elyes HAOUAS ehaouas@noos.fr Reviewed-on: https://review.coreboot.org/c/coreboot/+/35558 Tested-by: build bot (Jenkins) no-reply@coreboot.org Reviewed-by: Nico Huber nico.h@gmx.de --- M src/device/dram/ddr4.c 1 file changed, 16 insertions(+), 2 deletions(-)
Approvals: build bot (Jenkins): Verified Nico Huber: Looks good to me, approved
diff --git a/src/device/dram/ddr4.c b/src/device/dram/ddr4.c index 4f99ecc..07f9dec 100644 --- a/src/device/dram/ddr4.c +++ b/src/device/dram/ddr4.c @@ -111,17 +111,31 @@ return SPD_STATUS_INVALID; }
- spd_bytes_total = (spd[0] >> 4) & ((1 << 3) - 1); - spd_bytes_used = spd[0] & ((1 << 4) - 1); + spd_bytes_total = (spd[0] >> 4) & 0x7; + spd_bytes_used = spd[0] & 0xf;
if (!spd_bytes_total || !spd_bytes_used) { printk(BIOS_ERR, "SPD failed basic sanity checks\n"); return SPD_STATUS_INVALID; }
+ if (spd_bytes_total >= 3) + printk(BIOS_WARNING, "SPD Bytes Total value is reserved\n"); + spd_bytes_total = 256 << (spd_bytes_total - 1); + + if (spd_bytes_used > 4) { + printk(BIOS_ERR, "SPD Bytes Used value is reserved\n"); + return SPD_STATUS_INVALID; + } + spd_bytes_used = spd_bytes_used_table[spd_bytes_used];
+ if (spd_bytes_used > spd_bytes_total) { + printk(BIOS_ERR, "SPD Bytes Used is greater than SPD Bytes Total\n"); + return SPD_STATUS_INVALID; + } + /* Verify CRC of blocks that have them, do not step over 'used' length */ for (int i = 0; i < ARRAY_SIZE(spd_blocks); i++) { /* this block is not checksumed */