-
Notifications
You must be signed in to change notification settings - Fork 156
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
FEATURE: Add BA3031.EnableClangSafeStack #663
Changes from 3 commits
abd0cd5
4bb866a
a76da09
8cfab55
6dcc01f
2f7651e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,6 +4,52 @@ This file records scripts used to compile the test files, in alphabetical order. | |
Base scenario is a simple hello world program built with different parameters for testing purpose. | ||
Test files are located in [BaselineTestData](https://github.com/microsoft/binskim/tree/main/src/Test.FunctionalTests.BinSkim.Driver/BaselineTestData) and [FunctionalTestData](https://github.com/microsoft/binskim/tree/main/src/Test.FunctionalTests.BinSkim.Rules/FunctionalTestData). | ||
|
||
## ARM64_CETShadowStack_NotApplicable.exe | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is just a re-order alphabetically #Closed |
||
|
||
A simple C++ hellow world program, cross compiled using CMake using the `cl.exe` compiler and `Ninja` generator. | ||
`CMakePresets.json` should be configured with a `configurePresets` as below: | ||
|
||
```json | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
{ | ||
"name": "arm64-release", | ||
"displayName": "ARM64 Release", | ||
"inherits": "windows-base", | ||
"architecture": { | ||
"value": "arm64", | ||
"strategy": "external" | ||
}, | ||
"cacheVariables": { | ||
"CMAKE_BUILD_TYPE": "RelWithDebInfo" | ||
} | ||
}, | ||
``` | ||
|
||
## ARM_CETShadowStack_NotApplicable.exe | ||
|
||
A simple C++ hellow world program, cross compiled using CMake with the `cl.exe` compiler and `Ninja` generator. | ||
`CMakePresets.json` should be configured with a `configurePresets` as below: | ||
|
||
```json | ||
{ | ||
"name": "arm-release", | ||
"displayName": "ARM Release", | ||
"inherits": "windows-base", | ||
"architecture": { | ||
"value": "arm", | ||
"strategy": "external" | ||
}, | ||
"cacheVariables": { | ||
"CMAKE_BUILD_TYPE": "RelWithDebInfo" | ||
} | ||
}, | ||
``` | ||
|
||
## clang.[version].elf.[c,cpp].[no_]safe_stack | ||
|
||
A simple hello world C/C++ program, compiled with different `clang [version]` that generates a executable file. Script to reproduce: | ||
`clang++-14 -Wall hellocpp.cpp -O2 -g -gdwarf-5 -o clang.14.elf.cpp.no_safe_stack` | ||
`clang-7 -Wall helloc.c -O2 -g -gdwarf-5 -o clang.7.elf.c.safe_stack -fsanitize=safe-stack` | ||
|
||
## clang.object_file.dwarf.3.o | ||
|
||
A simple hello world program, compiled with `clang 10.0.0` that generates a .o object file. Script to reproduce: | ||
|
@@ -47,40 +93,3 @@ Also create two user functions `userfn_use_safebuffers_1()` and `userfn_use_safe | |
A simple `Windows Kernel Mode Driver` program, created with `Visual Studio 2019` that generates a .exe and associated .pdb file. Code to reproduce: | ||
Use `NTSTATUS GsDriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath)` as entry point and do not decorated with `__declspec(safebuffers)`. | ||
No user functions decorated with `__declspec(safebuffers)`. | ||
|
||
## ARM64_CETShadowStack_NotApplicable.exe | ||
A simple C++ hellow world program, cross compiled using CMake using the `cl.exe` compiler and `Ninja` generator. | ||
`CMakePresets.json` should be configured with a `configurePresets` as below: | ||
``` | ||
{ | ||
"name": "arm64-release", | ||
"displayName": "ARM64 Release", | ||
"inherits": "windows-base", | ||
"architecture": { | ||
"value": "arm64", | ||
"strategy": "external" | ||
}, | ||
"cacheVariables": { | ||
"CMAKE_BUILD_TYPE": "RelWithDebInfo" | ||
} | ||
}, | ||
``` | ||
|
||
## ARM_CETShadowStack_NotApplicable.exe | ||
|
||
A simple C++ hellow world program, cross compiled using CMake with the `cl.exe` compiler and `Ninja` generator. | ||
`CMakePresets.json` should be configured with a `configurePresets` as below: | ||
``` | ||
{ | ||
"name": "arm-release", | ||
"displayName": "ARM Release", | ||
"inherits": "windows-base", | ||
"architecture": { | ||
"value": "arm", | ||
"strategy": "external" | ||
}, | ||
"cacheVariables": { | ||
"CMAKE_BUILD_TYPE": "RelWithDebInfo" | ||
} | ||
}, | ||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
// Copyright (c) Microsoft. All rights reserved. | ||
// Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
|
||
using System.Collections.Generic; | ||
using System.Composition; | ||
using System.Linq; | ||
|
||
using ELFSharp.ELF; | ||
using ELFSharp.ELF.Sections; | ||
|
||
using Microsoft.CodeAnalysis.BinaryParsers; | ||
using Microsoft.CodeAnalysis.IL.Sdk; | ||
using Microsoft.CodeAnalysis.Sarif; | ||
using Microsoft.CodeAnalysis.Sarif.Driver; | ||
|
||
namespace Microsoft.CodeAnalysis.IL.Rules | ||
{ | ||
[Export(typeof(Skimmer<BinaryAnalyzerContext>)), Export(typeof(ReportingDescriptor))] | ||
public class EnableSafeStackWithClang : ElfBinarySkimmer | ||
{ | ||
// Symbol is the same for both C and C++, despite the "cpp" or "cc" in file name. | ||
// Clang V7 - V9: "safestack.cc.o" | ||
// Clang V10 - V14: "safestack.cpp.o" | ||
private static readonly string[] symbolSafeStack = new string[] { "safestack.cpp.o", "safestack.cc.o" }; | ||
|
||
/// <summary> | ||
/// BA3031 | ||
/// </summary> | ||
public override string Id => RuleIds.EnableSafeStackWithClang; | ||
|
||
/// <summary> | ||
/// The SafeStack instrumentation pass protects programs by implementing two separate program stacks, | ||
/// one for return addresses and local variables, and the other for everything else. | ||
/// To enable SafeStack, pass '-fsanitize=safe-stack' flag to both compile and link command lines. | ||
/// </summary> | ||
public override MultiformatMessageString FullDescription => new MultiformatMessageString { Text = RuleResources.BA3031_EnableSafeStackWithClang_Description }; | ||
|
||
protected override IEnumerable<string> MessageResourceNames => new string[] { | ||
nameof(RuleResources.BA3031_Pass), | ||
nameof(RuleResources.BA3031_Error), | ||
nameof(RuleResources.NotApplicable_InvalidMetadata) | ||
}; | ||
|
||
public override AnalysisApplicability CanAnalyzeElf(ElfBinary target, Sarif.PropertiesDictionary policy, out string reasonForNotAnalyzing) | ||
{ | ||
IELF elf = target.ELF; | ||
|
||
if (elf.Type == FileType.Core || elf.Type == FileType.None || elf.Type == FileType.Relocatable) | ||
{ | ||
reasonForNotAnalyzing = MetadataConditions.ElfIsCoreNoneOrObject; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fixed to ElfIsCoreNoneOrRelocatable |
||
return AnalysisApplicability.NotApplicableToSpecifiedTarget; | ||
} | ||
|
||
if (!target.Compilers.Any(c => c.Compiler == ElfCompilerType.Clang && c.Version.Major >= 7)) | ||
{ | ||
reasonForNotAnalyzing = MetadataConditions.ElfNotBuiltWithClangV7OrLater; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the comment is replaced by later discussions to fire a special error that says you should enable SafeStack, you might need to update your version of Clang to do this. |
||
return AnalysisApplicability.NotApplicableToSpecifiedTarget; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove this. #Resolved There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Removed the version check only, we still need to Clang check, if people just use Gcc we will skip this image as NotApplicable. |
||
|
||
reasonForNotAnalyzing = null; | ||
return AnalysisApplicability.ApplicableToSpecifiedTarget; | ||
} | ||
|
||
/// <summary> | ||
/// Checks if SafeStack is enabled by Symbols. | ||
/// </summary> | ||
public override void Analyze(BinaryAnalyzerContext context) | ||
{ | ||
IELF elf = context.ElfBinary().ELF; | ||
|
||
IEnumerable<ISymbolEntry> symbols = | ||
ElfUtility.GetAllSymbols(elf).Where(sym => sym.Type == SymbolType.File); | ||
|
||
if (symbols.Any(s => symbolSafeStack.Contains(s.Name))) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Foreach over the symbols, to avoid a 2x traversal in the pathological case. Fire a pass result and exit if you meet the first condition. Otherwise fall out and fire the error result. #Resolved There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Changed to not use Linq and just use foreach. |
||
{ | ||
context.Logger.Log(this, | ||
RuleUtilities.BuildResult(ResultKind.Pass, context, null, | ||
nameof(RuleResources.BA3031_Pass), | ||
context.TargetUri.GetFileName())); | ||
} | ||
else | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. agree with this approach, fixed. |
||
{ | ||
context.Logger.Log(this, | ||
RuleUtilities.BuildResult(FailureLevel.Error, context, null, | ||
nameof(RuleResources.BA3031_Error), | ||
context.TargetUri.GetFileName())); | ||
} | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -61,6 +61,7 @@ internal static class RuleIds | |
// BA3012-3029 -- saved for future non-compiler/language specific checks. | ||
// Compiler/Language specific checks follow. | ||
public const string UseCheckedFunctionsWithGcc = "BA3030"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fixed |
||
public const string EnableSafeStackWithClang = "BA3031"; | ||
|
||
// Reporting checks | ||
public const string ReportPortableExecutableCompilerData = "BA4001"; | ||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -951,7 +951,7 @@ | |
}, | ||
{ | ||
"id": "BA2026", | ||
"name": "EnableAdditionalSdlSecurityChecks", | ||
"name": "EnableMicrosoftCompilerSdlSwitch", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice. Thanks for fixing this. |
||
"fullDescription": { | ||
"text": "/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks." | ||
}, | ||
|
@@ -969,7 +969,7 @@ | |
"text": "'{0}' was not evaluated for check '{1}' as the analysis is not relevant based on observed metadata: {2}." | ||
} | ||
}, | ||
"helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableAdditionalSdlSecurityChecks" | ||
"helpUri": "https://github.com/microsoft/binskim/blob/main/docs/BinSkimRules.md#rule-BA2026EnableMicrosoftCompilerSdlSwitch" | ||
} | ||
], | ||
"properties": { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
EnableClangSafeStack?
I will think about the name and help refine this help text a bit further. #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed