Skip to content

Commit

Permalink
fix: communicate buffer and size check for STMM handlers
Browse files Browse the repository at this point in the history
- CommBuffer and CommBufferSize checks prior to proceeding
  within STMM handlers.
- CommBuffer data payload size validation prior to proceeding.

Signed-off-by: Simon Wang <simowang@nvidia.com>
Reviewed-by: Girish Mahadevan <gmahadevan@nvidia.com>
  • Loading branch information
wangsim authored and jgarver committed Jun 6, 2024
1 parent 9e93d6d commit 81572c6
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 13 deletions.
84 changes: 78 additions & 6 deletions Silicon/NVIDIA/Drivers/FwPartitionMmDxe/FwPartitionStandaloneMm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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 (
Expand All @@ -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;
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
26 changes: 21 additions & 5 deletions Silicon/NVIDIA/Drivers/MctpMmDxe/MctpStandaloneMm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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));

Expand All @@ -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;
Expand All @@ -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;
}
Expand All @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand Down
40 changes: 40 additions & 0 deletions Silicon/NVIDIA/Drivers/SequentialRecordStMm/SequentialRecordComm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 81572c6

Please sign in to comment.