diff options
author | Oliver Smith-Denny <osde@microsoft.com> | 2024-09-24 15:46:32 -0700 |
---|---|---|
committer | mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> | 2024-10-04 00:57:12 +0000 |
commit | 71239406652f78675499f2fbe937de03c53129cb (patch) | |
tree | 2c3bc2d9b4732cd401c58cd7edba478e628245f2 | |
parent | 2fdc39d09d49a57e8dc87022b1dedd958f8c8d6a (diff) | |
download | edk2-71239406652f78675499f2fbe937de03c53129cb.tar.gz edk2-71239406652f78675499f2fbe937de03c53129cb.tar.bz2 edk2-71239406652f78675499f2fbe937de03c53129cb.zip |
MdePkg: MdeLibs.dsc.inc: Introduce CUSTOM_STACK_CHECK_LIB Macro
In order to support a platform overriding StackCheckLibNull
provided by MdeLibs.dsc.inc, the CUSTOM_STACK_CHECK_LIB macro
is introduced. If this macro is defined, MdeLibs.dsc.inc will
not link StackCheckLibNull and it is expected that the platform
will link the version(s) of StackCheckLib that it requires.
The StackCheckLib README is also updated in this patch to
document the new macro and provide additional information.
Signed-off-by: Oliver Smith-Denny <osde@linux.microsoft.com>
-rw-r--r-- | MdePkg/Library/StackCheckLib/Readme.md | 82 | ||||
-rw-r--r-- | MdePkg/MdeLibs.dsc.inc | 9 |
2 files changed, 83 insertions, 8 deletions
diff --git a/MdePkg/Library/StackCheckLib/Readme.md b/MdePkg/Library/StackCheckLib/Readme.md index 636cd047f0..8d15ad4ca4 100644 --- a/MdePkg/Library/StackCheckLib/Readme.md +++ b/MdePkg/Library/StackCheckLib/Readme.md @@ -102,25 +102,93 @@ update the tools_def file so the `<TARGET>_<TOOLCHAIN>_<ARCH>_CC_FLAGS` includes 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` instances linked to satisfy
+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 fies. The only exception to this is 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`.
+DSC files. 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
+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.
+
+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:
+
+```inf
+[LibraryClasses.common.SEC, LibraryClasses.common.USER_DEFINED]
+ NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
+```
+
+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.
+
+```inf
+UefiCpuPkg/SecCore/SecCore.inf {
+ <LibraryClasses>
+ NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
+ }
+```
+
+### Custom Stack Check Library Configuration
+
+In order to use a different instance of StackCheckLib than `MdeLibs.dsc.inc` provides, a DSC
+should add the following:
+
+```inf
+[Defines]
+ DEFINE CUSTOM_STACK_CHECK_LIB = TRUE
+```
-SEC and PEI_CORE modules should always use `StackCheckLibNull` and pre-memory modules
+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`.
+
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:
-```text
+```inf
[LibraryClasses.common.SEC, LibraryClasses.common.PEI_CORE]
NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
[LibraryClasses.common.PEIM]
NULL|MdePkg/Library/StackCheckLib/StackCheckLibStaticInit.inf
-[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]
+[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
```
+
+### Disable Stack Check Library
+
+If a platform would like to disable stack cookies (say for debugging purposes),
+they can add the following to their DSC:
+
+```inf
+[BuildOptions]
+ MSVC:*_*_*_CC_FLAGS = /GS-
+ GCC:*_*_*_CC_FLAGS = -fno-stack-protector
+```
+
+The same build options can be put in a module's INF to only disable stack cookies
+for that module.
+
+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 4e3858edb6..542b5f77f4 100644 --- a/MdePkg/MdeLibs.dsc.inc +++ b/MdePkg/MdeLibs.dsc.inc @@ -31,8 +31,15 @@ #
NULL|MdePkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
+#
# Stack Cookies cannot be generically applied to SEC modules because they may not define _ModuleEntryPoint and when we
# link a library in, we have to be able to define the entry point. SEC modules that do define _ModuleEntryPoint can
-# apply a library class override to get StackCheckLibNull.inf
+# apply a library class override to get StackCheckLibNull.inf.
+#
+# 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.
+#
[LibraryClasses.common.PEI_CORE, LibraryClasses.common.PEIM, LibraryClasses.common.DXE_CORE, LibraryClasses.common.SMM_CORE, LibraryClasses.common.MM_CORE_STANDALONE, LibraryClasses.common.DXE_DRIVER, LibraryClasses.common.DXE_RUNTIME_DRIVER, LibraryClasses.common.DXE_SMM_DRIVER, LibraryClasses.common.MM_STANDALONE, LibraryClasses.common.UEFI_DRIVER, LibraryClasses.common.UEFI_APPLICATION]
+!ifndef CUSTOM_STACK_CHECK_LIB
NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
+!endif
|