-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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 .NET Libraries fuzzing targets and automation #101993
Changes from 35 commits
2b30105
1ea296f
c8b351e
8f5945a
4358dda
26c6820
b9a83a9
0b21ae4
acd6d02
f5f8ddf
35276be
4db747e
702545d
64e1932
3b8e258
eda23f4
b428dd9
aa3efe6
9923f0c
cd6161d
0b2cd98
8113b8d
6603ff2
eaf3d60
078d217
dcbda32
53bab43
03f5d8b
12004ef
d209cf7
9fe39da
02034a4
44116ff
6f4cea3
70857b2
fc79990
fe24c98
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 |
---|---|---|
@@ -0,0 +1,107 @@ | ||
trigger: none | ||
|
||
schedules: | ||
- cron: "0 10 * * *" # 10 AM UTC | ||
displayName: OneFuzz deployment nightly run | ||
branches: | ||
include: | ||
- main | ||
|
||
variables: | ||
- template: ../variables.yml | ||
- name: fuzzerProject | ||
value: $(Build.SourcesDirectory)/src/libraries/Fuzzing/DotnetFuzzing | ||
- name: dotnetPath | ||
value: $(Build.SourcesDirectory)/.dotnet/dotnet | ||
|
||
extends: | ||
template: /eng/pipelines/common/templates/pipeline-with-resources.yml | ||
parameters: | ||
stages: | ||
- stage: Build | ||
jobs: | ||
- job: windows | ||
displayName: Build & Deploy to OneFuzz | ||
timeoutInMinutes: 120 | ||
pool: | ||
name: $(DncEngInternalBuildPool) | ||
demands: ImageOverride -equals windows.vs2022.amd64 | ||
|
||
steps: | ||
- checkout: self | ||
clean: true | ||
fetchDepth: 1 | ||
lfs: false | ||
|
||
- powershell: | | ||
cd $(Build.SourcesDirectory) | ||
./build.cmd clr+libs+packs+host -rc Checked -c Debug | ||
displayName: Build runtime (checked + debug) | ||
|
||
- powershell: | | ||
cd $(fuzzerProject) | ||
$(dotnetPath) publish -o publish | ||
displayName: Build Fuzzing targets | ||
|
||
- powershell: | | ||
cd $(fuzzerProject) | ||
$(dotnetPath) tool install --tool-path . SharpFuzz.CommandLine | ||
displayName: Install SharpFuzz.CommandLine | ||
|
||
- powershell: | | ||
cd $(fuzzerProject) | ||
publish/DotnetFuzzing.exe prepare-onefuzz deployment | ||
displayName: Prepare OneFuzz deployment | ||
|
||
# OneFuzz can't currently handle a single deployment where multiple jobs share similar assemblies/pdbs. | ||
# As a workaround, we emit a task for every fuzzing target individually. | ||
# https://fuzzfest.visualstudio.com/Onefuzz/_workitems/edit/191504/ is tracking this issue. | ||
# - task: onefuzz-task@0 | ||
# inputs: | ||
# onefuzzOSes: 'Windows' | ||
# env: | ||
# onefuzzDropDirectory: $(fuzzerProject)/deployment | ||
# SYSTEM_ACCESSTOKEN: $(System.AccessToken) | ||
# displayName: Send to OneFuzz | ||
|
||
# ONEFUZZ_TASK_WORKAROUND_START | ||
- task: onefuzz-task@0 | ||
inputs: | ||
onefuzzOSes: 'Windows' | ||
env: | ||
onefuzzDropDirectory: $(fuzzerProject)/deployment/HttpHeadersFuzzer | ||
SYSTEM_ACCESSTOKEN: $(System.AccessToken) | ||
displayName: Send HttpHeadersFuzzer to OneFuzz | ||
|
||
- task: onefuzz-task@0 | ||
inputs: | ||
onefuzzOSes: 'Windows' | ||
env: | ||
onefuzzDropDirectory: $(fuzzerProject)/deployment/JsonDocumentFuzzer | ||
SYSTEM_ACCESSTOKEN: $(System.AccessToken) | ||
displayName: Send JsonDocumentFuzzer to OneFuzz | ||
|
||
- task: onefuzz-task@0 | ||
inputs: | ||
onefuzzOSes: 'Windows' | ||
env: | ||
onefuzzDropDirectory: $(fuzzerProject)/deployment/SearchValuesByteCharFuzzer | ||
SYSTEM_ACCESSTOKEN: $(System.AccessToken) | ||
displayName: Send SearchValuesByteCharFuzzer to OneFuzz | ||
|
||
- task: onefuzz-task@0 | ||
inputs: | ||
onefuzzOSes: 'Windows' | ||
env: | ||
onefuzzDropDirectory: $(fuzzerProject)/deployment/SearchValuesStringFuzzer | ||
SYSTEM_ACCESSTOKEN: $(System.AccessToken) | ||
displayName: Send SearchValuesStringFuzzer to OneFuzz | ||
|
||
- task: onefuzz-task@0 | ||
inputs: | ||
onefuzzOSes: 'Windows' | ||
env: | ||
onefuzzDropDirectory: $(fuzzerProject)/deployment/UTF8Fuzzer | ||
SYSTEM_ACCESSTOKEN: $(System.AccessToken) | ||
displayName: Send UTF8Fuzzer to OneFuzz | ||
# ONEFUZZ_TASK_WORKAROUND_END |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
TempNugetCache | ||
publish | ||
deployment | ||
inputs | ||
crash-* |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<Project> | ||
<PropertyGroup> | ||
<NetCoreAppCurrentVersion>9.0</NetCoreAppCurrentVersion> | ||
<NetCoreAppCurrent>net$(NetCoreAppCurrentVersion)</NetCoreAppCurrent> | ||
Comment on lines
+3
to
+4
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 can't share the same settings that the rest of the repo uses? 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. I think it should be possible, I just gave up after spending a few hours bashing my head against different configurations that wouldn't compile. |
||
<ProductVersion>$(NetCoreAppCurrentVersion).0</ProductVersion> | ||
<TestUtilities>..\..\Common\tests\TestUtilities</TestUtilities> | ||
</PropertyGroup> | ||
</Project> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
<Project> | ||
</Project> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
| ||
Microsoft Visual Studio Solution File, Format Version 12.00 | ||
# Visual Studio Version 17 | ||
VisualStudioVersion = 17.11.34807.36 | ||
MinimumVisualStudioVersion = 10.0.40219.1 | ||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotnetFuzzing", "DotnetFuzzing\DotnetFuzzing.csproj", "{002673BF-11AE-4072-9CBE-FC312BF68613}" | ||
EndProject | ||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{6DDAE3F1-325F-468C-92DB-5947A3AD757E}" | ||
ProjectSection(SolutionItems) = preProject | ||
.gitignore = .gitignore | ||
..\..\..\eng\pipelines\libraries\fuzzing\deploy-to-onefuzz.yml = ..\..\..\eng\pipelines\libraries\fuzzing\deploy-to-onefuzz.yml | ||
Directory.Build.props = Directory.Build.props | ||
Directory.Build.targets = Directory.Build.targets | ||
nuget.config = nuget.config | ||
README.md = README.md | ||
OneFuzz.md = OneFuzz.md | ||
EndProjectSection | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|Any CPU = Debug|Any CPU | ||
Release|Any CPU = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{002673BF-11AE-4072-9CBE-FC312BF68613}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{002673BF-11AE-4072-9CBE-FC312BF68613}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{002673BF-11AE-4072-9CBE-FC312BF68613}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{002673BF-11AE-4072-9CBE-FC312BF68613}.Release|Any CPU.Build.0 = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(SolutionProperties) = preSolution | ||
HideSolutionNode = FALSE | ||
EndGlobalSection | ||
GlobalSection(ExtensibilityGlobals) = postSolution | ||
SolutionGuid = {0BAD3B6E-67D4-418D-A45F-49B3F79168DF} | ||
EndGlobalSection | ||
EndGlobal |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using System.Text; | ||
|
||
namespace DotnetFuzzing; | ||
|
||
internal static class Assert | ||
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. We can't use xunit's asserts directly, and/or AssertExtensions? 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. I think we'd have to figure out #101993 (comment) first. |
||
{ | ||
// Feel free to add any other helpers as needed. | ||
|
||
public static void Equal<T>(T expected, T actual) | ||
{ | ||
if (!EqualityComparer<T>.Default.Equals(expected, actual)) | ||
{ | ||
Throw(expected, actual); | ||
} | ||
|
||
static void Throw(T expected, T actual) => | ||
throw new Exception($"Expected={expected} Actual={actual}"); | ||
} | ||
|
||
public static void SequenceEqual<T>(ReadOnlySpan<T> expected, ReadOnlySpan<T> actual) | ||
{ | ||
if (!expected.SequenceEqual(actual)) | ||
{ | ||
Throw(expected, actual); | ||
} | ||
|
||
static void Throw(ReadOnlySpan<T> expected, ReadOnlySpan<T> actual) | ||
{ | ||
Equal(expected.Length, actual.Length); | ||
|
||
int diffIndex = expected.CommonPrefixLength(actual); | ||
|
||
throw new Exception($"Expected={expected[diffIndex]} Actual={actual[diffIndex]} at index {diffIndex}"); | ||
} | ||
} | ||
|
||
public static void SequenceEqual(ReadOnlySpan<char> expected, StringBuilder actual) | ||
{ | ||
Equal(expected.Length, actual.Length); | ||
|
||
foreach (ReadOnlyMemory<char> chunk in actual.GetChunks()) | ||
{ | ||
SequenceEqual(expected.Slice(0, chunk.Length), chunk.Span); | ||
MihaZupan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
expected = expected.Slice(chunk.Length); | ||
} | ||
|
||
Equal(0, expected.Length); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
"0" | ||
"7" | ||
"," | ||
":" | ||
"2.1e24" | ||
|
||
"true" | ||
"false" | ||
"null" | ||
|
||
"\"\"" | ||
"\"\":" | ||
|
||
"{}" | ||
",{}" | ||
":{}" | ||
"{\"\":0}" | ||
"{{}}" | ||
|
||
"[]" | ||
",[]" | ||
":[]" | ||
"[0]" | ||
"[[]]" | ||
|
||
"''" | ||
"\\" | ||
"\\b" | ||
"\\f" | ||
"\\n" | ||
"\\r" | ||
"\\t" | ||
"\\u0000" | ||
"\\x00" | ||
"\\0" | ||
"\\uD800\\uDC00" | ||
"\\uDBFF\\uDFFF" | ||
|
||
"\"\":0" | ||
"//" | ||
"/**/" | ||
|
||
|
||
# Things like geojson, json-ld, ... | ||
"$ref" | ||
"type" | ||
"coordinates" | ||
"@context" | ||
"@id" | ||
"@type" | ||
|
||
# Strings with truncated special values | ||
"{\"foo\":fa" | ||
"{\"foo\":t" | ||
"{\"foo\":nul" | ||
|
||
"{" | ||
"}" | ||
"\"qty\": 1, \"qty\": -1" | ||
"\"qty\": 1, \"qty\\ud800\": -1" | ||
"\"qty\": 1, \"qt\\y\": -1" | ||
"/*" | ||
"*/" | ||
"\"" | ||
"1.7976931348623157e+308" | ||
"5e-324" | ||
"9007199254740991" | ||
"-9007199254740991" | ||
|
||
"}=" | ||
|
||
",," | ||
"{\"\":" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<OutputType>Exe</OutputType> | ||
<TargetFramework>$(NetCoreAppCurrent)-windows</TargetFramework> | ||
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 only works on Windows? 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. As-is, yes. We could make it work on Linux as well if needed, it's "just work". Namely updating the pipeline, and tweaking how we consume local bits to avoid the limitation in SharpFuzz to instrument mixed-mode assemblies only on Windows. |
||
<PublishSelfContained>true</PublishSelfContained> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
<EnablePreviewFeatures>True</EnablePreviewFeatures> | ||
<NoWarn>CA2252</NoWarn> | ||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="SharpFuzz" Version="2.1.1" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<FrameworkReference Update="Microsoft.NETCore.App" RuntimeFrameworkVersion="$(ProductVersion)-dev" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<Compile Include="$(TestUtilities)\System\Buffers\BoundedMemory.*" Link="TestUtilities\%(Filename)%(Extension)" /> | ||
<Compile Include="$(TestUtilities)\System\Buffers\PoisonPagePlacement.cs" Link="TestUtilities\PoisonPagePlacement.cs" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<None Update="Dictionaries\*"> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
</None> | ||
</ItemGroup> | ||
|
||
</Project> |
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.
So for right now, until the workaround is no longer needed, to add new tests one adds a new test file and then also updates this file?
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.
Yes.
When you add a new target and test it locally, the
prepare-onefuzz
part ofdotnet publish -o publish && publish/DotnetFuzzing.exe prepare-onefuzz deployment
will also update this file for you, so you should only have to: