Felix Held has submitted this change. ( https://review.coreboot.org/c/coreboot/+/83778?usp=email )
Change subject: soc/amd/common/psp_smi_flash: add buffer overflow checks ......................................................................
soc/amd/common/psp_smi_flash: add buffer overflow checks
Before 'handle_psp_command' calls any of the functions in this file, it make sure that the 'size' field in the command buffer's header doesn't indicate that the command buffer is larger than the SMM memory region reserved for it.
The read/write command buffer has a 'num_bytes' field to indicate how many bytes should be read from the SPI flash and put into the data buffer within the command buffer or how many bytes from this buffer should be written to the flash. While we should be able to assume that the PSP won't send us malformed command buffer, we should still better check this just to be sure.
Test=When selecting SOC_AMD_COMMON_BLOCK_PSP_SMI, Mandolin still builds
Signed-off-by: Felix Held felix-coreboot@felixheld.de Change-Id: Ib4e8514eedc3ad154a705c8a1e85d367e452dbed Reviewed-on: https://review.coreboot.org/c/coreboot/+/83778 Reviewed-by: Martin Roth martin.roth@amd.corp-partner.google.com Tested-by: build bot (Jenkins) no-reply@coreboot.org --- M src/soc/amd/common/block/psp/psp_smi_flash.c 1 file changed, 22 insertions(+), 0 deletions(-)
Approvals: build bot (Jenkins): Verified Martin Roth: Looks good to me, approved
diff --git a/src/soc/amd/common/block/psp/psp_smi_flash.c b/src/soc/amd/common/block/psp/psp_smi_flash.c index 2d075ef..405fc29 100644 --- a/src/soc/amd/common/block/psp/psp_smi_flash.c +++ b/src/soc/amd/common/block/psp/psp_smi_flash.c @@ -104,6 +104,16 @@ *num_blocks = read64(&cmd_buf->req.num_blocks); }
+static bool is_valid_rw_byte_count(struct mbox_pspv2_cmd_spi_read_write *cmd_buf, + u64 num_bytes) +{ + const u32 cmd_buf_size = read32(&cmd_buf->header.size); + const size_t payload_buffer_offset = + offsetof(struct mbox_pspv2_cmd_spi_read_write, req) + + offsetof(struct pspv2_spi_read_write_request, buffer); + return num_bytes <= cmd_buf_size - payload_buffer_offset; +} + static const char *id_to_region_name(u64 target_nv_id) { switch (target_nv_id) { @@ -238,6 +248,12 @@
get_psp_spi_read_write(cmd_buf, &target_nv_id, &lba, &offset, &num_bytes, &data);
+ if (!is_valid_rw_byte_count(cmd_buf, num_bytes)) { + printk(BIOS_ERR, "PSP: Read command requested more bytes than we have space " + "for in the buffer\n"); + return MBOX_PSP_COMMAND_PROCESS_ERROR; + } + ret = find_psp_spi_flash_device_region(target_nv_id, &store, &flash);
if (ret != MBOX_PSP_SUCCESS) @@ -281,6 +297,12 @@
get_psp_spi_read_write(cmd_buf, &target_nv_id, &lba, &offset, &num_bytes, &data);
+ if (!is_valid_rw_byte_count(cmd_buf, num_bytes)) { + printk(BIOS_ERR, "PSP: Write command contains more bytes than we have space " + "for in the buffer\n"); + return MBOX_PSP_COMMAND_PROCESS_ERROR; + } + ret = find_psp_spi_flash_device_region(target_nv_id, &store, &flash);
if (ret != MBOX_PSP_SUCCESS)