summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/AArch64/DynamicCookieGcc.S56
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/DxeCore/DxeCoreEntryPoint.c70
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/DxeCore/DxeCoreEntryPoint.uni16
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/DxeCoreEntryPoint.inf45
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/IA32/DynamicCookieGcc.nasm63
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/IA32/DynamicCookieMsvc.nasm63
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/PeiCore/PeiCoreEntryPoint.c93
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/PeiCore/PeiCoreEntryPoint.uni16
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/PeiCore/PeiCoreStackCheckEntryPointLibNull.c66
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/PeiCoreEntryPoint.inf44
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/Peim/PeimEntryPoint.c72
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/Peim/PeimEntryPoint.uni16
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/Peim/PeimStackCheckEntryPointLibNull.c46
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/PeimEntryPoint.inf43
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmCore/X64/StandaloneMmCoreEntryPoint.c65
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmCoreEntryPoint.inf38
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmDriver/StandaloneMmDriverEntryPoint.c135
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmDriver/StandaloneMmDriverEntryPoint.uni17
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmDriverEntryPoint.inf53
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplication/ApplicationEntryPoint.c112
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplication/ApplicationStackCheckEntryPointLibNull.c50
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplication/UefiApplicationEntryPoint.uni16
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplicationEntryPoint.inf45
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/UefiDriver/DriverEntryPoint.c162
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/UefiDriver/UefiDriverEntryPoint.uni16
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/UefiDriverEntryPoint.inf68
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/X64/DynamicCookieGcc.nasm63
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/X64/DynamicCookieMsvc.nasm63
-rw-r--r--MdePkg/Library/StackCheckLib/Readme.md198
-rw-r--r--MdePkg/MdeLibs.dsc.inc36
-rw-r--r--MdePkg/MdePkg.dsc7
31 files changed, 1779 insertions, 74 deletions
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/AArch64/DynamicCookieGcc.S b/MdePkg/Library/DynamicStackCookieEntryPointLib/AArch64/DynamicCookieGcc.S
new file mode 100644
index 0000000000..d33c02a7c4
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/AArch64/DynamicCookieGcc.S
@@ -0,0 +1,56 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+# Module Name:
+#
+# DynamicCookie.S
+#
+# Abstract:
+#
+# Generates random number through the RNDR instruction on a 64-bit AARCH64 platform
+# to store a random value in the GCC __stack_check_guard stack cookie.
+# The first byte is 0'd to prevent string copy functions from clobbering
+# the stack cookie.
+#
+# Notes:
+#
+# If RNDR fails, the build time static stack cookie value will be used instead.
+#
+#------------------------------------------------------------------------------
+
+#include <AArch64/AArch64.h>
+
+.text
+.p2align 2
+
+GCC_ASM_IMPORT(__stack_chk_guard)
+GCC_ASM_IMPORT(_CModuleEntryPoint)
+GCC_ASM_EXPORT(_ModuleEntryPoint)
+
+#------------------------------------------------------------------------------
+# VOID
+# EFIAPI
+# _ModuleEntryPoint (
+# Parameters are passed through.
+# )
+#------------------------------------------------------------------------------
+ASM_PFX(_ModuleEntryPoint):
+ AARCH64_BTI(c)
+
+ mrs x9, ID_AA64ISAR0_EL1 // Read the AArch64 Instruction Set Attribute Register 0
+ ubfx x9, x9, #60, #4 // Extract the RNDR bit field (bits 60-63)
+ cbz x9, c_entry // If RNDR is not supported, jump to c_entry
+
+ mrs x9, RNDR // Generate a random number
+ b.eq c_entry // RNDR sets NZCV to 0b0100 on failure
+ // So if the zero flag is set, use the static stack guard
+
+ and x9, x9, #0xFFFFFFFFFFFFFF00 // Zero the first byte of the random value
+
+ adrp x8, ASM_PFX(__stack_chk_guard) // Load the page address of __stack_chk_guard
+ str x9, [x8, :lo12:ASM_PFX(__stack_chk_guard)] // Store the random value in __stack_chk_guard
+
+c_entry:
+ b ASM_PFX(_CModuleEntryPoint) // Jump to the C module entry point
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/DxeCore/DxeCoreEntryPoint.c b/MdePkg/Library/DynamicStackCookieEntryPointLib/DxeCore/DxeCoreEntryPoint.c
new file mode 100644
index 0000000000..986ab25b31
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/DxeCore/DxeCoreEntryPoint.c
@@ -0,0 +1,70 @@
+/** @file
+ Entry point to the DXE Core.
+
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiDxe.h>
+
+#include <Library/DxeCoreEntryPoint.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+
+//
+// Cache copy of HobList pointer.
+//
+VOID *gHobList = NULL;
+
+/**
+ The entry point of PE/COFF Image for the DXE Core.
+
+ This function is the entry point for the DXE Core. This function is required to call
+ ProcessModuleEntryPointList() and ProcessModuleEntryPointList() is never expected to return.
+ The DXE Core is responsible for calling ProcessLibraryConstructorList() as soon as the EFI
+ System Table and the image handle for the DXE Core itself have been established.
+ If ProcessModuleEntryPointList() returns, then ASSERT() and halt the system.
+
+ @param HobStart The pointer to the beginning of the HOB List passed in from the PEI Phase.
+
+**/
+VOID
+EFIAPI
+_CModuleEntryPoint (
+ IN VOID *HobStart
+ )
+{
+ //
+ // Cache a pointer to the HobList
+ //
+ gHobList = HobStart;
+
+ //
+ // Call the DXE Core entry point
+ //
+ ProcessModuleEntryPointList (HobStart);
+
+ //
+ // Should never return
+ //
+ ASSERT (FALSE);
+ CpuDeadLoop ();
+}
+
+/**
+ Required by the EBC compiler and identical in functionality to _ModuleEntryPoint().
+
+ This function is required to call _ModuleEntryPoint() passing in HobStart.
+
+ @param HobStart The pointer to the beginning of the HOB List passed in from the PEI Phase.
+
+**/
+VOID
+EFIAPI
+EfiMain (
+ IN VOID *HobStart
+ )
+{
+ _ModuleEntryPoint (HobStart);
+}
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/DxeCore/DxeCoreEntryPoint.uni b/MdePkg/Library/DynamicStackCookieEntryPointLib/DxeCore/DxeCoreEntryPoint.uni
new file mode 100644
index 0000000000..af26f0bec4
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/DxeCore/DxeCoreEntryPoint.uni
@@ -0,0 +1,16 @@
+// /** @file
+// Module entry point library for DXE core.
+//
+// Module entry point library for DXE core.
+//
+// Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "Module entry point library for DXE core"
+
+#string STR_MODULE_DESCRIPTION #language en-US "Module entry point library for DXE core."
+
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/DxeCoreEntryPoint.inf b/MdePkg/Library/DynamicStackCookieEntryPointLib/DxeCoreEntryPoint.inf
new file mode 100644
index 0000000000..ea84987678
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/DxeCoreEntryPoint.inf
@@ -0,0 +1,45 @@
+## @file
+# Module entry point library for DXE core that dynamically updates the stack cookie.
+#
+# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = DxeCoreEntryPointDynamicInit
+ MODULE_UNI_FILE = DxeCore/DxeCoreEntryPoint.uni
+ FILE_GUID = FD044D85-1407-4043-B527-471F16ABD8C6
+ MODULE_TYPE = DXE_CORE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = DxeCoreEntryPoint|DXE_CORE
+
+
+#
+# VALID_ARCHITECTURES = IA32 X64 AARCH64
+#
+
+[Sources]
+ DxeCore/DxeCoreEntryPoint.c
+
+[Sources.IA32]
+ IA32/DynamicCookieGcc.nasm | GCC
+ IA32/DynamicCookieMsvc.nasm | MSFT
+
+[Sources.X64]
+ X64/DynamicCookieGcc.nasm | GCC
+ X64/DynamicCookieMsvc.nasm | MSFT
+
+[Sources.AARCH64]
+ AArch64/DynamicCookieGcc.S | GCC
+
+[Packages]
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ StackCheckLib
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/IA32/DynamicCookieGcc.nasm b/MdePkg/Library/DynamicStackCookieEntryPointLib/IA32/DynamicCookieGcc.nasm
new file mode 100644
index 0000000000..ae8db569dc
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/IA32/DynamicCookieGcc.nasm
@@ -0,0 +1,63 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) Microsoft Corporation.
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+; Module Name:
+;
+; DynamicCookie.nasm
+;
+; Abstract:
+;
+; Generates random number through CPU RdRand instruction on a 32-bit platform
+; to store a random value in the GCC __stack_check_guard stack cookie.
+; The first byte is 0'd to prevent string copy functions from clobbering
+; the stack cookie.
+;
+; Notes:
+;
+; If RdRand fails, the build time static stack cookie value will be used instead.
+;
+;------------------------------------------------------------------------------
+
+SECTION .text
+
+extern ASM_PFX(__stack_chk_guard)
+extern ASM_PFX(_CModuleEntryPoint)
+global ASM_PFX(_ModuleEntryPoint)
+
+;------------------------------------------------------------------------------
+; VOID
+; EFIAPI
+; _ModuleEntryPoint (
+; Parameters are passed through
+; );
+;------------------------------------------------------------------------------
+global _ModuleEntryPoint
+_ModuleEntryPoint:
+ push ebx
+ push ecx
+ push edx
+
+ mov eax, 1 ; CPUID function 1
+ cpuid
+ test ecx, 0x40000000 ; Check if the RdRand bit (bit 30) is set in ECX
+ jz c_entry ; If not set, jump to c_entry
+
+ rdrand eax ; Use rdrand, getting a 32 bit value as on
+ ; IA32, __stack_chk_guard is a 32 bit value.
+ ; CF=1 if RN generated ok, otherwise CF=0
+ jnc c_entry ; If the cmd fails, don't update __stack_chk_guard, we'll have to move forward
+ ; with the static value provided at build time.
+
+ lea ebx, [ASM_PFX(__stack_chk_guard)] ; load the address of __stack_chk_guard into ebx
+
+ xor ah, ah ; Zero a byte of the __stack_chk_guard value to protect against string functions
+ ; (such as strcpy like functions) clobbering past the canary
+ mov [ebx], eax ; Store our random value, with 0'd first byte to __stack_chk_guard
+
+c_entry:
+ pop edx
+ pop ecx
+ pop ebx
+ jmp ASM_PFX(_CModuleEntryPoint)
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/IA32/DynamicCookieMsvc.nasm b/MdePkg/Library/DynamicStackCookieEntryPointLib/IA32/DynamicCookieMsvc.nasm
new file mode 100644
index 0000000000..efd43c04a3
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/IA32/DynamicCookieMsvc.nasm
@@ -0,0 +1,63 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) Microsoft Corporation.
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+; Module Name:
+;
+; DynamicCookie.nasm
+;
+; Abstract:
+;
+; Generates random number through CPU RdRand instruction on a 32-bit platform
+; to store a random value in the GCC __stack_check_guard stack cookie.
+; The first byte is 0'd to prevent string copy functions from clobbering
+; the stack cookie.
+;
+; Notes:
+;
+; If RdRand fails, the build time static stack cookie value will be used instead.
+;
+;------------------------------------------------------------------------------
+
+SECTION .text
+
+extern ASM_PFX(__security_cookie)
+extern ASM_PFX(_CModuleEntryPoint)
+global ASM_PFX(_ModuleEntryPoint)
+
+;------------------------------------------------------------------------------
+; VOID
+; EFIAPI
+; _ModuleEntryPoint (
+; Parameters are passed through
+; );
+;------------------------------------------------------------------------------
+global _ModuleEntryPoint
+_ModuleEntryPoint:
+ push ebx
+ push ecx
+ push edx
+
+ mov eax, 1 ; CPUID function 1
+ cpuid
+ test ecx, 0x40000000 ; Check if the RdRand bit (bit 30) is set in ECX
+ jz c_entry ; If not set, jump to c_entry
+
+ rdrand eax ; Use rdrand, getting a 32 bit value as on
+ ; IA32, __security_cookie is a 32 bit value.
+ ; CF=1 if RN generated ok, otherwise CF=0
+ jnc c_entry ; If the cmd fails, don't update __security_cookie, we'll have to move forward
+ ; with the static value provided at build time.
+
+ lea ebx, [ASM_PFX(__security_cookie)] ; load the address of __stack_chk_guard into ebx
+
+ xor ah, ah ; Zero a byte of the __security_cookie value to protect against string functions
+ ; (such as strcpy like functions) clobbering past the canary
+ mov [ebx], eax ; Store our random value, with 0'd first byte to __security_cookie
+
+c_entry:
+ pop edx
+ pop ecx
+ pop ebx
+ jmp ASM_PFX(_CModuleEntryPoint)
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/PeiCore/PeiCoreEntryPoint.c b/MdePkg/Library/DynamicStackCookieEntryPointLib/PeiCore/PeiCoreEntryPoint.c
new file mode 100644
index 0000000000..bcc9c2ce35
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/PeiCore/PeiCoreEntryPoint.c
@@ -0,0 +1,93 @@
+/** @file
+ Entry point to a the PEI Core.
+
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+
+//
+// The Library classes this module produced
+//
+#include <Library/PeiCoreEntryPoint.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+
+/**
+ The entry point of PE/COFF Image for the PEI Core.
+
+ This function is the entry point for the PEI Foundation, which allows the SEC phase
+ to pass information about the stack, temporary RAM and the Boot Firmware Volume.
+ In addition, it also allows the SEC phase to pass services and data forward for use
+ during the PEI phase in the form of one or more PPIs.
+ There is no limit to the number of additional PPIs that can be passed from SEC into
+ the PEI Foundation. As part of its initialization phase, the PEI Foundation will add
+ these SEC-hosted PPIs to its PPI database such that both the PEI Foundation and any
+ modules can leverage the associated service calls and/or code in these early PPIs.
+ This function is required to call ProcessModuleEntryPointList() with the Context
+ parameter set to NULL. ProcessModuleEntryPoint() is never expected to return.
+ The PEI Core is responsible for calling ProcessLibraryConstructorList() as soon as
+ the PEI Services Table and the file handle for the PEI Core itself have been established.
+ If ProcessModuleEntryPointList() returns, then ASSERT() and halt the system.
+
+ @param SecCoreData Points to a data structure containing information about the
+ PEI core's operating environment, such as the size and
+ location of temporary RAM, the stack location and the BFV
+ location.
+
+ @param PpiList Points to a list of one or more PPI descriptors to be
+ installed initially by the PEI core. An empty PPI list
+ consists of a single descriptor with the end-tag
+ EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST.
+ As part of its initialization phase, the PEI Foundation will
+ add these SEC-hosted PPIs to its PPI database, such that both
+ the PEI Foundation and any modules can leverage the associated
+ service calls and/or code in these early PPIs.
+
+**/
+VOID
+EFIAPI
+_CModuleEntryPoint (
+ IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
+ IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList
+ )
+{
+ ProcessModuleEntryPointList (SecCoreData, PpiList, NULL);
+
+ //
+ // Should never return
+ //
+ ASSERT (FALSE);
+ CpuDeadLoop ();
+}
+
+/**
+ Required by the EBC compiler and identical in functionality to _ModuleEntryPoint().
+
+ This function is required to call _CModuleEntryPoint() passing in SecCoreData and PpiList.
+
+ @param SecCoreData Points to a data structure containing information about the PEI core's
+ operating environment, such as the size and location of temporary RAM,
+ the stack location and the BFV location.
+
+ @param PpiList Points to a list of one or more PPI descriptors to be installed
+ initially by the PEI core. An empty PPI list consists of
+ a single descriptor with the end-tag
+ EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST.
+ As part of its initialization phase, the PEI Foundation will
+ add these SEC-hosted PPIs to its PPI database, such that both
+ the PEI Foundationand any modules can leverage the associated
+ service calls and/or code in these early PPIs.
+
+**/
+VOID
+EFIAPI
+EfiMain (
+ IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
+ IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList
+ )
+{
+ _CModuleEntryPoint (SecCoreData, PpiList);
+}
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/PeiCore/PeiCoreEntryPoint.uni b/MdePkg/Library/DynamicStackCookieEntryPointLib/PeiCore/PeiCoreEntryPoint.uni
new file mode 100644
index 0000000000..f4c12c0e60
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/PeiCore/PeiCoreEntryPoint.uni
@@ -0,0 +1,16 @@
+// /** @file
+// Module entry point library for PEI core.
+//
+// Module entry point library for PEI core.
+//
+// Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "Module entry point library for PEI core"
+
+#string STR_MODULE_DESCRIPTION #language en-US "Module entry point library for PEI core."
+
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/PeiCore/PeiCoreStackCheckEntryPointLibNull.c b/MdePkg/Library/DynamicStackCookieEntryPointLib/PeiCore/PeiCoreStackCheckEntryPointLibNull.c
new file mode 100644
index 0000000000..c698cc640c
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/PeiCore/PeiCoreStackCheckEntryPointLibNull.c
@@ -0,0 +1,66 @@
+/** @file
+ Entry point to a the PEI Core that does not update the stack cookie dynamically.
+
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+
+//
+// The Library classes this module produced
+//
+#include <Library/PeiCoreEntryPoint.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+
+extern
+VOID
+EFIAPI
+_CModuleEntryPoint (
+ IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
+ IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList
+ );
+
+/**
+ The entry point of PE/COFF Image for the PEI Core.
+
+ This function is the entry point for the PEI Foundation, which allows the SEC phase
+ to pass information about the stack, temporary RAM and the Boot Firmware Volume.
+ In addition, it also allows the SEC phase to pass services and data forward for use
+ during the PEI phase in the form of one or more PPIs.
+ There is no limit to the number of additional PPIs that can be passed from SEC into
+ the PEI Foundation. As part of its initialization phase, the PEI Foundation will add
+ these SEC-hosted PPIs to its PPI database such that both the PEI Foundation and any
+ modules can leverage the associated service calls and/or code in these early PPIs.
+ This function is required to call ProcessModuleEntryPointList() with the Context
+ parameter set to NULL. ProcessModuleEntryPoint() is never expected to return.
+ The PEI Core is responsible for calling ProcessLibraryConstructorList() as soon as
+ the PEI Services Table and the file handle for the PEI Core itself have been established.
+ If ProcessModuleEntryPointList() returns, then ASSERT() and halt the system.
+
+ @param SecCoreData Points to a data structure containing information about the
+ PEI core's operating environment, such as the size and
+ location of temporary RAM, the stack location and the BFV
+ location.
+
+ @param PpiList Points to a list of one or more PPI descriptors to be
+ installed initially by the PEI core. An empty PPI list
+ consists of a single descriptor with the end-tag
+ EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST.
+ As part of its initialization phase, the PEI Foundation will
+ add these SEC-hosted PPIs to its PPI database, such that both
+ the PEI Foundation and any modules can leverage the associated
+ service calls and/or code in these early PPIs.
+
+**/
+VOID
+EFIAPI
+_ModuleEntryPoint (
+ IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
+ IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList
+ )
+{
+ _CModuleEntryPoint (SecCoreData, PpiList);
+}
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/PeiCoreEntryPoint.inf b/MdePkg/Library/DynamicStackCookieEntryPointLib/PeiCoreEntryPoint.inf
new file mode 100644
index 0000000000..9ac20b8659
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/PeiCoreEntryPoint.inf
@@ -0,0 +1,44 @@
+## @file
+# Module entry point library for PEI core that dynamically updates the stack cookie.
+#
+# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = PeiCoreEntryPointDynamicInit
+ MODULE_UNI_FILE = PeiCore/PeiCoreEntryPoint.uni
+ FILE_GUID = 2627DFCD-054D-403E-B812-E67034865D29
+ MODULE_TYPE = PEI_CORE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = PeiCoreEntryPoint|PEI_CORE
+
+#
+# VALID_ARCHITECTURES = IA32 X64 AARCH64
+#
+
+[Sources]
+ PeiCore/PeiCoreEntryPoint.c
+
+[Sources.IA32]
+ IA32/DynamicCookieGcc.nasm | GCC
+ IA32/DynamicCookieMsvc.nasm | MSFT
+
+[Sources.X64]
+ X64/DynamicCookieGcc.nasm | GCC
+ X64/DynamicCookieMsvc.nasm | MSFT
+
+[Sources.AARCH64]
+ AArch64/DynamicCookieGcc.S | GCC
+
+[Packages]
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ StackCheckLib
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/Peim/PeimEntryPoint.c b/MdePkg/Library/DynamicStackCookieEntryPointLib/Peim/PeimEntryPoint.c
new file mode 100644
index 0000000000..da03d61dac
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/Peim/PeimEntryPoint.c
@@ -0,0 +1,72 @@
+/** @file
+ Entry point to a PEIM.
+
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+
+#include <Library/PeimEntryPoint.h>
+#include <Library/DebugLib.h>
+
+/**
+ The entry point of PE/COFF Image for a PEIM.
+
+ This function is the entry point for a PEIM. This function must call ProcessLibraryConstructorList()
+ and ProcessModuleEntryPointList(). The return value from ProcessModuleEntryPointList() is returned.
+ If _gPeimRevision is not zero and PeiServices->Hdr.Revision is less than _gPeimRevison, then ASSERT().
+
+ @param FileHandle Handle of the file being invoked.
+ @param PeiServices Describes the list of possible PEI Services.
+
+ @retval EFI_SUCCESS The PEIM executed normally.
+ @retval !EFI_SUCCESS The PEIM failed to execute normally.
+**/
+EFI_STATUS
+EFIAPI
+_CModuleEntryPoint (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ if (_gPeimRevision != 0) {
+ //
+ // Make sure that the PEI spec revision of the platform is >= PEI spec revision of the driver
+ //
+ ASSERT ((*PeiServices)->Hdr.Revision >= _gPeimRevision);
+ }
+
+ //
+ // Call constructor for all libraries
+ //
+ ProcessLibraryConstructorList (FileHandle, PeiServices);
+
+ //
+ // Call the driver entry point
+ //
+ return ProcessModuleEntryPointList (FileHandle, PeiServices);
+}
+
+/**
+ Required by the EBC compiler and identical in functionality to _ModuleEntryPoint().
+
+ This function is required to call _ModuleEntryPoint() passing in FileHandle and PeiServices.
+
+ @param FileHandle Handle of the file being invoked.
+ @param PeiServices Describes the list of possible PEI Services.
+
+ @retval EFI_SUCCESS The PEIM executed normally.
+ @retval !EFI_SUCCESS The PEIM failed to execute normally.
+
+**/
+EFI_STATUS
+EFIAPI
+EfiMain (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ return _CModuleEntryPoint (FileHandle, PeiServices);
+}
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/Peim/PeimEntryPoint.uni b/MdePkg/Library/DynamicStackCookieEntryPointLib/Peim/PeimEntryPoint.uni
new file mode 100644
index 0000000000..bae3abaeb2
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/Peim/PeimEntryPoint.uni
@@ -0,0 +1,16 @@
+// /** @file
+// Module entry point library for PEIM.
+//
+// Module entry point library for PEIM.
+//
+// Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "Module entry point library for PEIM"
+
+#string STR_MODULE_DESCRIPTION #language en-US "Module entry point library for PEIM."
+
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/Peim/PeimStackCheckEntryPointLibNull.c b/MdePkg/Library/DynamicStackCookieEntryPointLib/Peim/PeimStackCheckEntryPointLibNull.c
new file mode 100644
index 0000000000..aa4a55d8d6
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/Peim/PeimStackCheckEntryPointLibNull.c
@@ -0,0 +1,46 @@
+/** @file
+ Entry point to a PEIM that does not update the stack cookie dynamically.
+
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+
+#include <Library/PeimEntryPoint.h>
+#include <Library/DebugLib.h>
+
+extern
+EFI_STATUS
+EFIAPI
+_CModuleEntryPoint (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ );
+
+/**
+ The entry point of PE/COFF Image for a PEIM.
+
+ This function is the entry point for a PEIM. This function must call ProcessLibraryConstructorList()
+ and ProcessModuleEntryPointList(). The return value from ProcessModuleEntryPointList() is returned.
+ If _gPeimRevision is not zero and PeiServices->Hdr.Revision is less than _gPeimRevison, then ASSERT().
+
+ @param FileHandle Handle of the file being invoked.
+ @param PeiServices Describes the list of possible PEI Services.
+
+ @retval EFI_SUCCESS The PEIM executed normally.
+ @retval !EFI_SUCCESS The PEIM failed to execute normally.
+**/
+EFI_STATUS
+EFIAPI
+_ModuleEntryPoint (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ //
+ // Call the driver entry point
+ //
+ return _CModuleEntryPoint (FileHandle, PeiServices);
+}
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/PeimEntryPoint.inf b/MdePkg/Library/DynamicStackCookieEntryPointLib/PeimEntryPoint.inf
new file mode 100644
index 0000000000..b6b8f0a94f
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/PeimEntryPoint.inf
@@ -0,0 +1,43 @@
+## @file
+# Module entry point library for PEIM that dynamically updates the stack cookie.
+#
+# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = PeimEntryPointDynamicInit
+ MODULE_UNI_FILE = Peim/PeimEntryPoint.uni
+ FILE_GUID = 0E53AFCB-7FDD-461E-B8CE-6DA9F3F9014C
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = PeimEntryPoint|PEIM
+
+#
+# VALID_ARCHITECTURES = IA32 X64 AARCH64
+#
+
+[Sources]
+ Peim/PeimEntryPoint.c
+
+[Sources.IA32]
+ IA32/DynamicCookieGcc.nasm | GCC
+ IA32/DynamicCookieMsvc.nasm | MSFT
+
+[Sources.X64]
+ X64/DynamicCookieGcc.nasm | GCC
+ X64/DynamicCookieMsvc.nasm | MSFT
+
+[Sources.AARCH64]
+ AArch64/DynamicCookieGcc.S | GCC
+
+[Packages]
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ DebugLib
+ StackCheckLib
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmCore/X64/StandaloneMmCoreEntryPoint.c b/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmCore/X64/StandaloneMmCoreEntryPoint.c
new file mode 100644
index 0000000000..f68fa193e1
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmCore/X64/StandaloneMmCoreEntryPoint.c
@@ -0,0 +1,65 @@
+/** @file
+ Entry point to the Standalone Mm Core.
+
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+Copyright (c) Microsoft Corporation.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiMm.h>
+
+#include <Library/StandaloneMmCoreEntryPoint.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+
+//
+// Cache copy of HobList pointer.
+//
+VOID *gHobList = NULL;
+
+/**
+ The entry point of PE/COFF Image for the STANDALONE MM Core.
+
+ This function is the entry point for the STANDALONE MM Core. This function is required to call
+ ProcessModuleEntryPointList() and ProcessModuleEntryPointList() is never expected to return.
+ The STANDALONE MM Core is responsible for calling ProcessLibraryConstructorList() as soon as the EFI
+ System Table and the image handle for the STANDALONE MM Core itself have been established.
+ If ProcessModuleEntryPointList() returns, then ASSERT() and halt the system.
+
+ @param HobStart Pointer to the beginning of the HOB List passed in from the PEI Phase.
+
+**/
+VOID
+EFIAPI
+_CModuleEntryPoint (
+ IN VOID *HobStart
+ )
+{
+ //
+ // Cache a pointer to the HobList
+ //
+ gHobList = HobStart;
+
+ //
+ // Call the Standalone MM Core entry point
+ //
+ ProcessModuleEntryPointList (HobStart);
+}
+
+/**
+ Required by the EBC compiler and identical in functionality to _ModuleEntryPoint().
+
+ This function is required to call _ModuleEntryPoint() passing in HobStart.
+
+ @param HobStart Pointer to the beginning of the HOB List passed in from the PEI Phase.
+
+**/
+VOID
+EFIAPI
+EfiMain (
+ IN VOID *HobStart
+ )
+{
+ _ModuleEntryPoint (HobStart);
+}
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmCoreEntryPoint.inf b/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmCoreEntryPoint.inf
new file mode 100644
index 0000000000..41361dde53
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmCoreEntryPoint.inf
@@ -0,0 +1,38 @@
+## @file
+# Module entry point library for StandaloneMm core that dynamically updates the stack cookie.
+# The AARCH64 version of this library lives in ArmPkg.
+#
+# Copyright (c) 2017 - 2021, Arm Ltd. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x0001001A
+ BASE_NAME = StandaloneMmCoreEntryPointDynamicInit
+ FILE_GUID = 490073A1-4DBC-4E9E-B30D-A4204139FC5F
+ MODULE_TYPE = MM_CORE_STANDALONE
+ VERSION_STRING = 1.0
+ PI_SPECIFICATION_VERSION = 0x00010032
+ LIBRARY_CLASS = StandaloneMmCoreEntryPoint|MM_CORE_STANDALONE
+
+#
+# VALID_ARCHITECTURES = X64
+#
+
+[Sources.X64]
+ StandaloneMmCore/X64/StandaloneMmCoreEntryPoint.c
+
+[Sources.X64]
+ X64/DynamicCookieGcc.nasm | GCC
+ X64/DynamicCookieMsvc.nasm | MSFT
+
+[Packages]
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ StackCheckLib
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmDriver/StandaloneMmDriverEntryPoint.c b/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmDriver/StandaloneMmDriverEntryPoint.c
new file mode 100644
index 0000000000..4241ef3058
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmDriver/StandaloneMmDriverEntryPoint.c
@@ -0,0 +1,135 @@
+/** @file
+ Entry point to a Standalone MM driver.
+
+Copyright (c) 2015 - 2021, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2016 - 2018, ARM Ltd. All rights reserved.<BR>
+Copyright (c) 2018, Linaro, Limited. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiMm.h>
+
+#include <Protocol/LoadedImage.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MmServicesTableLib.h>
+#include <Library/StandaloneMmDriverEntryPoint.h>
+
+/**
+ Unloads an image from memory.
+
+ This function is a callback that a driver registers to do cleanup
+ when the UnloadImage boot service function is called.
+
+ @param ImageHandle The handle to the image to unload.
+
+ @return Status returned by all unload().
+
+**/
+EFI_STATUS
+EFIAPI
+_DriverUnloadHandler (
+ EFI_HANDLE ImageHandle
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // If an UnloadImage() handler is specified, then call it
+ //
+ Status = ProcessModuleUnloadList (ImageHandle);
+
+ //
+ // If the driver specific unload handler does not return an error, then call all of the
+ // library destructors. If the unload handler returned an error, then the driver can not be
+ // unloaded, and the library destructors should not be called
+ //
+ if (!EFI_ERROR (Status)) {
+ ProcessLibraryDestructorList (ImageHandle, gMmst);
+ }
+
+ //
+ // Return the status from the driver specific unload handler
+ //
+ return Status;
+}
+
+/**
+ The entry point of PE/COFF Image for a Standalone MM Driver.
+
+ This function is the entry point for a Standalone MM Driver.
+ This function must call ProcessLibraryConstructorList() and
+ ProcessModuleEntryPointList().
+ If the return status from ProcessModuleEntryPointList()
+ is an error status, then ProcessLibraryDestructorList() must be called.
+ The return value from ProcessModuleEntryPointList() is returned.
+ If _gMmRevision is not zero and SystemTable->Hdr.Revision is
+ less than _gMmRevision, then return EFI_INCOMPATIBLE_VERSION.
+
+ @param ImageHandle The image handle of the Standalone MM Driver.
+ @param MmSystemTable A pointer to the MM System Table.
+
+ @retval EFI_SUCCESS The Standalone MM Driver exited normally.
+ @retval EFI_INCOMPATIBLE_VERSION _gMmRevision is greater than
+ MmSystemTable->Hdr.Revision.
+ @retval Other Return value from
+ ProcessModuleEntryPointList().
+
+**/
+EFI_STATUS
+EFIAPI
+_CModuleEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN IN EFI_MM_SYSTEM_TABLE *MmSystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
+
+ if (_gMmRevision != 0) {
+ //
+ // Make sure that the MM spec revision of the platform
+ // is >= MM spec revision of the driver
+ //
+ if (MmSystemTable->Hdr.Revision < _gMmRevision) {
+ return EFI_INCOMPATIBLE_VERSION;
+ }
+ }
+
+ //
+ // Call constructor for all libraries
+ //
+ ProcessLibraryConstructorList (ImageHandle, MmSystemTable);
+
+ //
+ // Install unload handler...
+ //
+ if (_gDriverUnloadImageCount != 0) {
+ Status = gMmst->MmHandleProtocol (
+ ImageHandle,
+ &gEfiLoadedImageProtocolGuid,
+ (VOID **)&LoadedImage
+ );
+ ASSERT_EFI_ERROR (Status);
+ LoadedImage->Unload = _DriverUnloadHandler;
+ }
+
+ //
+ // Call the driver entry point
+ //
+ Status = ProcessModuleEntryPointList (ImageHandle, MmSystemTable);
+
+ //
+ // If all of the drivers returned errors, then invoke all of the library destructors
+ //
+ if (EFI_ERROR (Status)) {
+ ProcessLibraryDestructorList (ImageHandle, MmSystemTable);
+ }
+
+ //
+ // Return the cumulative return status code from all of the driver entry points
+ //
+ return Status;
+}
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmDriver/StandaloneMmDriverEntryPoint.uni b/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmDriver/StandaloneMmDriverEntryPoint.uni
new file mode 100644
index 0000000000..917ae95144
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmDriver/StandaloneMmDriverEntryPoint.uni
@@ -0,0 +1,17 @@
+// /** @file
+//
+// Module entry point library for standalone MM driver
+//
+// Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
+// Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.<BR>
+// Copyright (c) 2018, Linaro, Limited. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "Module entry point library for standalone MM driver"
+
+#string STR_MODULE_DESCRIPTION #language en-US "Module entry point library for standalone MM driver."
+
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmDriverEntryPoint.inf b/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmDriverEntryPoint.inf
new file mode 100644
index 0000000000..1d43ce9345
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmDriverEntryPoint.inf
@@ -0,0 +1,53 @@
+## @file
+# Module entry point library for Standalone MM drivers that dynamically updates the stack cookie.
+#
+# Copyright (c) 2015 - 2021, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2016-2018, ARM Ltd. All rights reserved.<BR>
+# Copyright (c) 2018, Linaro, Limited. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x0001001B
+ BASE_NAME = StandaloneMmDriverEntryPointDynamicInit
+ MODULE_UNI_FILE = StandaloneMmDriver/StandaloneMmDriverEntryPoint.uni
+ FILE_GUID = 28CBCD87-2FEE-4D46-BB5C-B37732BBEEB1
+ MODULE_TYPE = MM_STANDALONE
+ VERSION_STRING = 1.0
+ PI_SPECIFICATION_VERSION = 0x00010032
+ LIBRARY_CLASS = StandaloneMmDriverEntryPoint|MM_STANDALONE
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = X64 AARCH64
+#
+
+[Sources]
+ StandaloneMmDriver/StandaloneMmDriverEntryPoint.c
+
+[Sources.IA32]
+ IA32/DynamicCookieGcc.nasm | GCC
+ IA32/DynamicCookieMsvc.nasm | MSFT
+
+[Sources.X64]
+ X64/DynamicCookieGcc.nasm | GCC
+ X64/DynamicCookieMsvc.nasm | MSFT
+
+[Sources.AARCH64]
+ AArch64/DynamicCookieGcc.S | GCC
+
+[Packages]
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ MmServicesTableLib
+ StackCheckLib
+
+[Protocols]
+ gEfiLoadedImageProtocolGuid ## SOMETIMES_CONSUMES
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplication/ApplicationEntryPoint.c b/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplication/ApplicationEntryPoint.c
new file mode 100644
index 0000000000..0c57b20417
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplication/ApplicationEntryPoint.c
@@ -0,0 +1,112 @@
+/** @file
+ Entry point library instance to a UEFI application.
+
+Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+#include <Library/UefiApplicationEntryPoint.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+/**
+ Entry point to UEFI Application.
+
+ This function is the entry point for a UEFI Application. This function must call
+ ProcessLibraryConstructorList(), ProcessModuleEntryPointList(), and ProcessLibraryDestructorList().
+ The return value from ProcessModuleEntryPointList() is returned.
+ If _gUefiDriverRevision is not zero and SystemTable->Hdr.Revision is less than _gUefiDriverRevison,
+ then return EFI_INCOMPATIBLE_VERSION.
+
+ @param ImageHandle The image handle of the UEFI Application.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The UEFI Application exited normally.
+ @retval EFI_INCOMPATIBLE_VERSION _gUefiDriverRevision is greater than SystemTable->Hdr.Revision.
+ @retval Other Return value from ProcessModuleEntryPointList().
+
+**/
+EFI_STATUS
+EFIAPI
+_CModuleEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ if (_gUefiDriverRevision != 0) {
+ //
+ // Make sure that the EFI/UEFI spec revision of the platform is >= EFI/UEFI spec revision of the application.
+ //
+ if (SystemTable->Hdr.Revision < _gUefiDriverRevision) {
+ return EFI_INCOMPATIBLE_VERSION;
+ }
+ }
+
+ //
+ // Call constructor for all libraries.
+ //
+ ProcessLibraryConstructorList (ImageHandle, SystemTable);
+
+ //
+ // Call the module's entry point
+ //
+ Status = ProcessModuleEntryPointList (ImageHandle, SystemTable);
+
+ //
+ // Process destructor for all libraries.
+ //
+ ProcessLibraryDestructorList (ImageHandle, SystemTable);
+
+ //
+ // Return the return status code from the driver entry point
+ //
+ return Status;
+}
+
+/**
+ Invokes the library destructors for all dependent libraries and terminates
+ the UEFI Application.
+
+ This function calls ProcessLibraryDestructorList() and the EFI Boot Service Exit()
+ with a status specified by Status.
+
+ @param Status Status returned by the application that is exiting.
+
+**/
+VOID
+EFIAPI
+Exit (
+ IN EFI_STATUS Status
+ )
+
+{
+ ProcessLibraryDestructorList (gImageHandle, gST);
+
+ gBS->Exit (gImageHandle, Status, 0, NULL);
+}
+
+/**
+ Required by the EBC compiler and identical in functionality to _ModuleEntryPoint().
+
+ @param ImageHandle The image handle of the UEFI Application.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The UEFI Application exited normally.
+ @retval EFI_INCOMPATIBLE_VERSION _gUefiDriverRevision is greater than SystemTable->Hdr.Revision.
+ @retval Other Return value from ProcessModuleEntryPointList().
+
+**/
+EFI_STATUS
+EFIAPI
+EfiMain (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ return _ModuleEntryPoint (ImageHandle, SystemTable);
+}
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplication/ApplicationStackCheckEntryPointLibNull.c b/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplication/ApplicationStackCheckEntryPointLibNull.c
new file mode 100644
index 0000000000..7c18e22ae7
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplication/ApplicationStackCheckEntryPointLibNull.c
@@ -0,0 +1,50 @@
+/** @file
+ Entry point library instance to a UEFI application that does not update the stack cookie dynamically.
+
+Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+#include <Library/UefiApplicationEntryPoint.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+
+extern
+EFI_STATUS
+EFIAPI
+_CModuleEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+/**
+ Entry point to UEFI Application.
+
+ This function is the entry point for a UEFI Application. This function must call
+ ProcessLibraryConstructorList(), ProcessModuleEntryPointList(), and ProcessLibraryDestructorList().
+ The return value from ProcessModuleEntryPointList() is returned.
+ If _gUefiDriverRevision is not zero and SystemTable->Hdr.Revision is less than _gUefiDriverRevison,
+ then return EFI_INCOMPATIBLE_VERSION.
+
+ @param ImageHandle The image handle of the UEFI Application.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The UEFI Application exited normally.
+ @retval EFI_INCOMPATIBLE_VERSION _gUefiDriverRevision is greater than SystemTable->Hdr.Revision.
+ @retval Other Return value from ProcessModuleEntryPointList().
+
+**/
+EFI_STATUS
+EFIAPI
+_ModuleEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ //
+ // Call the module's entry point
+ //
+ return _CModuleEntryPoint (ImageHandle, SystemTable);
+}
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplication/UefiApplicationEntryPoint.uni b/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplication/UefiApplicationEntryPoint.uni
new file mode 100644
index 0000000000..8a68a8a70c
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplication/UefiApplicationEntryPoint.uni
@@ -0,0 +1,16 @@
+// /** @file
+// Module entry point library for UEFI Application.
+//
+// Module entry point library for UEFI Application.
+//
+// Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "Module entry point library for UEFI Application"
+
+#string STR_MODULE_DESCRIPTION #language en-US "Module entry point library for UEFI Application."
+
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplicationEntryPoint.inf b/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplicationEntryPoint.inf
new file mode 100644
index 0000000000..596303e001
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplicationEntryPoint.inf
@@ -0,0 +1,45 @@
+## @file
+# Module entry point library for UEFI Application that dynamically updates the stack cookie.
+#
+# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = UefiApplicationEntryPointDynamicInit
+ MODULE_UNI_FILE = UefiApplication/UefiApplicationEntryPoint.uni
+ FILE_GUID = 755B9094-E5AF-4E5B-BE33-D430CDE2C5D2
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = UefiApplicationEntryPoint|UEFI_APPLICATION
+
+#
+# VALID_ARCHITECTURES = IA32 X64 AARCH64
+#
+
+[Sources]
+ UefiApplication/ApplicationEntryPoint.c
+
+[Sources.IA32]
+ IA32/DynamicCookieGcc.nasm | GCC
+ IA32/DynamicCookieMsvc.nasm | MSFT
+
+[Sources.X64]
+ X64/DynamicCookieGcc.nasm | GCC
+ X64/DynamicCookieMsvc.nasm | MSFT
+
+[Sources.AARCH64]
+ AArch64/DynamicCookieGcc.S | GCC
+
+[Packages]
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ UefiBootServicesTableLib
+ DebugLib
+ BaseLib
+ StackCheckLib
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiDriver/DriverEntryPoint.c b/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiDriver/DriverEntryPoint.c
new file mode 100644
index 0000000000..09e7bcaea5
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiDriver/DriverEntryPoint.c
@@ -0,0 +1,162 @@
+/** @file
+ Entry point to a EFI/DXE driver.
+
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+
+#include <Protocol/LoadedImage.h>
+
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+/**
+ Unloads an image from memory.
+
+ This function is a callback that a driver registers to do cleanup
+ when the UnloadImage boot service function is called.
+
+ @param ImageHandle The handle to the image to unload.
+
+ @return Status returned by all unload().
+
+**/
+EFI_STATUS
+EFIAPI
+_DriverUnloadHandler (
+ EFI_HANDLE ImageHandle
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // If an UnloadImage() handler is specified, then call it
+ //
+ Status = ProcessModuleUnloadList (ImageHandle);
+
+ //
+ // If the driver specific unload handler does not return an error, then call all of the
+ // library destructors. If the unload handler returned an error, then the driver can not be
+ // unloaded, and the library destructors should not be called
+ //
+ if (!EFI_ERROR (Status)) {
+ ProcessLibraryDestructorList (ImageHandle, gST);
+ }
+
+ //
+ // Return the status from the driver specific unload handler
+ //
+ return Status;
+}
+
+/**
+ The entry point of PE/COFF Image for a DXE Driver, DXE Runtime Driver, DXE SMM
+ Driver, or UEFI Driver.
+
+ This function is the entry point for a DXE Driver, DXE Runtime Driver, DXE SMM Driver,
+ or UEFI Driver. This function must call ProcessLibraryConstructorList() and
+ ProcessModuleEntryPointList(). If the return status from ProcessModuleEntryPointList()
+ is an error status, then ProcessLibraryDestructorList() must be called. The return
+ value from ProcessModuleEntryPointList() is returned. If _gDriverUnloadImageCount
+ is greater than zero, then an unload handler must be registered for this image
+ and the unload handler must invoke ProcessModuleUnloadList().
+ If _gUefiDriverRevision is not zero and SystemTable->Hdr.Revision is less than
+ _gUefiDriverRevison, then return EFI_INCOMPATIBLE_VERSION.
+
+
+ @param ImageHandle The image handle of the DXE Driver, DXE Runtime Driver,
+ DXE SMM Driver, or UEFI Driver.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The DXE Driver, DXE Runtime Driver, DXE SMM
+ Driver, or UEFI Driver exited normally.
+ @retval EFI_INCOMPATIBLE_VERSION _gUefiDriverRevision is greater than
+ SystemTable->Hdr.Revision.
+ @retval Other Return value from ProcessModuleEntryPointList().
+
+**/
+EFI_STATUS
+EFIAPI
+_CModuleEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
+
+ if (_gUefiDriverRevision != 0) {
+ //
+ // Make sure that the EFI/UEFI spec revision of the platform is >= EFI/UEFI spec revision of the driver
+ //
+ if (SystemTable->Hdr.Revision < _gUefiDriverRevision) {
+ return EFI_INCOMPATIBLE_VERSION;
+ }
+ }
+
+ //
+ // Call constructor for all libraries
+ //
+ ProcessLibraryConstructorList (ImageHandle, SystemTable);
+
+ //
+ // Install unload handler...
+ //
+ if (_gDriverUnloadImageCount != 0) {
+ Status = gBS->HandleProtocol (
+ ImageHandle,
+ &gEfiLoadedImageProtocolGuid,
+ (VOID **)&LoadedImage
+ );
+ ASSERT_EFI_ERROR (Status);
+ LoadedImage->Unload = _DriverUnloadHandler;
+ }
+
+ //
+ // Call the driver entry point
+ //
+ Status = ProcessModuleEntryPointList (ImageHandle, SystemTable);
+
+ //
+ // If all of the drivers returned errors, then invoke all of the library destructors
+ //
+ if (EFI_ERROR (Status)) {
+ ProcessLibraryDestructorList (ImageHandle, SystemTable);
+ }
+
+ //
+ // Return the cummalative return status code from all of the driver entry points
+ //
+ return Status;
+}
+
+/**
+ Required by the EBC compiler and identical in functionality to _ModuleEntryPoint().
+
+ This function is required to call _ModuleEntryPoint() passing in ImageHandle,
+ and SystemTable.
+
+ @param ImageHandle The image handle of the DXE Driver, DXE Runtime Driver, DXE
+ SMM Driver, or UEFI Driver.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The DXE Driver, DXE Runtime Driver, DXE SMM
+ Driver, or UEFI Driver exited normally.
+ @retval EFI_INCOMPATIBLE_VERSION _gUefiDriverRevision is greater than
+ SystemTable->Hdr.Revision.
+ @retval Other Return value from ProcessModuleEntryPointList().
+**/
+EFI_STATUS
+EFIAPI
+EfiMain (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ return _ModuleEntryPoint (ImageHandle, SystemTable);
+}
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiDriver/UefiDriverEntryPoint.uni b/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiDriver/UefiDriverEntryPoint.uni
new file mode 100644
index 0000000000..6667c378fa
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiDriver/UefiDriverEntryPoint.uni
@@ -0,0 +1,16 @@
+// /** @file
+// Module entry point library for UEFI driver, DXE driver and SMM driver.
+//
+// Module entry point library for UEFI driver, DXE driver and SMM driver.
+//
+// Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "Module entry point library for UEFI driver, DXE driver and SMM driver"
+
+#string STR_MODULE_DESCRIPTION #language en-US "Module entry point library for UEFI driver, DXE driver and SMM driver."
+
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiDriverEntryPoint.inf b/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiDriverEntryPoint.inf
new file mode 100644
index 0000000000..d624c3e1a3
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiDriverEntryPoint.inf
@@ -0,0 +1,68 @@
+## @file
+# Module entry point library for UEFI driver, DXE driver and SMM driver that dynamically sets the stack cookie.
+#
+# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = UefiDriverEntryPointDynamicInit
+ MODULE_UNI_FILE = UefiDriver/UefiDriverEntryPoint.uni
+ FILE_GUID = 900238F9-1421-4596-9548-A1BF58C97693
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = UefiDriverEntryPoint|DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER SMM_CORE DXE_SMM_DRIVER
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 AARCH64
+#
+
+[Sources]
+ UefiDriver/DriverEntryPoint.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+
+[Sources.IA32]
+ IA32/DynamicCookieGcc.nasm | GCC
+ IA32/DynamicCookieMsvc.nasm | MSFT
+
+[Sources.X64]
+ X64/DynamicCookieGcc.nasm | GCC
+ X64/DynamicCookieMsvc.nasm | MSFT
+
+[Sources.AARCH64]
+ AArch64/DynamicCookieGcc.S | GCC
+
+[LibraryClasses]
+ UefiBootServicesTableLib
+ DebugLib
+ BaseLib
+ StackCheckLib
+
+[Protocols]
+ gEfiLoadedImageProtocolGuid ## SOMETIMES_CONSUMES
+
+#
+# For UEFI drivers, these architectural protocols defined in PI 1.0 spec need
+# to be appended and merged to the final dependency section.
+#
+[Depex.common.UEFI_DRIVER]
+ gEfiBdsArchProtocolGuid AND
+ gEfiCpuArchProtocolGuid AND
+ gEfiMetronomeArchProtocolGuid AND
+ gEfiMonotonicCounterArchProtocolGuid AND
+ gEfiRealTimeClockArchProtocolGuid AND
+ gEfiResetArchProtocolGuid AND
+ gEfiRuntimeArchProtocolGuid AND
+ gEfiSecurityArchProtocolGuid AND
+ gEfiTimerArchProtocolGuid AND
+ gEfiVariableWriteArchProtocolGuid AND
+ gEfiVariableArchProtocolGuid AND
+ gEfiWatchdogTimerArchProtocolGuid
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/X64/DynamicCookieGcc.nasm b/MdePkg/Library/DynamicStackCookieEntryPointLib/X64/DynamicCookieGcc.nasm
new file mode 100644
index 0000000000..872e0f703c
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/X64/DynamicCookieGcc.nasm
@@ -0,0 +1,63 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) Microsoft Corporation.
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+; Module Name:
+;
+; DynamicCookie.nasm
+;
+; Abstract:
+;
+; Generates random number through CPU RdRand instruction on 64-bit platform
+; to store a random value in the GCC __stack_check_guard stack cookie.
+; The first byte is 0'd to prevent string copy functions from clobbering
+; the stack cookie.
+;
+; Notes:
+;
+; If RdRand fails, the build time static stack cookie value will be used instead.
+;
+;------------------------------------------------------------------------------
+
+DEFAULT REL
+SECTION .text
+
+extern ASM_PFX(__stack_chk_guard)
+extern ASM_PFX(_CModuleEntryPoint)
+
+;------------------------------------------------------------------------------
+; VOID
+; EFIAPI
+; _ModuleEntryPoint (
+; Parameters are passed through. TODO: Make sure there are only two args on X64
+; );
+;------------------------------------------------------------------------------
+global ASM_PFX(_ModuleEntryPoint)
+ASM_PFX(_ModuleEntryPoint):
+ push rbx
+ push rcx
+ push rdx
+
+ mov eax, 1 ; Set eax to 1 to get feature information
+ cpuid ; Call cpuid
+ test ecx, 0x40000000 ; Test the rdrand bit (bit 30) in ecx
+ jz c_entry ; If rdrand is not supported, jump to c_entry
+
+ rdrand rax ; Call rdrand functionality here, getting a 64 bit value as on
+ ; X64, __stack_chk_guard is a 64 bit value.
+ ; CF=1 if RN generated ok, otherwise CF=0
+ jnc c_entry ; If the cmd fails, don't, update __stack_chk_guard, we'll have to move forward
+ ; with the static value provided at build time.
+
+ lea rbx, [rel ASM_PFX(__stack_chk_guard)] ; load the address of __stack_check_guard into rbx
+
+ xor ah, ah ; Zero a byte of the __stack_chk_guard value to protect against string functions
+ ; (such as strcpy like functions) clobbering past the canary
+ mov [rbx], rax ; Store our random value, with 0'd first byte to __stack_chk_guard
+
+c_entry:
+ pop rdx
+ pop rcx
+ pop rbx
+ jmp ASM_PFX(_CModuleEntryPoint)
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/X64/DynamicCookieMsvc.nasm b/MdePkg/Library/DynamicStackCookieEntryPointLib/X64/DynamicCookieMsvc.nasm
new file mode 100644
index 0000000000..23c34e7289
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/X64/DynamicCookieMsvc.nasm
@@ -0,0 +1,63 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) Microsoft Corporation.
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+; Module Name:
+;
+; DynamicCookie.nasm
+;
+; Abstract:
+;
+; Generates random number through CPU RdRand instruction on 64-bit platform
+; to store a random value in the GCC __stack_check_guard stack cookie.
+; The first byte is 0'd to prevent string copy functions from clobbering
+; the stack cookie.
+;
+; Notes:
+;
+; If RdRand fails, the build time static stack cookie value will be used instead.
+;
+;------------------------------------------------------------------------------
+
+DEFAULT REL
+SECTION .text
+
+extern ASM_PFX(__security_cookie)
+extern ASM_PFX(_CModuleEntryPoint)
+
+;------------------------------------------------------------------------------
+; VOID
+; EFIAPI
+; _ModuleEntryPoint (
+; Parameters are passed through. TODO: Make sure there are only two args on X64
+; );
+;------------------------------------------------------------------------------
+global ASM_PFX(_ModuleEntryPoint)
+ASM_PFX(_ModuleEntryPoint):
+ push rbx
+ push rcx
+ push rdx
+
+ mov eax, 1 ; Set eax to 1 to get feature information
+ cpuid ; Call cpuid
+ test ecx, 0x40000000 ; Test the rdrand bit (bit 30) in ecx
+ jz c_entry ; If rdrand is not supported, jump to c_entry
+
+ rdrand rax ; Call rdrand functionality here, getting a 64 bit value as on
+ ; X64, __stack_chk_guard is a 64 bit value.
+ ; CF=1 if RN generated ok, otherwise CF=0
+ jnc c_entry ; If the cmd fails, don't, update __stack_chk_guard, we'll have to move forward
+ ; with the static value provided at build time.
+
+ lea rbx, [rel ASM_PFX(__security_cookie)] ; load the address of __stack_check_guard into rbx
+
+ xor ah, ah ; Zero a byte of the __stack_chk_guard value to protect against string functions
+ ; (such as strcpy like functions) clobbering past the canary
+ mov [rbx], rax ; Store our random value, with 0'd first byte to __stack_chk_guard
+
+c_entry:
+ pop rdx
+ pop rcx
+ pop rbx
+ jmp ASM_PFX(_CModuleEntryPoint)
diff --git a/MdePkg/Library/StackCheckLib/Readme.md b/MdePkg/Library/StackCheckLib/Readme.md
index 8d15ad4ca4..2d9bb6fbda 100644
--- a/MdePkg/Library/StackCheckLib/Readme.md
+++ b/MdePkg/Library/StackCheckLib/Readme.md
@@ -1,12 +1,12 @@
-# StackCheckLib
+# StackCheckLib Overview
## Table of Contents
- [StackCheckLib](#stackchecklib)
- [Table of Contents](#table-of-contents)
- [Introduction and Library Instances](#introduction-and-library-instances)
- - [StackCheckLibStaticInit](#stackchecklibstaticinit)
- - [StackCheckLibDynamicInit](#stackchecklibdynamicinit)
+ - [StackCheckLib](#stackchecklib)
+ - [DynamicStackCookieEntryPointLib](#dynamicstackcookieentrypointlib)
- [StackCheckLibNull](#stackchecklibnull)
- [How Failures are Handled](#how-failures-are-handled)
- [Debugging Stack Cookie Check Failures](#debugging-stack-cookie-check-failures)
@@ -15,44 +15,79 @@
## Introduction and Library Instances
`StackCheckLib` contains the required functionality for initializing the stack cookie
-value, checking the value, and triggering an interrupt when a mismatch occurs.
-The stack cookie is a random value placed on the stack between the stack variables
-and the return address so that continuously writing past the stack variables will
-cause the stack cookie to be overwritten. Before the function returns, the stack
-cookie value will be checked and if there is a mismatch then `StackCheckLib` handles
-the failure.
+value (based on a randomly generated value during build time), checking the value,
+and triggering an interrupt when a mismatch occurs. The stack cookie is a random value
+placed on the stack between the stack variables and the return address so that
+continuously writing past the stack variables will cause the stack cookie to be
+overwritten. Before the function returns, the stack cookie value will be checked and
+if there is a mismatch then `StackCheckLib` handles the failure.
Because UEFI doesn't use the C runtime libraries provided by MSVC, the stack
check code is written in assembly within this library. GCC and Clang compilers
have built-in support for stack cookie checking, so this library only handles failures.
-### StackCheckLibStaticInit
-
-`StackCheckLibStaticInit` is an instance of `StackCheckLib` which does not update the
-stack cookie value for the module at runtime. It's always preferable to use
-`StackCheckLibDynamicInit` for improved security but there are cases where the stack
-cookie global cannot be written to such as in execute-in-place (XIP) modules and during
-the Cache-as-RAM (CAR) phase of the boot process. The stack cookie value is initialized
-at compile time via updates to the AutoGen process. Each module will define
-`STACK_COOKIE_VALUE` which is used for the module stack cookie value.
-
-### StackCheckLibDynamicInit
-
-This section is future work. The below is the proposed instance.
-
-`StackCheckLibDynamicInit` is an instance of `StackCheckLib` which updates the stack
-cookie value for the module at runtime. This is the preferred method for stack cookie
-initialization as it provides improved security. The stack cookie value is initialized
-at runtime by calling `GetRandomNumber32()` or `GetRandomNumber64()` to generate a random
-value via the platform's random number generator protocol. If the random number generator
-returns an error, then the value will still have the build-time randomized value to fall
-back on.
+The stack cookie value is initialized at compile time via updates to the AutoGen process.
+Each module will define `STACK_COOKIE_VALUE` which is used for the module stack cookie
+value.
+
+The entry point libraries under `MdePkg/DynamicStackCookieEntryPointLib/` update the stack
+cookie value at runtime for improved security, but there are cases where the stack cookie
+global cannot be written to such as in execute-in-place (XIP) modules and during the
+temporary RAM phase of the boot process. It is always preferable to use
+one of the dynamic stack cookie entry points when possible.
+
+### StackCheckLib
+
+`StackCheckLib` provides the stack cookie checking functionality per architecture and
+toolchain. The currently supported pairs are IA32{GCC,MSVC}, X64{GCC, MSVC},
+ARM{GCC, MSVC}, and AARCH64{GCC, MSVC}. `StackCheckLib` is agnostic as to
+whether the stack cookie was updated during build time or run time; it simply
+checks the cookie in the MSVC case and in both GCC and MSVC responds to stack
+cookie checking failures.
+
+To add support for other architectures/toolchains, additional assembly files
+should be added to `StackCheckLib.inf` and scoped to that architecture/toolchain.
+
+Note: Stack cookie failures generate exceptions and SEC and PEI_CORE may not have
+exception handlers registered. In order to safely use stack cookie checking in
+these phases, a platform should implement exception handlers because unhandled
+exceptions may lead to a hung system state. If a platform does not implement
+exception handlers in SEC and PEI_CORE, it is recommended to use `StackCheckLibNull`
+for these phases, except for development purposes.
+
+### DynamicStackCookieEntryPointLib
+
+Each EntryPoint lib under `MdePkg/DynamicStackCookieEntryPointLib/` is an instance of
+that module type entry point lib which updates the stack cookie value for the module at
+runtime. This is the preferred method for stack cookie initialization as it provides
+improved security. The stack cookie value is initialized at runtime in `_ModuleEntryPoint`
+by calling `rdrand` on x86 and `RNDR` on AARCH64. If the random number generator is not
+supported on that platform or otherwise returns an error, then the value will still have
+the build-time randomized value to fall back on.
+
+Typically, dynamic cookies cannot be used for SEC, PEI_CORE, and PEIM modules, due to
+the lack of the ability to write to globals for many architectures. If a given platform
+can write to globals during these phases, it is recommended to use the provided dynamic
+stack cookie entry point lib for those types. Note that SEC does not have a universal
+entry point, so there is no dynamic stack cookie entry point lib there.
+
+The dynamic stack cookie entry point lib is used in place of the standard entry point lib,
+e.g. for UefiDriverEntryPoint to have dynamic stack cookies, a platform would remove
+MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf from its DSC and instead
+include MdePkg/Library/DynamicStackCookieEntryPointLib/UefiDriverEntryPoint.inf.
+
+See the Usage section for other ways of including these libraries.
+
+Note: Standalone MM Core support for dynamic cookies for AARCH64 is currently not
+supported, due to the unique entry point mechanism there. This support will be
+added at a future date.
### StackCheckLibNull
`StackCheckLibNull` is an instance of `StackCheckLib` which does not perform any stack
cookie checks. This is useful for modules which will fail if stack cookie checks are
-inserted. Of course, this is not recommended for production code.
+inserted. Of course, this is not recommended for production code outside of
+SEC and PEI_CORE.
## How Failures are Handled
@@ -104,8 +139,9 @@ edk2 updated the tools_def to add `/GS` to VS2022 and VS2019 IA32/X64 builds and
`-fstack-protector` to GCC builds. This will cause stack cookie references to be inserted
throughout the code. Every module should have a `StackCheckLib` instance linked to satisfy
these references. So every module doesn't need to add `StackCheckLib` to the LibraryClasses
-section of the INF file, `StackCheckLib` instances should be linked as NULL in the platform
-DSC files. The only exception to this is MSVC built host-based unit tests as they will be
+section of the INF file, `StackCheckLib` is added as a dependency for each entry point lib.
+This means that custom entry point libs need to have StackCheckLib added as a dependency.
+The only exception to this is MSVC built host-based unit tests as they will be
compiled with the runtime libraries which already contain the stack cookie definitions
and will collide with `StackCheckLib`. A `StackCheckLibHostApplication.inf` is linked
by `UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc` that provides the stack
@@ -113,70 +149,80 @@ cookie functions for GCC HOST_APPLICATIONS but not for MSVC HOST_APPLICATIONS.
### Default Stack Check Library Configuration
-`MdePkg/MdeLibs.dsc.inc` links `StackCheckLibNull` for all types except SEC, HOST_APPLICATION,
-and USER_DEFINED in order to not break existing DSCs. SEC cannot be generically linked to
-because there are some SEC modules which do not link against the standard entry point
-libraries and thus do not get stack cookies inserted by the compiler. USER_DEFINED modules
-are by nature different from other modules, so we do not make any assumptions about their
-state.
+`MdePkg/MdeLibs.dsc.inc` links `StackCheckLibNull` and `StackCheckFailureLibNull` for all
+types.
As stated above, all HOST_APPLICATIONS will link against a HOST_APPLICATION specific
implementation provided in `UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc`.
-To link the rest of a platform's modules to `StackCheckLibNull`, a platform would needs
-to link it for all SEC and USER_DEFINED modules. If all of the DSC's SEC and USER_DEFINED
-modules link against the entry point libs, it would look like the following:
+### Custom Stack Check Library Configuration
+
+In order to use a different instance of StackCheckLib than `MdeLibs.dsc.inc` provides, a DSC
+should add one of the following:
+
+#### Static Stack Check Cookie Configuration
```inf
-[LibraryClasses.common.SEC, LibraryClasses.common.USER_DEFINED]
- NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
+[Defines]
+ DEFINE CUSTOM_STACK_CHECK_LIB = STATIC
```
-If some do not, then the individual SEC/USER_DEFINED modules that do link against
-the entry point libs will need to be linked to `StackCheckLibNull`, such as below.
-This case is identifiable if a DSC is built and the linker complains the stack
-check functions are not found for a module.
+This will cause `MdeLibs.dsc.inc` to not link `StackCheckLibNull` and instead link
+`StackCheckLib` to perform stack cookie checking on the static stack cookies, but not update
+any of the stack cookies at runtime.
+
+Because edk2 does not implement exception handling for `SEC` and `PEI_CORE`, `MdeLibs.dsc.inc`
+uses `StackCheckLibNull` for these phases always. If a platform wishes to use `StackCheckLib`
+for these phases, it should override this in its DSC, e.g.:
```inf
-UefiCpuPkg/SecCore/SecCore.inf {
- <LibraryClasses>
- NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
- }
+[LibraryClasses.common.SEC, LibraryClasses.common.PEI_CORE]
+ StackCheckLib|MdePkg/Library/StackCheckLib/StackCheckLib.inf
```
-### Custom Stack Check Library Configuration
+It is recommended that a platform only do this for debugging or if they have implemented
+exception handlers for these phases.
-In order to use a different instance of StackCheckLib than `MdeLibs.dsc.inc` provides, a DSC
-should add the following:
+#### Dynamic Stack Cookie Configuration
```inf
[Defines]
- DEFINE CUSTOM_STACK_CHECK_LIB = TRUE
+ DEFINE CUSTOM_STACK_CHECK_LIB = DYNAMIC
```
-This will cause `MdeLibs.dsc.inc` to not link `StackCheckLibNull` and rely on a DSC to
-link whichever version(s) of `StackCheckLib` it desires.
-
-It is recommended that SEC and PEI_CORE modules use `StackCheckLibNull` and pre-memory modules
-should use `StackCheckLibStaticInit`. All other modules should use `StackCheckLibDynamicInit`.
+This will cause `MdeLibs.dsc.inc` to not link `StackCheckLibNull` and instead link
+`StackCheckLib` to perform stack cookie checking. It will also link the dynamic
+stack cookie updating versions of `DxeCoreEntryPoint`, `StandaloneMmDriverEntryPoint`,
+`UefiApplicationEntryPoint`, and `UefiDriverEntryPoint`.
-Below is an **example** of how to link the `StackCheckLib` instances in the platform DSC file
-but it may need customization based on the platform's requirements:
+Because edk2 does not implement exception handling for `SEC` and `PEI_CORE`, `MdeLibs.dsc.inc`
+uses `StackCheckLibNull` for these phases always. As a result, dynamic stack cookies are also
+not set for `PEI_CORE`. There is no standard `SEC` entrypoint, so it is not supported generically
+to apply dynamic stack cookies there. If a platform wishes to use `StackCheckLib` and dynamic stack
+cookies for these phases, it should override this in its DSC, e.g.:
```inf
[LibraryClasses.common.SEC, LibraryClasses.common.PEI_CORE]
- NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
+ StackCheckLib|MdePkg/Library/StackCheckLib/StackCheckLib.inf
+ PeiCoreEntryPoint|MdePkg/Library/DynamicStackCookieEntryPointLib/PeiCoreEntryPoint.inf
+```
+
+It is recommended that a platform only do this for debugging or if they have implemented
+exception handlers for these phases.
-[LibraryClasses.common.PEIM]
- NULL|MdePkg/Library/StackCheckLib/StackCheckLibStaticInit.inf
+Note: `StandaloneMmCoreEntryPoint` is recommended to use the dynamic stack cookie if
+possible, but as it is not supported on AARCH64 today, it is not included in MdeLibs.dsc.inc.
+Platforms should include this separately, e.g.:
-[LibraryClasses.common.MM_CORE_STANDALONE, LibraryClasses.common.MM_STANDALONE, LibraryClasses.common.DXE_CORE,
-LibraryClasses.common.SMM_CORE, LibraryClasses.common.DXE_SMM_DRIVER, LibraryClasses.common.DXE_DRIVER,
-LibraryClasses.common.DXE_RUNTIME_DRIVER, LibraryClasses.common.DXE_SAL_DRIVER, LibraryClasses.common.UEFI_DRIVER,
-LibraryClasses.common.UEFI_APPLICATION]
- NULL|MdePkg/Library/StackCheckLib/StackCheckLibDynamicInit.inf
+```inf
+[LibraryClasses.X64]
+ StandaloneMmCoreEntryPoint|MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmCoreEntryPoint.inf
```
+Platforms then must remove any references to these entry point libs in their DSC, so that
+the `MdeLibs.dsc.inc` versions are chosen. Alternatively, for better DSC readability,
+a platform can directly reference the dynamic stack cookie entry points.
+
### Disable Stack Check Library
If a platform would like to disable stack cookies (say for debugging purposes),
@@ -191,4 +237,14 @@ they can add the following to their DSC:
The same build options can be put in a module's INF to only disable stack cookies
for that module.
+Alternatively, a module can have the stack cookies inserted but checking disabled
+by including the following in a DSC:
+
+```inf
+SomePkg/SomeDirectory/SomeModule.inf {
+ <LibraryClasses>
+ StackCheckLib|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
+}
+```
+
It is not recommended to disable stack cookie checking in production scenarios.
diff --git a/MdePkg/MdeLibs.dsc.inc b/MdePkg/MdeLibs.dsc.inc
index 19a883d50d..57818e2499 100644
--- a/MdePkg/MdeLibs.dsc.inc
+++ b/MdePkg/MdeLibs.dsc.inc
@@ -11,6 +11,14 @@
#
##
+[Defines]
+!ifndef CUSTOM_STACK_CHECK_LIB
+ # The DSC parser will set any unset macros to 0. Then, below when we check for STATIC or DYNAMIC, even if we couch
+ # that in a !ifdef CUSTOM_STACK_CHECK_LIB, the parser will issue a warning that we are comparing a boolean (0) against
+ # a string, which will always fail. So we set it to a dummy value here.
+ DEFINE CUSTOM_STACK_CHECK_LIB = NONE
+!endif
+
[LibraryClasses]
OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf
ArmTrngLib|MdePkg/Library/BaseArmTrngLibNull/BaseArmTrngLibNull.inf
@@ -22,13 +30,35 @@
MmUnblockMemoryLib|MdePkg/Library/MmUnblockMemoryLib/MmUnblockMemoryLibNull.inf
StackCheckFailureHookLib|MdePkg/Library/StackCheckFailureHookLibNull/StackCheckFailureHookLibNull.inf
-!ifndef CUSTOM_STACK_CHECK_LIB
+!if $(CUSTOM_STACK_CHECK_LIB) == STATIC
+ # To only use the static stack cookie, we just include the checking functionality.
+ StackCheckLib|MdePkg/Library/StackCheckLib/StackCheckLib.inf
+!elseif $(CUSTOM_STACK_CHECK_LIB) == DYNAMIC
+ StackCheckLib|MdePkg/Library/StackCheckLib/StackCheckLib.inf
+
+ # To use the dynamic stack cookie, we need to include the entry point libraries that will set up the stack cookie.
+ # Typically, PeiCore and PEIMs will not use dynamic stack cookies, so they are not included generally.
+ # If dynamic stack cookies are not enabled, we do not setup the entry points, as the existing behavior was
+ # for a platform to define them.
+ # StandaloneMmCoreEntryPoint is not included here because support dynamic stack cookies is not available for
+ # AARCH64 here. X64 platforms should include the DynamicStackCookieEntryPointLib in their DSC file.
+ DxeCoreEntryPoint|MdePkg/Library/DynamicStackCookieEntryPointLib/DxeCoreEntryPoint.inf
+ StandaloneMmDriverEntryPoint|MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmDriverEntryPoint.inf
+ UefiApplicationEntryPoint|MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplicationEntryPoint.inf
+ UefiDriverEntryPoint|MdePkg/Library/DynamicStackCookieEntryPointLib/UefiDriverEntryPoint.inf
+
+!else
# If CUSTOM_STACK_CHECK_LIB is set, MdeLibs.dsc.inc will not link StackCheckLibNull and it is expected that the
# DSC being built is providing it's own implementation of StackCheckLib.
- NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
-
+ StackCheckLib|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
!endif
+[LibraryClasses.common.SEC, LibraryClasses.common.PEI_CORE]
+ # edk2 does not implement exception handling for SEC and PEI_CORE, so StackCheckLibNull is used, as failing
+ # stack cookies will generate an exception, which if unhandled can lead to a hung system state. If a platform
+ # implements exception handling for SEC and PEI_CORE, it can use StackCheckLib for these phases in its DSC.
+ StackCheckLib|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
+
[LibraryClasses.ARM, LibraryClasses.AARCH64]
#
# It is not possible to prevent the ARM/AARCH64 compilers from inserting generic intrinsic functions.
diff --git a/MdePkg/MdePkg.dsc b/MdePkg/MdePkg.dsc
index ccefe558f3..12a1b8f13c 100644
--- a/MdePkg/MdePkg.dsc
+++ b/MdePkg/MdePkg.dsc
@@ -143,6 +143,12 @@
MdePkg/Library/StackCheckFailureHookLibNull/StackCheckFailureHookLibNull.inf
MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
MdePkg/Library/StackCheckLib/StackCheckLib.inf
+ MdePkg/Library/DynamicStackCookieEntryPointLib/DxeCoreEntryPoint.inf
+ MdePkg/Library/DynamicStackCookieEntryPointLib/PeiCoreEntryPoint.inf
+ MdePkg/Library/DynamicStackCookieEntryPointLib/PeimEntryPoint.inf
+ MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmDriverEntryPoint.inf
+ MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplicationEntryPoint.inf
+ MdePkg/Library/DynamicStackCookieEntryPointLib/UefiDriverEntryPoint.inf
[Components.IA32, Components.X64, Components.ARM, Components.AARCH64]
#
@@ -193,6 +199,7 @@
MdePkg/Library/TraceHubDebugSysTLibNull/TraceHubDebugSysTLibNull.inf
[Components.X64]
+ MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmCoreEntryPoint.inf
MdePkg/Library/StandaloneMmCoreEntryPoint/StandaloneMmCoreEntryPoint.inf
[Components.EBC]