[clang] [llvm] [analysis] Software Bill of Mitigations (PR #130103)
https://github.com/matthewlevy97 created https://github.com/llvm/llvm-project/pull/130103 The goal of this stack is to provide a metric to audit the deployed mitigations in a binary and where they are enabled at function level granularity. This will enable tracking of where we do and don't have mitigations, versus the current approach of tracking where flags are passed. Two flags are added to control this behavior: 1) Compile time `-fmitigation-analysis` to generate the metadata pertaining to mitigation enablement/disablement 2) Link time `-enable-mitigation-analysis` to generate the output JSON when building with LTO >From fb04b7bf5f2b668bf354632fc53e7521f44880c9 Mon Sep 17 00:00:00 2001 From: Matt Levy Date: Wed, 5 Mar 2025 12:36:02 -0500 Subject: [PATCH 1/2] [clang][CodeGen] Software Bill of Mitigations Metadata The goal of this stack is to create a high fidelity mapping of mitigations to their possible insertion points and their actual insertion points. This would let us track where we do and don't have mitigations rather than the current approach of tracking where we have the flag. There are some challenges posed by this like: - Some mitigations are not emitted by the compiler, but the preprocessor - Some mitigations are lowered later during IR -> MIR (stack cookies) --- clang/include/clang/Basic/CodeGenOptions.def | 1 + clang/include/clang/Driver/Options.td| 6 ++ clang/lib/CodeGen/CGBuiltin.cpp | 10 +++ clang/lib/CodeGen/CGClass.cpp| 3 + clang/lib/CodeGen/CGDecl.cpp | 4 + clang/lib/CodeGen/CGExpr.cpp | 5 ++ clang/lib/CodeGen/CGExprCXX.cpp | 6 ++ clang/lib/CodeGen/CMakeLists.txt | 1 + clang/lib/CodeGen/CodeGenModule.cpp | 22 + clang/lib/CodeGen/MitigationTagging.cpp | 84 clang/lib/CodeGen/MitigationTagging.h| 45 +++ clang/lib/Driver/ToolChains/Clang.cpp| 3 + 12 files changed, 190 insertions(+) create mode 100644 clang/lib/CodeGen/MitigationTagging.cpp create mode 100644 clang/lib/CodeGen/MitigationTagging.h diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def index a7f5f1abbb825..76a46ac3e592b 100644 --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -191,6 +191,7 @@ CODEGENOPT(NoTypeCheck , 1, 0) ///< Set when -Wa,--no-type-check is enable CODEGENOPT(MisExpect , 1, 0) ///< Set when -Wmisexpect is enabled CODEGENOPT(EnableSegmentedStacks , 1, 0) ///< Set when -fsplit-stack is enabled. CODEGENOPT(StackClashProtector, 1, 0) ///< Set when -fstack-clash-protection is enabled. +CODEGENOPT(MitigationAnalysis, 1, 0) ///< Set when -fmitigation-analysis is enabled. CODEGENOPT(NoImplicitFloat , 1, 0) ///< Set when -mno-implicit-float is enabled. CODEGENOPT(NullPointerIsValid , 1, 0) ///< Assume Null pointer deference is defined. CODEGENOPT(OpenCLCorrectlyRoundedDivSqrt, 1, 0) ///< -cl-fp32-correctly-rounded-divide-sqrt diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index d0414aba35209..e50bb5c1c2cb4 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -3891,6 +3891,12 @@ defm split_stack : BoolFOption<"split-stack", CodeGenOpts<"EnableSegmentedStacks">, DefaultFalse, NegFlag, PosFlag>; +defm mitigation_analysis : BoolFOption<"mitigation-analysis", + CodeGenOpts<"MitigationAnalysis">, DefaultFalse, + PosFlag, + NegFlag, + BothFlags<[], [ClangOption], " mitigation analysis">>, + DocBrief<"Instrument mitigations (CFI, Stack Protectors, Auto-Var-Init, StackClashProtection) to analyze their coverage">; def fstack_protector_all : Flag<["-"], "fstack-protector-all">, Group, HelpText<"Enable stack protectors for all functions">; defm stack_clash_protection : BoolFOption<"stack-clash-protection", diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index ab8f19b25fa66..4e180bb1a87cf 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -21,6 +21,7 @@ #include "CodeGenFunction.h" #include "CodeGenModule.h" #include "ConstantEmitter.h" +#include "MitigationTagging.h" #include "PatternInit.h" #include "TargetInfo.h" #include "clang/AST/ASTContext.h" @@ -83,6 +84,8 @@ static void initializeAlloca(CodeGenFunction &CGF, AllocaInst *AI, Value *Size, switch (CGF.getLangOpts().getTrivialAutoVarInit()) { case LangOptions::TrivialAutoVarInitKind::Uninitialized: // Nothing to initialize. +AttachMitigationMetadataToFunction(CGF, MitigationKey::AUTO_VAR_INIT, + false); return; case LangOptions::TrivialAutoVarInitKind::Zero: Byte = CGF.Builder.getInt8(0x00); @@ -94,6 +97,7 @@ static void initializeAlloca(CodeGenFunction &CGF, AllocaInst *AI, Value *Size, break; }
[clang] [llvm] [analysis] Software Bill of Mitigations (PR #130103)
https://github.com/matthewlevy97 updated https://github.com/llvm/llvm-project/pull/130103 >From fb04b7bf5f2b668bf354632fc53e7521f44880c9 Mon Sep 17 00:00:00 2001 From: Matt Levy Date: Wed, 5 Mar 2025 12:36:02 -0500 Subject: [PATCH 1/5] [clang][CodeGen] Software Bill of Mitigations Metadata The goal of this stack is to create a high fidelity mapping of mitigations to their possible insertion points and their actual insertion points. This would let us track where we do and don't have mitigations rather than the current approach of tracking where we have the flag. There are some challenges posed by this like: - Some mitigations are not emitted by the compiler, but the preprocessor - Some mitigations are lowered later during IR -> MIR (stack cookies) --- clang/include/clang/Basic/CodeGenOptions.def | 1 + clang/include/clang/Driver/Options.td| 6 ++ clang/lib/CodeGen/CGBuiltin.cpp | 10 +++ clang/lib/CodeGen/CGClass.cpp| 3 + clang/lib/CodeGen/CGDecl.cpp | 4 + clang/lib/CodeGen/CGExpr.cpp | 5 ++ clang/lib/CodeGen/CGExprCXX.cpp | 6 ++ clang/lib/CodeGen/CMakeLists.txt | 1 + clang/lib/CodeGen/CodeGenModule.cpp | 22 + clang/lib/CodeGen/MitigationTagging.cpp | 84 clang/lib/CodeGen/MitigationTagging.h| 45 +++ clang/lib/Driver/ToolChains/Clang.cpp| 3 + 12 files changed, 190 insertions(+) create mode 100644 clang/lib/CodeGen/MitigationTagging.cpp create mode 100644 clang/lib/CodeGen/MitigationTagging.h diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def index a7f5f1abbb825..76a46ac3e592b 100644 --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -191,6 +191,7 @@ CODEGENOPT(NoTypeCheck , 1, 0) ///< Set when -Wa,--no-type-check is enable CODEGENOPT(MisExpect , 1, 0) ///< Set when -Wmisexpect is enabled CODEGENOPT(EnableSegmentedStacks , 1, 0) ///< Set when -fsplit-stack is enabled. CODEGENOPT(StackClashProtector, 1, 0) ///< Set when -fstack-clash-protection is enabled. +CODEGENOPT(MitigationAnalysis, 1, 0) ///< Set when -fmitigation-analysis is enabled. CODEGENOPT(NoImplicitFloat , 1, 0) ///< Set when -mno-implicit-float is enabled. CODEGENOPT(NullPointerIsValid , 1, 0) ///< Assume Null pointer deference is defined. CODEGENOPT(OpenCLCorrectlyRoundedDivSqrt, 1, 0) ///< -cl-fp32-correctly-rounded-divide-sqrt diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index d0414aba35209..e50bb5c1c2cb4 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -3891,6 +3891,12 @@ defm split_stack : BoolFOption<"split-stack", CodeGenOpts<"EnableSegmentedStacks">, DefaultFalse, NegFlag, PosFlag>; +defm mitigation_analysis : BoolFOption<"mitigation-analysis", + CodeGenOpts<"MitigationAnalysis">, DefaultFalse, + PosFlag, + NegFlag, + BothFlags<[], [ClangOption], " mitigation analysis">>, + DocBrief<"Instrument mitigations (CFI, Stack Protectors, Auto-Var-Init, StackClashProtection) to analyze their coverage">; def fstack_protector_all : Flag<["-"], "fstack-protector-all">, Group, HelpText<"Enable stack protectors for all functions">; defm stack_clash_protection : BoolFOption<"stack-clash-protection", diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index ab8f19b25fa66..4e180bb1a87cf 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -21,6 +21,7 @@ #include "CodeGenFunction.h" #include "CodeGenModule.h" #include "ConstantEmitter.h" +#include "MitigationTagging.h" #include "PatternInit.h" #include "TargetInfo.h" #include "clang/AST/ASTContext.h" @@ -83,6 +84,8 @@ static void initializeAlloca(CodeGenFunction &CGF, AllocaInst *AI, Value *Size, switch (CGF.getLangOpts().getTrivialAutoVarInit()) { case LangOptions::TrivialAutoVarInitKind::Uninitialized: // Nothing to initialize. +AttachMitigationMetadataToFunction(CGF, MitigationKey::AUTO_VAR_INIT, + false); return; case LangOptions::TrivialAutoVarInitKind::Zero: Byte = CGF.Builder.getInt8(0x00); @@ -94,6 +97,7 @@ static void initializeAlloca(CodeGenFunction &CGF, AllocaInst *AI, Value *Size, break; } } + AttachMitigationMetadataToFunction(CGF, MitigationKey::AUTO_VAR_INIT, true); if (CGF.CGM.stopAutoInit()) return; auto *I = CGF.Builder.CreateMemSet(AI, Byte, Size, AlignmentInBytes); @@ -4642,6 +4646,9 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, AI->setAlignment(SuitableAlignmentInBytes); if (BuiltinID != Builtin::BI__builtin_alloca_uninitialized) initializeAlloca(*this, AI, Size, SuitableAlignmentInBytes); +else + AttachMitigationMetadataToFunction(*t
[clang] [llvm] [analysis] Software Bill of Mitigations (PR #130103)
https://github.com/matthewlevy97 updated https://github.com/llvm/llvm-project/pull/130103 >From fb04b7bf5f2b668bf354632fc53e7521f44880c9 Mon Sep 17 00:00:00 2001 From: Matt Levy Date: Wed, 5 Mar 2025 12:36:02 -0500 Subject: [PATCH 1/6] [clang][CodeGen] Software Bill of Mitigations Metadata The goal of this stack is to create a high fidelity mapping of mitigations to their possible insertion points and their actual insertion points. This would let us track where we do and don't have mitigations rather than the current approach of tracking where we have the flag. There are some challenges posed by this like: - Some mitigations are not emitted by the compiler, but the preprocessor - Some mitigations are lowered later during IR -> MIR (stack cookies) --- clang/include/clang/Basic/CodeGenOptions.def | 1 + clang/include/clang/Driver/Options.td| 6 ++ clang/lib/CodeGen/CGBuiltin.cpp | 10 +++ clang/lib/CodeGen/CGClass.cpp| 3 + clang/lib/CodeGen/CGDecl.cpp | 4 + clang/lib/CodeGen/CGExpr.cpp | 5 ++ clang/lib/CodeGen/CGExprCXX.cpp | 6 ++ clang/lib/CodeGen/CMakeLists.txt | 1 + clang/lib/CodeGen/CodeGenModule.cpp | 22 + clang/lib/CodeGen/MitigationTagging.cpp | 84 clang/lib/CodeGen/MitigationTagging.h| 45 +++ clang/lib/Driver/ToolChains/Clang.cpp| 3 + 12 files changed, 190 insertions(+) create mode 100644 clang/lib/CodeGen/MitigationTagging.cpp create mode 100644 clang/lib/CodeGen/MitigationTagging.h diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def index a7f5f1abbb825..76a46ac3e592b 100644 --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -191,6 +191,7 @@ CODEGENOPT(NoTypeCheck , 1, 0) ///< Set when -Wa,--no-type-check is enable CODEGENOPT(MisExpect , 1, 0) ///< Set when -Wmisexpect is enabled CODEGENOPT(EnableSegmentedStacks , 1, 0) ///< Set when -fsplit-stack is enabled. CODEGENOPT(StackClashProtector, 1, 0) ///< Set when -fstack-clash-protection is enabled. +CODEGENOPT(MitigationAnalysis, 1, 0) ///< Set when -fmitigation-analysis is enabled. CODEGENOPT(NoImplicitFloat , 1, 0) ///< Set when -mno-implicit-float is enabled. CODEGENOPT(NullPointerIsValid , 1, 0) ///< Assume Null pointer deference is defined. CODEGENOPT(OpenCLCorrectlyRoundedDivSqrt, 1, 0) ///< -cl-fp32-correctly-rounded-divide-sqrt diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index d0414aba35209..e50bb5c1c2cb4 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -3891,6 +3891,12 @@ defm split_stack : BoolFOption<"split-stack", CodeGenOpts<"EnableSegmentedStacks">, DefaultFalse, NegFlag, PosFlag>; +defm mitigation_analysis : BoolFOption<"mitigation-analysis", + CodeGenOpts<"MitigationAnalysis">, DefaultFalse, + PosFlag, + NegFlag, + BothFlags<[], [ClangOption], " mitigation analysis">>, + DocBrief<"Instrument mitigations (CFI, Stack Protectors, Auto-Var-Init, StackClashProtection) to analyze their coverage">; def fstack_protector_all : Flag<["-"], "fstack-protector-all">, Group, HelpText<"Enable stack protectors for all functions">; defm stack_clash_protection : BoolFOption<"stack-clash-protection", diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index ab8f19b25fa66..4e180bb1a87cf 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -21,6 +21,7 @@ #include "CodeGenFunction.h" #include "CodeGenModule.h" #include "ConstantEmitter.h" +#include "MitigationTagging.h" #include "PatternInit.h" #include "TargetInfo.h" #include "clang/AST/ASTContext.h" @@ -83,6 +84,8 @@ static void initializeAlloca(CodeGenFunction &CGF, AllocaInst *AI, Value *Size, switch (CGF.getLangOpts().getTrivialAutoVarInit()) { case LangOptions::TrivialAutoVarInitKind::Uninitialized: // Nothing to initialize. +AttachMitigationMetadataToFunction(CGF, MitigationKey::AUTO_VAR_INIT, + false); return; case LangOptions::TrivialAutoVarInitKind::Zero: Byte = CGF.Builder.getInt8(0x00); @@ -94,6 +97,7 @@ static void initializeAlloca(CodeGenFunction &CGF, AllocaInst *AI, Value *Size, break; } } + AttachMitigationMetadataToFunction(CGF, MitigationKey::AUTO_VAR_INIT, true); if (CGF.CGM.stopAutoInit()) return; auto *I = CGF.Builder.CreateMemSet(AI, Byte, Size, AlignmentInBytes); @@ -4642,6 +4646,9 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, AI->setAlignment(SuitableAlignmentInBytes); if (BuiltinID != Builtin::BI__builtin_alloca_uninitialized) initializeAlloca(*this, AI, Size, SuitableAlignmentInBytes); +else + AttachMitigationMetadataToFunction(*t
[clang] [llvm] [analysis] Software Bill of Mitigations (PR #130103)
matthewlevy97 wrote: @efriedma-quic That is correct about this just tracking where mitigations are emitted. I believe the emissions points should largely correlate with where they would get instrumented, but if this analysis runs super late (after all optimizations, etc.) to determine exactly if/where mitigations actually get instrumented, it might become more of a binary analysis task and greatly increase complexity. I am open to suggestions on different approaches. The use case isn't really to verify that mitigations are enabled, but provide a way of tracking incremental deployments of mitigations (e.g., large binary where a given mitigation being deployed causes to large of a regression so only certain sub-units have a given mitigation). I have a follow-up diff that outputs a summary instead of a per-function tracking to show overall coverage on mitigations in the binary which I assume will be the more used option. https://github.com/llvm/llvm-project/pull/130103 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [analysis] Software Bill of Mitigations (PR #130103)
https://github.com/matthewlevy97 updated https://github.com/llvm/llvm-project/pull/130103 >From fb04b7bf5f2b668bf354632fc53e7521f44880c9 Mon Sep 17 00:00:00 2001 From: Matt Levy Date: Wed, 5 Mar 2025 12:36:02 -0500 Subject: [PATCH 1/5] [clang][CodeGen] Software Bill of Mitigations Metadata The goal of this stack is to create a high fidelity mapping of mitigations to their possible insertion points and their actual insertion points. This would let us track where we do and don't have mitigations rather than the current approach of tracking where we have the flag. There are some challenges posed by this like: - Some mitigations are not emitted by the compiler, but the preprocessor - Some mitigations are lowered later during IR -> MIR (stack cookies) --- clang/include/clang/Basic/CodeGenOptions.def | 1 + clang/include/clang/Driver/Options.td| 6 ++ clang/lib/CodeGen/CGBuiltin.cpp | 10 +++ clang/lib/CodeGen/CGClass.cpp| 3 + clang/lib/CodeGen/CGDecl.cpp | 4 + clang/lib/CodeGen/CGExpr.cpp | 5 ++ clang/lib/CodeGen/CGExprCXX.cpp | 6 ++ clang/lib/CodeGen/CMakeLists.txt | 1 + clang/lib/CodeGen/CodeGenModule.cpp | 22 + clang/lib/CodeGen/MitigationTagging.cpp | 84 clang/lib/CodeGen/MitigationTagging.h| 45 +++ clang/lib/Driver/ToolChains/Clang.cpp| 3 + 12 files changed, 190 insertions(+) create mode 100644 clang/lib/CodeGen/MitigationTagging.cpp create mode 100644 clang/lib/CodeGen/MitigationTagging.h diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def index a7f5f1abbb825..76a46ac3e592b 100644 --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -191,6 +191,7 @@ CODEGENOPT(NoTypeCheck , 1, 0) ///< Set when -Wa,--no-type-check is enable CODEGENOPT(MisExpect , 1, 0) ///< Set when -Wmisexpect is enabled CODEGENOPT(EnableSegmentedStacks , 1, 0) ///< Set when -fsplit-stack is enabled. CODEGENOPT(StackClashProtector, 1, 0) ///< Set when -fstack-clash-protection is enabled. +CODEGENOPT(MitigationAnalysis, 1, 0) ///< Set when -fmitigation-analysis is enabled. CODEGENOPT(NoImplicitFloat , 1, 0) ///< Set when -mno-implicit-float is enabled. CODEGENOPT(NullPointerIsValid , 1, 0) ///< Assume Null pointer deference is defined. CODEGENOPT(OpenCLCorrectlyRoundedDivSqrt, 1, 0) ///< -cl-fp32-correctly-rounded-divide-sqrt diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index d0414aba35209..e50bb5c1c2cb4 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -3891,6 +3891,12 @@ defm split_stack : BoolFOption<"split-stack", CodeGenOpts<"EnableSegmentedStacks">, DefaultFalse, NegFlag, PosFlag>; +defm mitigation_analysis : BoolFOption<"mitigation-analysis", + CodeGenOpts<"MitigationAnalysis">, DefaultFalse, + PosFlag, + NegFlag, + BothFlags<[], [ClangOption], " mitigation analysis">>, + DocBrief<"Instrument mitigations (CFI, Stack Protectors, Auto-Var-Init, StackClashProtection) to analyze their coverage">; def fstack_protector_all : Flag<["-"], "fstack-protector-all">, Group, HelpText<"Enable stack protectors for all functions">; defm stack_clash_protection : BoolFOption<"stack-clash-protection", diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index ab8f19b25fa66..4e180bb1a87cf 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -21,6 +21,7 @@ #include "CodeGenFunction.h" #include "CodeGenModule.h" #include "ConstantEmitter.h" +#include "MitigationTagging.h" #include "PatternInit.h" #include "TargetInfo.h" #include "clang/AST/ASTContext.h" @@ -83,6 +84,8 @@ static void initializeAlloca(CodeGenFunction &CGF, AllocaInst *AI, Value *Size, switch (CGF.getLangOpts().getTrivialAutoVarInit()) { case LangOptions::TrivialAutoVarInitKind::Uninitialized: // Nothing to initialize. +AttachMitigationMetadataToFunction(CGF, MitigationKey::AUTO_VAR_INIT, + false); return; case LangOptions::TrivialAutoVarInitKind::Zero: Byte = CGF.Builder.getInt8(0x00); @@ -94,6 +97,7 @@ static void initializeAlloca(CodeGenFunction &CGF, AllocaInst *AI, Value *Size, break; } } + AttachMitigationMetadataToFunction(CGF, MitigationKey::AUTO_VAR_INIT, true); if (CGF.CGM.stopAutoInit()) return; auto *I = CGF.Builder.CreateMemSet(AI, Byte, Size, AlignmentInBytes); @@ -4642,6 +4646,9 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, AI->setAlignment(SuitableAlignmentInBytes); if (BuiltinID != Builtin::BI__builtin_alloca_uninitialized) initializeAlloca(*this, AI, Size, SuitableAlignmentInBytes); +else + AttachMitigationMetadataToFunction(*t
[clang] [llvm] [analysis] Software Bill of Mitigations (PR #130103)
https://github.com/matthewlevy97 updated https://github.com/llvm/llvm-project/pull/130103 >From fb04b7bf5f2b668bf354632fc53e7521f44880c9 Mon Sep 17 00:00:00 2001 From: Matt Levy Date: Wed, 5 Mar 2025 12:36:02 -0500 Subject: [PATCH 1/6] [clang][CodeGen] Software Bill of Mitigations Metadata The goal of this stack is to create a high fidelity mapping of mitigations to their possible insertion points and their actual insertion points. This would let us track where we do and don't have mitigations rather than the current approach of tracking where we have the flag. There are some challenges posed by this like: - Some mitigations are not emitted by the compiler, but the preprocessor - Some mitigations are lowered later during IR -> MIR (stack cookies) --- clang/include/clang/Basic/CodeGenOptions.def | 1 + clang/include/clang/Driver/Options.td| 6 ++ clang/lib/CodeGen/CGBuiltin.cpp | 10 +++ clang/lib/CodeGen/CGClass.cpp| 3 + clang/lib/CodeGen/CGDecl.cpp | 4 + clang/lib/CodeGen/CGExpr.cpp | 5 ++ clang/lib/CodeGen/CGExprCXX.cpp | 6 ++ clang/lib/CodeGen/CMakeLists.txt | 1 + clang/lib/CodeGen/CodeGenModule.cpp | 22 + clang/lib/CodeGen/MitigationTagging.cpp | 84 clang/lib/CodeGen/MitigationTagging.h| 45 +++ clang/lib/Driver/ToolChains/Clang.cpp| 3 + 12 files changed, 190 insertions(+) create mode 100644 clang/lib/CodeGen/MitigationTagging.cpp create mode 100644 clang/lib/CodeGen/MitigationTagging.h diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def index a7f5f1abbb825..76a46ac3e592b 100644 --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -191,6 +191,7 @@ CODEGENOPT(NoTypeCheck , 1, 0) ///< Set when -Wa,--no-type-check is enable CODEGENOPT(MisExpect , 1, 0) ///< Set when -Wmisexpect is enabled CODEGENOPT(EnableSegmentedStacks , 1, 0) ///< Set when -fsplit-stack is enabled. CODEGENOPT(StackClashProtector, 1, 0) ///< Set when -fstack-clash-protection is enabled. +CODEGENOPT(MitigationAnalysis, 1, 0) ///< Set when -fmitigation-analysis is enabled. CODEGENOPT(NoImplicitFloat , 1, 0) ///< Set when -mno-implicit-float is enabled. CODEGENOPT(NullPointerIsValid , 1, 0) ///< Assume Null pointer deference is defined. CODEGENOPT(OpenCLCorrectlyRoundedDivSqrt, 1, 0) ///< -cl-fp32-correctly-rounded-divide-sqrt diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index d0414aba35209..e50bb5c1c2cb4 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -3891,6 +3891,12 @@ defm split_stack : BoolFOption<"split-stack", CodeGenOpts<"EnableSegmentedStacks">, DefaultFalse, NegFlag, PosFlag>; +defm mitigation_analysis : BoolFOption<"mitigation-analysis", + CodeGenOpts<"MitigationAnalysis">, DefaultFalse, + PosFlag, + NegFlag, + BothFlags<[], [ClangOption], " mitigation analysis">>, + DocBrief<"Instrument mitigations (CFI, Stack Protectors, Auto-Var-Init, StackClashProtection) to analyze their coverage">; def fstack_protector_all : Flag<["-"], "fstack-protector-all">, Group, HelpText<"Enable stack protectors for all functions">; defm stack_clash_protection : BoolFOption<"stack-clash-protection", diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index ab8f19b25fa66..4e180bb1a87cf 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -21,6 +21,7 @@ #include "CodeGenFunction.h" #include "CodeGenModule.h" #include "ConstantEmitter.h" +#include "MitigationTagging.h" #include "PatternInit.h" #include "TargetInfo.h" #include "clang/AST/ASTContext.h" @@ -83,6 +84,8 @@ static void initializeAlloca(CodeGenFunction &CGF, AllocaInst *AI, Value *Size, switch (CGF.getLangOpts().getTrivialAutoVarInit()) { case LangOptions::TrivialAutoVarInitKind::Uninitialized: // Nothing to initialize. +AttachMitigationMetadataToFunction(CGF, MitigationKey::AUTO_VAR_INIT, + false); return; case LangOptions::TrivialAutoVarInitKind::Zero: Byte = CGF.Builder.getInt8(0x00); @@ -94,6 +97,7 @@ static void initializeAlloca(CodeGenFunction &CGF, AllocaInst *AI, Value *Size, break; } } + AttachMitigationMetadataToFunction(CGF, MitigationKey::AUTO_VAR_INIT, true); if (CGF.CGM.stopAutoInit()) return; auto *I = CGF.Builder.CreateMemSet(AI, Byte, Size, AlignmentInBytes); @@ -4642,6 +4646,9 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, AI->setAlignment(SuitableAlignmentInBytes); if (BuiltinID != Builtin::BI__builtin_alloca_uninitialized) initializeAlloca(*this, AI, Size, SuitableAlignmentInBytes); +else + AttachMitigationMetadataToFunction(*t
[clang] [llvm] [analysis] Software Bill of Mitigations (PR #130103)
https://github.com/matthewlevy97 updated https://github.com/llvm/llvm-project/pull/130103 >From fb04b7bf5f2b668bf354632fc53e7521f44880c9 Mon Sep 17 00:00:00 2001 From: Matt Levy Date: Wed, 5 Mar 2025 12:36:02 -0500 Subject: [PATCH 1/3] [clang][CodeGen] Software Bill of Mitigations Metadata The goal of this stack is to create a high fidelity mapping of mitigations to their possible insertion points and their actual insertion points. This would let us track where we do and don't have mitigations rather than the current approach of tracking where we have the flag. There are some challenges posed by this like: - Some mitigations are not emitted by the compiler, but the preprocessor - Some mitigations are lowered later during IR -> MIR (stack cookies) --- clang/include/clang/Basic/CodeGenOptions.def | 1 + clang/include/clang/Driver/Options.td| 6 ++ clang/lib/CodeGen/CGBuiltin.cpp | 10 +++ clang/lib/CodeGen/CGClass.cpp| 3 + clang/lib/CodeGen/CGDecl.cpp | 4 + clang/lib/CodeGen/CGExpr.cpp | 5 ++ clang/lib/CodeGen/CGExprCXX.cpp | 6 ++ clang/lib/CodeGen/CMakeLists.txt | 1 + clang/lib/CodeGen/CodeGenModule.cpp | 22 + clang/lib/CodeGen/MitigationTagging.cpp | 84 clang/lib/CodeGen/MitigationTagging.h| 45 +++ clang/lib/Driver/ToolChains/Clang.cpp| 3 + 12 files changed, 190 insertions(+) create mode 100644 clang/lib/CodeGen/MitigationTagging.cpp create mode 100644 clang/lib/CodeGen/MitigationTagging.h diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def index a7f5f1abbb825..76a46ac3e592b 100644 --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -191,6 +191,7 @@ CODEGENOPT(NoTypeCheck , 1, 0) ///< Set when -Wa,--no-type-check is enable CODEGENOPT(MisExpect , 1, 0) ///< Set when -Wmisexpect is enabled CODEGENOPT(EnableSegmentedStacks , 1, 0) ///< Set when -fsplit-stack is enabled. CODEGENOPT(StackClashProtector, 1, 0) ///< Set when -fstack-clash-protection is enabled. +CODEGENOPT(MitigationAnalysis, 1, 0) ///< Set when -fmitigation-analysis is enabled. CODEGENOPT(NoImplicitFloat , 1, 0) ///< Set when -mno-implicit-float is enabled. CODEGENOPT(NullPointerIsValid , 1, 0) ///< Assume Null pointer deference is defined. CODEGENOPT(OpenCLCorrectlyRoundedDivSqrt, 1, 0) ///< -cl-fp32-correctly-rounded-divide-sqrt diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index d0414aba35209..e50bb5c1c2cb4 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -3891,6 +3891,12 @@ defm split_stack : BoolFOption<"split-stack", CodeGenOpts<"EnableSegmentedStacks">, DefaultFalse, NegFlag, PosFlag>; +defm mitigation_analysis : BoolFOption<"mitigation-analysis", + CodeGenOpts<"MitigationAnalysis">, DefaultFalse, + PosFlag, + NegFlag, + BothFlags<[], [ClangOption], " mitigation analysis">>, + DocBrief<"Instrument mitigations (CFI, Stack Protectors, Auto-Var-Init, StackClashProtection) to analyze their coverage">; def fstack_protector_all : Flag<["-"], "fstack-protector-all">, Group, HelpText<"Enable stack protectors for all functions">; defm stack_clash_protection : BoolFOption<"stack-clash-protection", diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index ab8f19b25fa66..4e180bb1a87cf 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -21,6 +21,7 @@ #include "CodeGenFunction.h" #include "CodeGenModule.h" #include "ConstantEmitter.h" +#include "MitigationTagging.h" #include "PatternInit.h" #include "TargetInfo.h" #include "clang/AST/ASTContext.h" @@ -83,6 +84,8 @@ static void initializeAlloca(CodeGenFunction &CGF, AllocaInst *AI, Value *Size, switch (CGF.getLangOpts().getTrivialAutoVarInit()) { case LangOptions::TrivialAutoVarInitKind::Uninitialized: // Nothing to initialize. +AttachMitigationMetadataToFunction(CGF, MitigationKey::AUTO_VAR_INIT, + false); return; case LangOptions::TrivialAutoVarInitKind::Zero: Byte = CGF.Builder.getInt8(0x00); @@ -94,6 +97,7 @@ static void initializeAlloca(CodeGenFunction &CGF, AllocaInst *AI, Value *Size, break; } } + AttachMitigationMetadataToFunction(CGF, MitigationKey::AUTO_VAR_INIT, true); if (CGF.CGM.stopAutoInit()) return; auto *I = CGF.Builder.CreateMemSet(AI, Byte, Size, AlignmentInBytes); @@ -4642,6 +4646,9 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, AI->setAlignment(SuitableAlignmentInBytes); if (BuiltinID != Builtin::BI__builtin_alloca_uninitialized) initializeAlloca(*this, AI, Size, SuitableAlignmentInBytes); +else + AttachMitigationMetadataToFunction(*t
[clang] [llvm] [analysis] Software Bill of Mitigations (PR #130103)
https://github.com/matthewlevy97 updated https://github.com/llvm/llvm-project/pull/130103 >From fb04b7bf5f2b668bf354632fc53e7521f44880c9 Mon Sep 17 00:00:00 2001 From: Matt Levy Date: Wed, 5 Mar 2025 12:36:02 -0500 Subject: [PATCH 1/3] [clang][CodeGen] Software Bill of Mitigations Metadata The goal of this stack is to create a high fidelity mapping of mitigations to their possible insertion points and their actual insertion points. This would let us track where we do and don't have mitigations rather than the current approach of tracking where we have the flag. There are some challenges posed by this like: - Some mitigations are not emitted by the compiler, but the preprocessor - Some mitigations are lowered later during IR -> MIR (stack cookies) --- clang/include/clang/Basic/CodeGenOptions.def | 1 + clang/include/clang/Driver/Options.td| 6 ++ clang/lib/CodeGen/CGBuiltin.cpp | 10 +++ clang/lib/CodeGen/CGClass.cpp| 3 + clang/lib/CodeGen/CGDecl.cpp | 4 + clang/lib/CodeGen/CGExpr.cpp | 5 ++ clang/lib/CodeGen/CGExprCXX.cpp | 6 ++ clang/lib/CodeGen/CMakeLists.txt | 1 + clang/lib/CodeGen/CodeGenModule.cpp | 22 + clang/lib/CodeGen/MitigationTagging.cpp | 84 clang/lib/CodeGen/MitigationTagging.h| 45 +++ clang/lib/Driver/ToolChains/Clang.cpp| 3 + 12 files changed, 190 insertions(+) create mode 100644 clang/lib/CodeGen/MitigationTagging.cpp create mode 100644 clang/lib/CodeGen/MitigationTagging.h diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def index a7f5f1abbb825..76a46ac3e592b 100644 --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -191,6 +191,7 @@ CODEGENOPT(NoTypeCheck , 1, 0) ///< Set when -Wa,--no-type-check is enable CODEGENOPT(MisExpect , 1, 0) ///< Set when -Wmisexpect is enabled CODEGENOPT(EnableSegmentedStacks , 1, 0) ///< Set when -fsplit-stack is enabled. CODEGENOPT(StackClashProtector, 1, 0) ///< Set when -fstack-clash-protection is enabled. +CODEGENOPT(MitigationAnalysis, 1, 0) ///< Set when -fmitigation-analysis is enabled. CODEGENOPT(NoImplicitFloat , 1, 0) ///< Set when -mno-implicit-float is enabled. CODEGENOPT(NullPointerIsValid , 1, 0) ///< Assume Null pointer deference is defined. CODEGENOPT(OpenCLCorrectlyRoundedDivSqrt, 1, 0) ///< -cl-fp32-correctly-rounded-divide-sqrt diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index d0414aba35209..e50bb5c1c2cb4 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -3891,6 +3891,12 @@ defm split_stack : BoolFOption<"split-stack", CodeGenOpts<"EnableSegmentedStacks">, DefaultFalse, NegFlag, PosFlag>; +defm mitigation_analysis : BoolFOption<"mitigation-analysis", + CodeGenOpts<"MitigationAnalysis">, DefaultFalse, + PosFlag, + NegFlag, + BothFlags<[], [ClangOption], " mitigation analysis">>, + DocBrief<"Instrument mitigations (CFI, Stack Protectors, Auto-Var-Init, StackClashProtection) to analyze their coverage">; def fstack_protector_all : Flag<["-"], "fstack-protector-all">, Group, HelpText<"Enable stack protectors for all functions">; defm stack_clash_protection : BoolFOption<"stack-clash-protection", diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index ab8f19b25fa66..4e180bb1a87cf 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -21,6 +21,7 @@ #include "CodeGenFunction.h" #include "CodeGenModule.h" #include "ConstantEmitter.h" +#include "MitigationTagging.h" #include "PatternInit.h" #include "TargetInfo.h" #include "clang/AST/ASTContext.h" @@ -83,6 +84,8 @@ static void initializeAlloca(CodeGenFunction &CGF, AllocaInst *AI, Value *Size, switch (CGF.getLangOpts().getTrivialAutoVarInit()) { case LangOptions::TrivialAutoVarInitKind::Uninitialized: // Nothing to initialize. +AttachMitigationMetadataToFunction(CGF, MitigationKey::AUTO_VAR_INIT, + false); return; case LangOptions::TrivialAutoVarInitKind::Zero: Byte = CGF.Builder.getInt8(0x00); @@ -94,6 +97,7 @@ static void initializeAlloca(CodeGenFunction &CGF, AllocaInst *AI, Value *Size, break; } } + AttachMitigationMetadataToFunction(CGF, MitigationKey::AUTO_VAR_INIT, true); if (CGF.CGM.stopAutoInit()) return; auto *I = CGF.Builder.CreateMemSet(AI, Byte, Size, AlignmentInBytes); @@ -4642,6 +4646,9 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, AI->setAlignment(SuitableAlignmentInBytes); if (BuiltinID != Builtin::BI__builtin_alloca_uninitialized) initializeAlloca(*this, AI, Size, SuitableAlignmentInBytes); +else + AttachMitigationMetadataToFunction(*t
[clang] [llvm] [analysis] Software Bill of Mitigations (PR #130103)
https://github.com/matthewlevy97 edited https://github.com/llvm/llvm-project/pull/130103 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [analysis] Software Bill of Mitigations (PR #130103)
https://github.com/matthewlevy97 updated https://github.com/llvm/llvm-project/pull/130103 >From fb04b7bf5f2b668bf354632fc53e7521f44880c9 Mon Sep 17 00:00:00 2001 From: Matt Levy Date: Wed, 5 Mar 2025 12:36:02 -0500 Subject: [PATCH 1/4] [clang][CodeGen] Software Bill of Mitigations Metadata The goal of this stack is to create a high fidelity mapping of mitigations to their possible insertion points and their actual insertion points. This would let us track where we do and don't have mitigations rather than the current approach of tracking where we have the flag. There are some challenges posed by this like: - Some mitigations are not emitted by the compiler, but the preprocessor - Some mitigations are lowered later during IR -> MIR (stack cookies) --- clang/include/clang/Basic/CodeGenOptions.def | 1 + clang/include/clang/Driver/Options.td| 6 ++ clang/lib/CodeGen/CGBuiltin.cpp | 10 +++ clang/lib/CodeGen/CGClass.cpp| 3 + clang/lib/CodeGen/CGDecl.cpp | 4 + clang/lib/CodeGen/CGExpr.cpp | 5 ++ clang/lib/CodeGen/CGExprCXX.cpp | 6 ++ clang/lib/CodeGen/CMakeLists.txt | 1 + clang/lib/CodeGen/CodeGenModule.cpp | 22 + clang/lib/CodeGen/MitigationTagging.cpp | 84 clang/lib/CodeGen/MitigationTagging.h| 45 +++ clang/lib/Driver/ToolChains/Clang.cpp| 3 + 12 files changed, 190 insertions(+) create mode 100644 clang/lib/CodeGen/MitigationTagging.cpp create mode 100644 clang/lib/CodeGen/MitigationTagging.h diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def index a7f5f1abbb825..76a46ac3e592b 100644 --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -191,6 +191,7 @@ CODEGENOPT(NoTypeCheck , 1, 0) ///< Set when -Wa,--no-type-check is enable CODEGENOPT(MisExpect , 1, 0) ///< Set when -Wmisexpect is enabled CODEGENOPT(EnableSegmentedStacks , 1, 0) ///< Set when -fsplit-stack is enabled. CODEGENOPT(StackClashProtector, 1, 0) ///< Set when -fstack-clash-protection is enabled. +CODEGENOPT(MitigationAnalysis, 1, 0) ///< Set when -fmitigation-analysis is enabled. CODEGENOPT(NoImplicitFloat , 1, 0) ///< Set when -mno-implicit-float is enabled. CODEGENOPT(NullPointerIsValid , 1, 0) ///< Assume Null pointer deference is defined. CODEGENOPT(OpenCLCorrectlyRoundedDivSqrt, 1, 0) ///< -cl-fp32-correctly-rounded-divide-sqrt diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index d0414aba35209..e50bb5c1c2cb4 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -3891,6 +3891,12 @@ defm split_stack : BoolFOption<"split-stack", CodeGenOpts<"EnableSegmentedStacks">, DefaultFalse, NegFlag, PosFlag>; +defm mitigation_analysis : BoolFOption<"mitigation-analysis", + CodeGenOpts<"MitigationAnalysis">, DefaultFalse, + PosFlag, + NegFlag, + BothFlags<[], [ClangOption], " mitigation analysis">>, + DocBrief<"Instrument mitigations (CFI, Stack Protectors, Auto-Var-Init, StackClashProtection) to analyze their coverage">; def fstack_protector_all : Flag<["-"], "fstack-protector-all">, Group, HelpText<"Enable stack protectors for all functions">; defm stack_clash_protection : BoolFOption<"stack-clash-protection", diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index ab8f19b25fa66..4e180bb1a87cf 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -21,6 +21,7 @@ #include "CodeGenFunction.h" #include "CodeGenModule.h" #include "ConstantEmitter.h" +#include "MitigationTagging.h" #include "PatternInit.h" #include "TargetInfo.h" #include "clang/AST/ASTContext.h" @@ -83,6 +84,8 @@ static void initializeAlloca(CodeGenFunction &CGF, AllocaInst *AI, Value *Size, switch (CGF.getLangOpts().getTrivialAutoVarInit()) { case LangOptions::TrivialAutoVarInitKind::Uninitialized: // Nothing to initialize. +AttachMitigationMetadataToFunction(CGF, MitigationKey::AUTO_VAR_INIT, + false); return; case LangOptions::TrivialAutoVarInitKind::Zero: Byte = CGF.Builder.getInt8(0x00); @@ -94,6 +97,7 @@ static void initializeAlloca(CodeGenFunction &CGF, AllocaInst *AI, Value *Size, break; } } + AttachMitigationMetadataToFunction(CGF, MitigationKey::AUTO_VAR_INIT, true); if (CGF.CGM.stopAutoInit()) return; auto *I = CGF.Builder.CreateMemSet(AI, Byte, Size, AlignmentInBytes); @@ -4642,6 +4646,9 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, AI->setAlignment(SuitableAlignmentInBytes); if (BuiltinID != Builtin::BI__builtin_alloca_uninitialized) initializeAlloca(*this, AI, Size, SuitableAlignmentInBytes); +else + AttachMitigationMetadataToFunction(*t
[clang] [llvm] [analysis] Software Bill of Mitigations (PR #130103)
https://github.com/matthewlevy97 edited https://github.com/llvm/llvm-project/pull/130103 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits