-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add IA32, X64, ARM, and AARCH64 Stack Cookie Support for MSVC and GCC #5957
Conversation
MdePkg\MdeLibs.dsc.inc can be updated to add the default NULL library instance. If so, single package DSC will not be updated. I understand this change. I want to confirm what purpose for it? And, why this change only for VS2019/VS2022 IA32 and X64 arch? |
@lgao4, thanks for taking a look, I actually have a bit more cleanup to do here, I put up this PR in draft form to start testing the CI, but happy to have discussion while I get it into final form. My concern about MdeLibs.dsc.inc is that an actual platform may not know about the updated stack check lib and just always get the null version. Furthermore, the concern would be that if a platform included MdeLibs.dsc.inc after they had specified the correct stack check lib, the version they chose would be overrode by the null version silently. If we think these issues are acceptable for platform owners to navigate, then I can drop most of the commits and simply add it to MdeLibs.dsc.inc. The purpose for this change is to add general stack cookie support to edk2. Today it is only supported in a limited form for ARM/AARCH64 GCC. Stack cookies help catch stack corruption, either unintentional or intentional, so protect against both programming errors and some classes of attack. See more details at https://learn.microsoft.com/en-us/cpp/build/reference/gs-buffer-security-check?view=msvc-170 and https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html#index-fstack-protector. Agreed that the VS2019/2022 change was not complete, I will push an update that includes ARM/AARCH64. |
881bfd2
to
c937581
Compare
@lgao4 @mdkinney @bcran @liyi77 @jyao1 @Wenxing-hou @ardbiesheuvel @leiflindholm I have moved the PR to active now that the pipelines are passing (CodeQL failures are from the overall edk2 CodeQL infra issue). Can you please review when you have a chance? |
MdeLibs.dsc.inc is designed as the default library instance. Platform always includes it the begin of their DSC file. So, it will not override the platform setting. |
@lgao4, while doing the CI for OvmfPkg, I realized we cannot do MdeLibs.dsc.inc. The reason is that StackCheckLib has a dependency on So, we cannot generically apply this to every DSC, even if the majority would be able to take it. |
@TaylorBeebe if you are interested in reviewing. |
⚠ WARNING: Cannot add some reviewers: A user specified as a reviewer for this PR is not a collaborator of the repository. Please add them as a collaborator to the repository so they can be requested in the future. Non-collaborators requested: Attn Admins: Admin Instructions:
|
Rebased and fixed merge conflicts (in every package, since my CompilerIntrinsicsLib PR also touched every DSC and went in before this one) |
Remove the old stack check lib now that MdeLibs.inc includes the new one. Signed-off-by: Oliver Smith-Denny <[email protected]>
Remove the old stack check lib now that MdeLibs.inc includes the new one. Signed-off-by: Oliver Smith-Denny <[email protected]>
Remove the old stack check lib now that MdeLibs.inc includes the new one. Signed-off-by: Oliver Smith-Denny <[email protected]>
Remove the old stack check lib now that MdeLibs.inc includes the new one. Signed-off-by: Oliver Smith-Denny <[email protected]>
Remove the old stack check lib now that MdeLibs.inc includes the new one. Signed-off-by: Oliver Smith-Denny <[email protected]>
Add null implementation of StackCheckLib Signed-off-by: Oliver Smith-Denny <[email protected]>
Remove the old stack check lib now that MdeLibs.inc includes the new one. Signed-off-by: Oliver Smith-Denny <[email protected]>
SecCore and SecCoreNative require StackCheckLib and so the NULL instance is linked against them here. Signed-off-by: Oliver Smith-Denny <[email protected]>
Add null implementation of StackCheckLib Signed-off-by: Oliver Smith-Denny <[email protected]>
Add StackCheckLib for Target and Host based unit tests. Host based unit tests are treated specially, because MSVC built host based unit tests use the MSVC C runtime lib to provide the stack cookie definitions, but GCC built host based unit tests use our implementation, as we do not link against a C runtime lib that provides the definitions. Signed-off-by: Oliver Smith-Denny <[email protected]>
This patch updates the GenC logic to generate a random stack cookie value for the stack check libraries. These random values improve security for modules which cannot update the global intrinsics. If the stack cookie value is randomized in the AutoGen.h file each build, the build system will determine the module/library must be rebuilt causing effectively a clean build every time. This also makes binary reproducibility impossible. This patch updates the early build scripts to create 32 and 64-bit JSON files in the build output directory which each contain 100 randomized stack cookie values for each bitwidth. If the JSON files are already present, then they are not recreated which allows them to be stored and moved to other builds for binary reproducibility. Because they are in the build directory, a clean build will cause the values to be regenerated. The logic which creates AutoGen.h will read these JSON files and use a hash of the module GUID (the hash seed is fixed in Basetools) to index into the array of stack cookie values for the module bitwidth. This model is necessary because there isn't thread-consistent data so we cannot use a locking mechanism to ensure only one thread is writing to the stack cookie files at a time. With this model, the build threads only need to read from the files. Signed-off-by: Oliver Smith-Denny <[email protected]>
This patch directs MSVC and GCC to build stack cookie support into binaries. Signed-off-by: Oliver Smith-Denny <[email protected]>
Now that the new stack check lib implementation is being used everywhere, remove the old one. Signed-off-by: Oliver Smith-Denny <[email protected]>
Missed one merge conflict in PrmPkg.dsc, fixed and pushed. |
⚠ WARNING: Cannot add some reviewers: A user specified as a reviewer for this PR is not a collaborator of the repository. Please add them as a collaborator to the repository so they can be requested in the future. Non-collaborators requested: Attn Admins: Admin Instructions:
|
⚠ WARNING: Cannot add some reviewers: A user specified as a reviewer for this PR is not a collaborator of the repository. Please add them as a collaborator to the repository so they can be requested in the future. Non-collaborators requested: Attn Admins: Admin Instructions:
|
I agree we need special handle for SEC module. |
But some packages have no SEC module, their pacakge DSC files are not requried to be updated, such as MdeModulePkg, FatPkg, ShellPkg, PcatChipsetPkg... |
edk2 PR tianocore/edk2#5957 removed BaseStackCheckLib and added StackCheckLibNull (amongst others). This PR updates all dscs/dsc.incs to remove the old BaseStackCheckLib and if appropriate, add StackCheckLibNull to LibraryClasses.common.SEC or to specific SEC libs. For all other component types, MdeLibs.dsc.inc links them to StackCheckLibNull. This does all dscs at once as it is formulaic and fixes build breaks. Continuous-integration-options: PatchCheck.ignore-multi-package Signed-off-by: Oliver Smith-Denny <[email protected]>
Commit ac43bba added StackCheckLibNull to MdeLibs.dsc.inc per review requests on the PR: tianocore#5957 (comment) tianocore#5957 (comment). The PR was adapted to move specifying StackCheckLibNull in every DSC to MdeLibs.dsc.inc. However, while this works, it does not allow for a platform to use one of the other StackCheckLibs (such as StackCheckLibStaticInit) because we get a linker error by having the compiler defined stack cookie variables defined more than once (once from StackCheckLibNull in MdeLibs.dsc.inc and the other in the actual StackCheckLib implementation). Every platform must include MdeLibs.dsc.inc and there is no way to override a NULL library class. So, we must go back to the original solution and include StackCheckLib in each DSC with whatever the preferred version is. In order to avoid build breaks, this PR updates all DSCs and relevant dsc.incs to add StackCheckLibNull for the CI build. It also removes it from MdeLibs.dsc.inc. As per the original PR, StackCheckLib cannot be generically linked against all SEC modules, on some IA32/X64 SEC modules, they do not include _ModuleEntryPoint, which is required when linking against a module. This has been tested that StackCheckLibStaticInit can be used in a package's CI instead of the null version now. Continuous-integration-options: PatchCheck.ignore-multi-package Signed-off-by: Oliver Smith-Denny <[email protected]>
Commit tianocore@ac43bba added StackCheckLibNull to MdeLibs.dsc.inc per review requests on the PR: tianocore#5957 (comment) tianocore#5957 (comment) The PR was adapted to move specifying StackCheckLibNull in every DSC to MdeLibs.dsc.inc. However, while this works, it does not allow for a platform to use one of the other StackCheckLibs (such as StackCheckLibStaticInit) because we get a linker error by having the compiler defined stack cookie variables defined more than once (once from StackCheckLibNull in MdeLibs.dsc.inc and the other in the actual StackCheckLib implementation). Every platform must include MdeLibs.dsc.inc and there is no way to override a NULL library class. In order to avoid build breaks, this PR updates all DSCs and relevant dsc.incs to remove StackCheckLibNull for the CI build. It also changes it to the StackCheckLib library class in MdeLibs.dsc.inc. StackCheckLib is added as a LibraryClass dependency to each of the Entry Point libs. This has been tested that StackCheckLibStaticInit can be used in a package's CI instead of the null version now. Continuous-integration-options: PatchCheck.ignore-multi-package Signed-off-by: Oliver Smith-Denny <[email protected]>
Description
This PR adds broader stack cookie support to the firmware across toolchains
and architectures.
This also pulls in a Unit Test Infrastructure commit that splits some common dependencies out from the Target and Host dsc.inc files so that Host does not depend on Target any longer. This is required for stack cookies because Target builds have stack cookies enabled and Host builds do not, without this commit we will have linkage failures.
Add StackCheckLibNull, StackCheckLibStaticInit
These libs provide the functions to link against that clang, gcc, and MSVC generate when stack cookies are enabled. For more information on what each lib does, see the README included in this PR. Each DSC then gets this linked against it.
Per the conversation on this PR, the dynamic instance is deferred to a later PR to continue working on the implementation.
Enable Stack Cookies
Finally, stack cookies are enabled for IA32, X64, ARM, and AARCH64 for gcc and MSVC.
See the README included in this patchset for full details.
How This Was Tested
Used to enable stack cookies on Project Mu devices and examine failures.
Integration Instructions
Follow the ReadMe in this PR. A summary is:
This updates 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 insertedthroughout the code. Every module should have a
StackCheckLib
instances linked to satisfythese references. So every module doesn't need to add
StackCheckLib
to the LibraryClassessection of the INF file,
StackCheckLib
instances should be linked as NULL in the platformDSC 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
.SEC and PEI_CORE modules should always use
StackCheckLibNull
and pre-memory modulesshould use
StackCheckLibStaticInit
. All other modules should useStackCheckLibDynamicInit
once it is enabled.Below is an example of how to link the
StackCheckLib
instances in the platform DSC filebut it may need customization based on the platform's requirements: