From 81572c68e3e3dd01bb5ee4b78b7212d2c721f8e8 Mon Sep 17 00:00:00 2001 From: Simon Wang Date: Mon, 6 May 2024 05:35:37 -0700 Subject: [PATCH] fix: communicate buffer and size check for STMM handlers - CommBuffer and CommBufferSize checks prior to proceeding within STMM handlers. - CommBuffer data payload size validation prior to proceeding. Signed-off-by: Simon Wang Reviewed-by: Girish Mahadevan --- .../FwPartitionStandaloneMm.c | 84 +++++++++++++++++-- .../Drivers/MctpMmDxe/MctpStandaloneMm.c | 26 ++++-- .../SequentialRecordComm.c | 40 +++++++++ .../OemPartitionDxeMm/OemPartitionMm.c | 4 +- 4 files changed, 141 insertions(+), 13 deletions(-) diff --git a/Silicon/NVIDIA/Drivers/FwPartitionMmDxe/FwPartitionStandaloneMm.c b/Silicon/NVIDIA/Drivers/FwPartitionMmDxe/FwPartitionStandaloneMm.c index f1d02610cc..e553e0acd5 100644 --- a/Silicon/NVIDIA/Drivers/FwPartitionMmDxe/FwPartitionStandaloneMm.c +++ b/Silicon/NVIDIA/Drivers/FwPartitionMmDxe/FwPartitionStandaloneMm.c @@ -32,6 +32,16 @@ FwPartitionMmHandler ( UINTN PayloadSize; EFI_STATUS Status; + if ((CommBuffer == NULL) || (CommBufferSize == NULL)) { + DEBUG ((DEBUG_ERROR, "%a: Communication buffer : %r\n", __FUNCTION__, EFI_INVALID_PARAMETER)); + return EFI_SUCCESS; + } + + if (*CommBufferSize < sizeof (FW_PARTITION_COMM_HEADER)) { + DEBUG ((DEBUG_ERROR, "%a: Communication buffer : %r\n", __FUNCTION__, EFI_BUFFER_TOO_SMALL)); + return EFI_SUCCESS; + } + FwImageCommHeader = (FW_PARTITION_COMM_HEADER *)CommBuffer; PayloadSize = *CommBufferSize - FW_PARTITION_COMM_HEADER_SIZE; @@ -42,6 +52,17 @@ FwPartitionMmHandler ( case FW_PARTITION_COMM_FUNCTION_INITIALIZE: { FW_PARTITION_COMM_INITIALIZE *InitPayload; + if (PayloadSize < sizeof (FW_PARTITION_COMM_INITIALIZE)) { + DEBUG (( + DEBUG_ERROR, + "%a: Command [%d], payload buffer : %r!\n", + __FUNCTION__, + FwImageCommHeader->Function, + EFI_INVALID_PARAMETER + )); + FwImageCommHeader->ReturnStatus = EFI_INVALID_PARAMETER; + break; + } InitPayload = (FW_PARTITION_COMM_INITIALIZE *)FwImageCommHeader->Data; Status = FwPartitionNorFlashStmmInitialize ( @@ -64,10 +85,19 @@ FwPartitionMmHandler ( NumImages = FwPartitionGetCount (); ImagesPayload = (FW_PARTITION_COMM_GET_PARTITIONS *)FwImageCommHeader->Data; - ASSERT ( - PayloadSize == OFFSET_OF (FW_PARTITION_COMM_GET_PARTITIONS, Partitions) + - (ImagesPayload->MaxCount * sizeof (ImagesPayload->Partitions[0])) - ); + if (PayloadSize != OFFSET_OF (FW_PARTITION_COMM_GET_PARTITIONS, Partitions) + + (ImagesPayload->MaxCount * sizeof (ImagesPayload->Partitions[0]))) + { + DEBUG (( + DEBUG_ERROR, + "%a: Command [%d], payload buffer : %r!\n", + __FUNCTION__, + FwImageCommHeader->Function, + EFI_INVALID_PARAMETER + )); + FwImageCommHeader->ReturnStatus = EFI_INVALID_PARAMETER; + break; + } if (NumImages > ImagesPayload->MaxCount) { FwImageCommHeader->ReturnStatus = EFI_BUFFER_TOO_SMALL; @@ -102,9 +132,30 @@ FwPartitionMmHandler ( FW_PARTITION_COMM_READ_DATA *ReadDataPayload; FW_PARTITION_PRIVATE_DATA *Partition; FW_PARTITION_DEVICE_INFO *DeviceInfo; + if (PayloadSize < sizeof (FW_PARTITION_COMM_READ_DATA)) { + DEBUG (( + DEBUG_ERROR, + "%a: Command [%d], payload buffer : %r!\n", + __FUNCTION__, + FwImageCommHeader->Function, + EFI_INVALID_PARAMETER + )); + FwImageCommHeader->ReturnStatus = EFI_INVALID_PARAMETER; + break; + } ReadDataPayload = (FW_PARTITION_COMM_READ_DATA *)FwImageCommHeader->Data; - ASSERT (PayloadSize == OFFSET_OF (FW_PARTITION_COMM_READ_DATA, Data) + ReadDataPayload->Bytes); + if (PayloadSize != OFFSET_OF (FW_PARTITION_COMM_READ_DATA, Data) + ReadDataPayload->Bytes) { + DEBUG (( + DEBUG_ERROR, + "%a: Command [%d], payload buffer : %r!\n", + __FUNCTION__, + FwImageCommHeader->Function, + EFI_INVALID_PARAMETER + )); + FwImageCommHeader->ReturnStatus = EFI_INVALID_PARAMETER; + break; + } DEBUG (( DEBUG_INFO, @@ -139,9 +190,30 @@ FwPartitionMmHandler ( FW_PARTITION_COMM_WRITE_DATA *WriteDataPayload; FW_PARTITION_PRIVATE_DATA *Partition; FW_PARTITION_DEVICE_INFO *DeviceInfo; + if (PayloadSize < sizeof (FW_PARTITION_COMM_WRITE_DATA)) { + DEBUG (( + DEBUG_ERROR, + "%a: Command [%d], payload buffer : %r!\n", + __FUNCTION__, + FwImageCommHeader->Function, + EFI_INVALID_PARAMETER + )); + FwImageCommHeader->ReturnStatus = EFI_INVALID_PARAMETER; + break; + } WriteDataPayload = (FW_PARTITION_COMM_WRITE_DATA *)FwImageCommHeader->Data; - ASSERT (PayloadSize == OFFSET_OF (FW_PARTITION_COMM_WRITE_DATA, Data) + WriteDataPayload->Bytes); + if (PayloadSize != OFFSET_OF (FW_PARTITION_COMM_WRITE_DATA, Data) + WriteDataPayload->Bytes) { + DEBUG (( + DEBUG_ERROR, + "%a: Command [%d], payload buffer : %r!\n", + __FUNCTION__, + FwImageCommHeader->Function, + EFI_INVALID_PARAMETER + )); + FwImageCommHeader->ReturnStatus = EFI_INVALID_PARAMETER; + break; + } DEBUG (( DEBUG_INFO, diff --git a/Silicon/NVIDIA/Drivers/MctpMmDxe/MctpStandaloneMm.c b/Silicon/NVIDIA/Drivers/MctpMmDxe/MctpStandaloneMm.c index a78f772eed..dc123aaa9e 100644 --- a/Silicon/NVIDIA/Drivers/MctpMmDxe/MctpStandaloneMm.c +++ b/Silicon/NVIDIA/Drivers/MctpMmDxe/MctpStandaloneMm.c @@ -2,7 +2,7 @@ MCTP protocol standalone MM - Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + SPDX-FileCopyrightText: Copyright (c) 2022-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent @@ -99,6 +99,16 @@ MctpMmHandler ( MCTP_MM_DEVICE_INFO *DeviceInfo; MCTP_DEVICE_ATTRIBUTES Attributes; + if ((CommBuffer == NULL) || (CommBufferSize == NULL)) { + DEBUG ((DEBUG_ERROR, "%a: Communication buffer : %r\n", __FUNCTION__, EFI_INVALID_PARAMETER)); + return EFI_SUCCESS; + } + + if (*CommBufferSize < sizeof (MCTP_COMM_HEADER)) { + DEBUG ((DEBUG_ERROR, "%a: Communication buffer : %r\n", __FUNCTION__, EFI_BUFFER_TOO_SMALL)); + return EFI_SUCCESS; + } + MctpCommHeader = (MCTP_COMM_HEADER *)CommBuffer; DEBUG ((DEBUG_INFO, "%a: Func=%u\n", __FUNCTION__, MctpCommHeader->Function)); @@ -108,6 +118,12 @@ MctpMmHandler ( case MCTP_COMM_FUNCTION_INITIALIZE: { MCTP_COMM_INITIALIZE *Payload = (MCTP_COMM_INITIALIZE *)MctpCommHeader->Data; + if (PayloadSize < sizeof (MCTP_COMM_INITIALIZE)) { + DEBUG ((DEBUG_ERROR, "%a: Command [%d], payload buffer invalid!\n", __FUNCTION__, MctpCommHeader->Function)); + MctpCommHeader->ReturnStatus = EFI_INVALID_PARAMETER; + break; + } + Status = MctpMmInitProtocols (&Payload->NumDevices); MctpCommHeader->ReturnStatus = Status; break; @@ -116,11 +132,11 @@ MctpMmHandler ( case MCTP_COMM_FUNCTION_GET_DEVICES: { MCTP_COMM_GET_DEVICES *Payload = (MCTP_COMM_GET_DEVICES *)MctpCommHeader->Data; - if ((PayloadSize != OFFSET_OF (MCTP_COMM_GET_DEVICES, Devices) + (Payload->MaxCount * sizeof (Payload->Devices))) || (mNumDevices > Payload->MaxCount)) { + DEBUG ((DEBUG_ERROR, "%a: Command [%d], payload buffer invalid!\n", __FUNCTION__, MctpCommHeader->Function)); MctpCommHeader->ReturnStatus = EFI_INVALID_PARAMETER; break; } @@ -145,10 +161,10 @@ MctpMmHandler ( case MCTP_COMM_FUNCTION_SEND: { MCTP_COMM_SEND *Payload = (MCTP_COMM_SEND *)MctpCommHeader->Data; - if ((PayloadSize != OFFSET_OF (MCTP_COMM_SEND, Data) + Payload->Length) || (Payload->MmIndex >= mNumDevices)) { + DEBUG ((DEBUG_ERROR, "%a: Command [%d], payload buffer invalid!\n", __FUNCTION__, MctpCommHeader->Function)); MctpCommHeader->ReturnStatus = EFI_INVALID_PARAMETER; break; } @@ -182,10 +198,10 @@ MctpMmHandler ( case MCTP_COMM_FUNCTION_RECV: { MCTP_COMM_RECV *Payload = (MCTP_COMM_RECV *)MctpCommHeader->Data; - if ((PayloadSize != OFFSET_OF (MCTP_COMM_RECV, Data) + Payload->MaxLength) || (Payload->MmIndex >= mNumDevices)) { + DEBUG ((DEBUG_ERROR, "%a: Command [%d], payload buffer invalid!\n", __FUNCTION__, MctpCommHeader->Function)); MctpCommHeader->ReturnStatus = EFI_INVALID_PARAMETER; break; } @@ -219,10 +235,10 @@ MctpMmHandler ( case MCTP_COMM_FUNCTION_DO_REQUEST: { MCTP_COMM_DO_REQUEST *Payload = (MCTP_COMM_DO_REQUEST *)MctpCommHeader->Data; - if ((PayloadSize != OFFSET_OF (MCTP_COMM_DO_REQUEST, Data) + MAX (Payload->RequestLength, Payload->ResponseBufferLength)) || (Payload->MmIndex >= mNumDevices)) { + DEBUG ((DEBUG_ERROR, "%a: Command [%d], payload buffer invalid!\n", __FUNCTION__, MctpCommHeader->Function)); MctpCommHeader->ReturnStatus = EFI_INVALID_PARAMETER; break; } diff --git a/Silicon/NVIDIA/Drivers/SequentialRecordStMm/SequentialRecordComm.c b/Silicon/NVIDIA/Drivers/SequentialRecordStMm/SequentialRecordComm.c index 848e6a9d5c..3f5bd7023a 100644 --- a/Silicon/NVIDIA/Drivers/SequentialRecordStMm/SequentialRecordComm.c +++ b/Silicon/NVIDIA/Drivers/SequentialRecordStMm/SequentialRecordComm.c @@ -118,6 +118,16 @@ CmetMsgHandler ( RAS_MM_COMMUNICATE_PAYLOAD *CmetHeader; UINT8 *CmetPayload; + if ((CommBuffer == NULL) || (CommBufferSize == NULL)) { + DEBUG ((DEBUG_ERROR, "%a: Communication buffer : %r\n", __FUNCTION__, EFI_INVALID_PARAMETER)); + return EFI_SUCCESS; + } + + if (*CommBufferSize < sizeof (RAS_MM_COMMUNICATE_PAYLOAD)) { + DEBUG ((DEBUG_ERROR, "%a: Communication buffer : %r\n", __FUNCTION__, EFI_BUFFER_TOO_SMALL)); + return EFI_SUCCESS; + } + CmetHeader = (RAS_MM_COMMUNICATE_PAYLOAD *)CommBuffer; CmetPayload = CmetHeader->Data; @@ -244,6 +254,16 @@ RasLogMsgHandler ( RAS_MM_COMMUNICATE_PAYLOAD *RasHeader; UINT8 *RasPayload; + if ((CommBuffer == NULL) || (CommBufferSize == NULL)) { + DEBUG ((DEBUG_ERROR, "%a: Communication buffer : %r\n", __FUNCTION__, EFI_INVALID_PARAMETER)); + return EFI_SUCCESS; + } + + if (*CommBufferSize < sizeof (RAS_MM_COMMUNICATE_PAYLOAD)) { + DEBUG ((DEBUG_ERROR, "%a: Communication buffer : %r\n", __FUNCTION__, EFI_BUFFER_TOO_SMALL)); + return EFI_SUCCESS; + } + RasHeader = (RAS_MM_COMMUNICATE_PAYLOAD *)CommBuffer; RasPayload = RasHeader->Data; @@ -391,6 +411,16 @@ EarlyVarsMsgHandler ( EFI_PHYSICAL_ADDRESS CpuBlAddr; UINT32 RecSize; + if ((CommBuffer == NULL) || (CommBufferSize == NULL)) { + DEBUG ((DEBUG_ERROR, "%a: Communication buffer : %r\n", __FUNCTION__, EFI_INVALID_PARAMETER)); + return EFI_SUCCESS; + } + + if (*CommBufferSize < sizeof (NVIDIA_MM_MB1_RECORD_PAYLOAD)) { + DEBUG ((DEBUG_ERROR, "%a: Communication buffer : %r\n", __FUNCTION__, EFI_BUFFER_TOO_SMALL)); + return EFI_SUCCESS; + } + EarlyVars = (NVIDIA_MM_MB1_RECORD_PAYLOAD *)CommBuffer; RecSize = TEGRABL_EARLY_BOOT_VARS_MAX_SIZE - sizeof (TEGRABL_EARLY_BOOT_VARS_DATA_HEADER); if (EarlyVarsProto == NULL) { @@ -665,6 +695,16 @@ SatMcMsgHandler ( EFI_PHYSICAL_ADDRESS CpuBlParamsAddr; UINT16 DeviceInstance; + if ((CommBuffer == NULL) || (CommBufferSize == NULL)) { + DEBUG ((DEBUG_ERROR, "%a: Communication buffer : %r\n", __FUNCTION__, EFI_INVALID_PARAMETER)); + return EFI_SUCCESS; + } + + if (*CommBufferSize < sizeof (SATMC_MM_COMMUNICATE_PAYLOAD)) { + DEBUG ((DEBUG_ERROR, "%a: Communication buffer : %r\n", __FUNCTION__, EFI_BUFFER_TOO_SMALL)); + return EFI_SUCCESS; + } + SatMcMmMsg = (SATMC_MM_COMMUNICATE_PAYLOAD *)CommBuffer; if (IsBufInSecSpMbox ((UINTN)CommBuffer, SATMC_VMID) == FALSE) { diff --git a/Silicon/NVIDIA/Server/TH500/Drivers/OemPartitionDxeMm/OemPartitionMm.c b/Silicon/NVIDIA/Server/TH500/Drivers/OemPartitionDxeMm/OemPartitionMm.c index 157433d638..e04a2f85fb 100644 --- a/Silicon/NVIDIA/Server/TH500/Drivers/OemPartitionDxeMm/OemPartitionMm.c +++ b/Silicon/NVIDIA/Server/TH500/Drivers/OemPartitionDxeMm/OemPartitionMm.c @@ -1,7 +1,7 @@ /** @file NVIDIA Oem Partition Sample Driver - SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + SPDX-FileCopyrightText: Copyright (c) 2023-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent @@ -422,7 +422,7 @@ MmOemPartitionHandler ( switch (MmFunctionHeader->Function) { case OEM_PARTITION_FUNC_GET_INFO: - if (CommBufferPayloadSize != sizeof (OEM_PARTITION_COMMUNICATE_READ)) { + if (CommBufferPayloadSize != sizeof (OEM_PARTITION_COMMUNICATE_GET_INFO)) { DEBUG ((DEBUG_ERROR, "%a: Command [%d], payload buffer invalid!\n", __FUNCTION__, MmFunctionHeader->Function)); Status = EFI_INVALID_PARAMETER; break;