Revision: 14287
http://edk2.svn.sourceforge.net/edk2/?rev=14287&view=rev
Author: vanjeff
Date: 2013-04-18 05:37:12 +0000 (Thu, 18 Apr 2013)
Log Message:
-----------
Sync patches r14252, r14258, r14283 and r14284 from main trunk.
1. If DataSize or VariableNameSize is near MAX_ADDRESS, this can cause the
computed PayLoadSize to overflow to a small value and pass the check in
InitCommunicateBuffer(). To protect against this vulnerability, check DataSize
and VariableNameSize to make sure PayloadSize doesn't overflow.
2. Update SMM variable DXE driver GetNextVariable interface to comply with UEFI
spec VariableNameSize is the returned buffer size. GetNextVariable should
behavior correct if it is bigger than SMM communication buffer or less than
string size of VariableName.
3. Update code not to block application/driver load when event log is full.
4. MdeModulePkg/AtaBus: AtaBusDxe module would ignore ATA Pass Thru Protocol
instances that do not have the LOGICAL attribute set.
Revision Links:
--------------
http://edk2.svn.sourceforge.net/edk2/?rev=14252&view=rev
http://edk2.svn.sourceforge.net/edk2/?rev=14258&view=rev
http://edk2.svn.sourceforge.net/edk2/?rev=14283&view=rev
http://edk2.svn.sourceforge.net/edk2/?rev=14284&view=rev
Modified Paths:
--------------
branches/UDK2010.SR1/MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBus.c
branches/UDK2010.SR1/MdeModulePkg/Include/Guid/SmmVariableCommon.h
branches/UDK2010.SR1/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
branches/UDK2010.SR1/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c
branches/UDK2010.SR1/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c
branches/UDK2010.SR1/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c
branches/UDK2010.SR1/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.c
Modified: branches/UDK2010.SR1/MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBus.c
===================================================================
--- branches/UDK2010.SR1/MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBus.c
2013-04-18 05:32:02 UTC (rev 14286)
+++ branches/UDK2010.SR1/MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBus.c
2013-04-18 05:37:12 UTC (rev 14287)
@@ -4,7 +4,7 @@
This file implements protocol interfaces: Driver Binding protocol,
Block IO protocol and DiskInfo protocol.
- Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD
License
which accompanies this distribution. The full text of the license may be
found at
@@ -630,11 +630,36 @@
}
//
+ // Test to see if this ATA Pass Thru Protocol is for a LOGICAL channel
+ //
+ if ((AtaPassThru->Mode->Attributes & EFI_ATA_PASS_THRU_ATTRIBUTES_LOGICAL)
== 0) {
+ //
+ // Close the I/O Abstraction(s) used to perform the supported test
+ //
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiAtaPassThruProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ return EFI_UNSUPPORTED;
+ }
+
+ //
// Test RemainingDevicePath is valid or not.
//
if ((RemainingDevicePath != NULL) && !IsDevicePathEnd (RemainingDevicePath))
{
Status = AtaPassThru->GetDevice (AtaPassThru, RemainingDevicePath, &Port,
&PortMultiplierPort);
if (EFI_ERROR (Status)) {
+ //
+ // Close the I/O Abstraction(s) used to perform the supported test
+ //
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiAtaPassThruProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
return Status;
}
}
Modified: branches/UDK2010.SR1/MdeModulePkg/Include/Guid/SmmVariableCommon.h
===================================================================
--- branches/UDK2010.SR1/MdeModulePkg/Include/Guid/SmmVariableCommon.h
2013-04-18 05:32:02 UTC (rev 14286)
+++ branches/UDK2010.SR1/MdeModulePkg/Include/Guid/SmmVariableCommon.h
2013-04-18 05:37:12 UTC (rev 14287)
@@ -1,7 +1,7 @@
/** @file
The file defined some common structures used for communicating between SMM
variable module and SMM variable wrapper module.
-Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials are licensed and made available
under
the terms and conditions of the BSD License that accompanies this
distribution.
The full text of the license may be found at
@@ -87,7 +87,7 @@
///
typedef struct {
EFI_GUID Guid;
- UINTN NameSize;
+ UINTN NameSize; // Return name buffer size
CHAR16 Name[1];
} SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME;
Modified:
branches/UDK2010.SR1/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
===================================================================
--- branches/UDK2010.SR1/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
2013-04-18 05:32:02 UTC (rev 14286)
+++ branches/UDK2010.SR1/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
2013-04-18 05:37:12 UTC (rev 14287)
@@ -2580,6 +2580,11 @@
ASSERT(VariableStoreHeader->Size == VariableStoreLength);
//
+ // The max variable or hardware error variable size should be < variable
store size.
+ //
+ ASSERT(MAX (PcdGet32 (PcdMaxVariableSize), PcdGet32
(PcdMaxHardwareErrorVariableSize)) < VariableStoreLength);
+
+ //
// Parse non-volatile variable data and get last variable offset.
//
NextVariable = GetStartPointer ((VARIABLE_STORE_HEADER
*)(UINTN)VariableStoreBase);
Modified:
branches/UDK2010.SR1/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c
===================================================================
---
branches/UDK2010.SR1/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c
2013-04-18 05:32:02 UTC (rev 14286)
+++
branches/UDK2010.SR1/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c
2013-04-18 05:37:12 UTC (rev 14287)
@@ -198,6 +198,16 @@
return EFI_INVALID_PARAMETER;
}
+ if (*DataSize >= mVariableBufferSize) {
+ //
+ // DataSize may be near MAX_ADDRESS incorrectly, this can cause the
computed PayLoadSize to
+ // overflow to a small value and pass the check in InitCommunicateBuffer().
+ // To protect against this vulnerability, return EFI_INVALID_PARAMETER if
DataSize is >= mVariableBufferSize.
+ // And there will be further check to ensure the total size is also not >
mVariableBufferSize.
+ //
+ return EFI_INVALID_PARAMETER;
+ }
+
AcquireLockOnlyAtBootTime(&mVariableServicesLock);
//
@@ -270,27 +280,58 @@
EFI_STATUS Status;
UINTN PayloadSize;
SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME *SmmGetNextVariableName;
+ UINTN SmmCommBufPayloadSize;
if (VariableNameSize == NULL || VariableName == NULL || VendorGuid == NULL) {
return EFI_INVALID_PARAMETER;
}
+ //
+ // SMM Communication Buffer max payload size
+ //
+ SmmCommBufPayloadSize = mVariableBufferSize - (SMM_COMMUNICATE_HEADER_SIZE +
SMM_VARIABLE_COMMUNICATE_HEADER_SIZE);
+
+ //
+ // If input string exceeds SMM payload limit. Return failure
+ //
+ if (StrSize (VariableName) > SmmCommBufPayloadSize - OFFSET_OF
(SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
AcquireLockOnlyAtBootTime(&mVariableServicesLock);
//
// Init the communicate buffer. The buffer data size is:
// SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE +
PayloadSize.
//
- PayloadSize = OFFSET_OF (SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME,
Name) + *VariableNameSize;
+ if (*VariableNameSize > SmmCommBufPayloadSize - OFFSET_OF
(SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name)) {
+ //
+ // If output buffer exceed SMM payload limit. Trim output buffer to SMM
payload size
+ //
+ *VariableNameSize = SmmCommBufPayloadSize - OFFSET_OF
(SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name);
+ }
+ //
+ // Payload should be Guid + NameSize + MAX of Input & Output buffer
+ //
+ PayloadSize = OFFSET_OF (SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME,
Name) + MAX (*VariableNameSize, StrSize (VariableName));
+
+
Status = InitCommunicateBuffer ((VOID **)&SmmGetNextVariableName,
PayloadSize, SMM_VARIABLE_FUNCTION_GET_NEXT_VARIABLE_NAME);
if (EFI_ERROR (Status)) {
goto Done;
}
ASSERT (SmmGetNextVariableName != NULL);
+ //
+ // SMM comm buffer->NameSize is buffer size for return string
+ //
SmmGetNextVariableName->NameSize = *VariableNameSize;
+
CopyGuid (&SmmGetNextVariableName->Guid, VendorGuid);
- CopyMem (SmmGetNextVariableName->Name, VariableName, *VariableNameSize);
+ //
+ // Copy whole string
+ //
+ CopyMem (SmmGetNextVariableName->Name, VariableName, StrSize (VariableName));
//
// Send data to SMM
@@ -355,6 +396,16 @@
return EFI_INVALID_PARAMETER;
}
+ if (DataSize >= mVariableBufferSize) {
+ //
+ // DataSize may be near MAX_ADDRESS incorrectly, this can cause the
computed PayLoadSize to
+ // overflow to a small value and pass the check in InitCommunicateBuffer().
+ // To protect against this vulnerability, return EFI_INVALID_PARAMETER if
DataSize is >= mVariableBufferSize.
+ // And there will be further check to ensure the total size is also not >
mVariableBufferSize.
+ //
+ return EFI_INVALID_PARAMETER;
+ }
+
AcquireLockOnlyAtBootTime(&mVariableServicesLock);
//
Modified:
branches/UDK2010.SR1/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c
===================================================================
---
branches/UDK2010.SR1/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c
2013-04-18 05:32:02 UTC (rev 14286)
+++
branches/UDK2010.SR1/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c
2013-04-18 05:37:12 UTC (rev 14287)
@@ -15,7 +15,7 @@
TcgMeasureGptTable() function will receive untrusted GPT partition table,
and parse
partition data carefully.
-Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD
License
which accompanies this distribution. The full text of the license may be
found at
@@ -664,6 +664,14 @@
&EventNumber,
&EventLogLastEntry
);
+ if (Status == EFI_OUT_OF_RESOURCES) {
+ //
+ // Out of resource here means the image is hashed and its result is
extended to PCR.
+ // But the event log cann't be saved since log area is full.
+ // Just return EFI_SUCCESS in order not to block the image load.
+ //
+ Status = EFI_SUCCESS;
+ }
Finish:
FreePool (TcgEvent);
Modified:
branches/UDK2010.SR1/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c
===================================================================
---
branches/UDK2010.SR1/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c
2013-04-18 05:32:02 UTC (rev 14286)
+++
branches/UDK2010.SR1/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c
2013-04-18 05:37:12 UTC (rev 14287)
@@ -2810,6 +2810,11 @@
ASSERT(VariableStoreHeader->Size == VariableStoreLength);
//
+ // The max variable or hardware error variable size should be < variable
store size.
+ //
+ ASSERT(MAX (PcdGet32 (PcdMaxVariableSize), PcdGet32
(PcdMaxHardwareErrorVariableSize)) < VariableStoreLength);
+
+ //
// Parse non-volatile variable data and get last variable offset.
//
NextVariable = GetStartPointer ((VARIABLE_STORE_HEADER
*)(UINTN)VariableStoreBase);
Modified:
branches/UDK2010.SR1/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.c
===================================================================
---
branches/UDK2010.SR1/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.c
2013-04-18 05:32:02 UTC (rev 14286)
+++
branches/UDK2010.SR1/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.c
2013-04-18 05:37:12 UTC (rev 14287)
@@ -214,6 +214,16 @@
return EFI_INVALID_PARAMETER;
}
+ if (*DataSize >= mVariableBufferSize) {
+ //
+ // DataSize may be near MAX_ADDRESS incorrectly, this can cause the
computed PayLoadSize to
+ // overflow to a small value and pass the check in InitCommunicateBuffer().
+ // To protect against this vulnerability, return EFI_INVALID_PARAMETER if
DataSize is >= mVariableBufferSize.
+ // And there will be further check to ensure the total size is also not >
mVariableBufferSize.
+ //
+ return EFI_INVALID_PARAMETER;
+ }
+
AcquireLockOnlyAtBootTime(&mVariableServicesLock);
//
@@ -286,27 +296,57 @@
EFI_STATUS Status;
UINTN PayloadSize;
SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME *SmmGetNextVariableName;
+ UINTN SmmCommBufPayloadSize;
if (VariableNameSize == NULL || VariableName == NULL || VendorGuid == NULL) {
return EFI_INVALID_PARAMETER;
}
+ //
+ // SMM Communication Buffer max payload size
+ //
+ SmmCommBufPayloadSize = mVariableBufferSize - (SMM_COMMUNICATE_HEADER_SIZE +
SMM_VARIABLE_COMMUNICATE_HEADER_SIZE);
+
+ //
+ // If input string exceeds SMM payload limit. Return failure
+ //
+ if (StrSize (VariableName) > SmmCommBufPayloadSize - OFFSET_OF
(SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
AcquireLockOnlyAtBootTime(&mVariableServicesLock);
//
// Init the communicate buffer. The buffer data size is:
// SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE +
PayloadSize.
//
- PayloadSize = OFFSET_OF (SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME,
Name) + *VariableNameSize;
+ if (*VariableNameSize > SmmCommBufPayloadSize - OFFSET_OF
(SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name)) {
+ //
+ // If output buffer exceed SMM payload limit. Trim output buffer to SMM
payload size
+ //
+ *VariableNameSize = SmmCommBufPayloadSize - OFFSET_OF
(SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name);
+ }
+ //
+ // Payload should be Guid + NameSize + MAX of Input & Output buffer
+ //
+ PayloadSize = OFFSET_OF (SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME,
Name) + MAX (*VariableNameSize, StrSize (VariableName));
+
Status = InitCommunicateBuffer ((VOID **)&SmmGetNextVariableName,
PayloadSize, SMM_VARIABLE_FUNCTION_GET_NEXT_VARIABLE_NAME);
if (EFI_ERROR (Status)) {
goto Done;
}
ASSERT (SmmGetNextVariableName != NULL);
+ //
+ // SMM comm buffer->NameSize is buffer size for return string
+ //
SmmGetNextVariableName->NameSize = *VariableNameSize;
+
CopyGuid (&SmmGetNextVariableName->Guid, VendorGuid);
- CopyMem (SmmGetNextVariableName->Name, VariableName, *VariableNameSize);
+ //
+ // Copy whole string
+ //
+ CopyMem (SmmGetNextVariableName->Name, VariableName, StrSize (VariableName));
//
// Send data to SMM
@@ -374,6 +414,16 @@
return EFI_INVALID_PARAMETER;
}
+ if (DataSize >= mVariableBufferSize) {
+ //
+ // DataSize may be near MAX_ADDRESS incorrectly, this can cause the
computed PayLoadSize to
+ // overflow to a small value and pass the check in InitCommunicateBuffer().
+ // To protect against this vulnerability, return EFI_INVALID_PARAMETER if
DataSize is >= mVariableBufferSize.
+ // And there will be further check to ensure the total size is also not >
mVariableBufferSize.
+ //
+ return EFI_INVALID_PARAMETER;
+ }
+
AcquireLockOnlyAtBootTime(&mVariableServicesLock);
//
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
Precog is a next-generation analytics platform capable of advanced
analytics on semi-structured data. The platform includes APIs for building
apps and a phenomenal toolset for data science. Developers can use
our toolset for easy data analysis & visualization. Get a free account!
http://www2.precog.com/precogplatform/slashdotnewsletter
_______________________________________________
edk2-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-commits