-
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
Conversation
Tagging subscribers to this area: @dotnet/area-meta |
src/libraries/Fuzzing/DotnetFuzzing/Fuzzers/JsonSerializerFuzzer.cs
Outdated
Show resolved
Hide resolved
src/libraries/Fuzzing/DotnetFuzzing/Fuzzers/SearchValuesByteCharFuzzer.cs
Show resolved
Hide resolved
src/libraries/Fuzzing/DotnetFuzzing/Fuzzers/HttpHeadersFuzzer.cs
Outdated
Show resolved
Hide resolved
10d46a6
to
bbe7db9
Compare
src/libraries/Fuzzing/DotnetFuzzing/Fuzzers/JsonSerializerFuzzer.cs
Outdated
Show resolved
Hide resolved
env: | ||
onefuzzDropDirectory: $(fuzzerProject)/deployment/UTF8Fuzzer | ||
SYSTEM_ACCESSTOKEN: $(System.AccessToken) | ||
displayName: Send UTF8Fuzzer to OneFuzz |
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 of
dotnet publish -o publish && publish/DotnetFuzzing.exe prepare-onefuzz deployment
will also update this file for you, so you should only have to:
- Add 1 file
- Test changes
- Commit the 2 changed files
<NetCoreAppCurrentVersion>9.0</NetCoreAppCurrentVersion> | ||
<NetCoreAppCurrent>net$(NetCoreAppCurrentVersion)</NetCoreAppCurrent> |
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.
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 comment
The 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.
We have similar isolated configurations for HttpStress / SslStress.
|
||
namespace DotnetFuzzing; | ||
|
||
internal static class Assert |
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.
We can't use xunit's asserts directly, and/or AssertExtensions?
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.
I think we'd have to figure out #101993 (comment) first.
Given it's just helpers for Equal(T, T)
and Equal(Span<T>, Span<T>)
at this point, I didn't think it mattered enough.
|
||
<PropertyGroup> | ||
<OutputType>Exe</OutputType> | ||
<TargetFramework>$(NetCoreAppCurrent)-windows</TargetFramework> |
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.
This only works on Windows?
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.
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.
src/libraries/Fuzzing/DotnetFuzzing/Fuzzers/SearchValuesStringFuzzer.cs
Outdated
Show resolved
Hide resolved
// Adapted from https://github.com/GrabYourPitchforks/utf8fuzz | ||
internal sealed class UTF8Fuzzer : IFuzzer | ||
{ | ||
public string BlameAlias => "mizupan"; |
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.
Feels unsustainable to be assigning these to a specific alias. Can we create some kind of team alias that these are assigned to instead?
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.
Sadly can't assign work items to groups / multiple people in AzDo.
I've changed it to always assign me for now, and I'll re-assign as needed (we shouldn't be getting these reports all that often anyway).
string[] TargetCoreLibPrefixes { get; } | ||
|
||
/// <summary>Optional name of the dictionary to use to better guide the fuzzer.</summary> | ||
string? Dictionary => null; |
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.
Is this overridden anywhere?
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.
The JsonDocumentFuzzer
sets json.dict
|
||
await DownloadArtifactAsync( | ||
Path.Combine(publishDirectory, "libfuzzer-dotnet.exe"), | ||
"https://github.com/Metalnem/libfuzzer-dotnet/releases/download/v2023.06.26.1359/libfuzzer-dotnet-windows.exe", |
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.
We're ok downloading such executables from an arbitrary repo?
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.
I don't know of a great alternative.
I figured that since the version is pinned (checksum), it's pretty much the same thing as us using the SharpFuzz 2.1.1
NuGet package from the internal mirror / asking anyone working on fuzzers to install dotnet tool install --global SharpFuzz.CommandLine
.
abf031a
to
70857b2
Compare
src/libraries/Fuzzing/DotnetFuzzing/Fuzzers/HttpHeadersFuzzer.cs
Outdated
Show resolved
Hide resolved
internal sealed class PooledBoundedMemory<T> : IDisposable where T : unmanaged | ||
{ | ||
// Default libFuzzer max_len for inputs is 4096. | ||
private const int MaxLength = 4096 * 2; |
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.
Isn't pooling in this fashion potentially going to allocate dozens of GB of memory? Especially in the SearchValues and UTF-8 tests, the elementCount parameter could potentially be any arbitrary integer 0 .. 4096, depending on where the fuzzer places certain delimiter characters we're searching for.
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.
Should be around 400 MB I believe (8k sizes, 2 variants of poison placement each, 2-3 memory pages each, one for chars + one for bytes).
Note that we're only pooling 1 buffer for each (type, size, placement)
as that's enough for practically all uses by fuzzers.
@MihuBot fuzz HttpHeaders |
|
* Initial fuzzing setup * Initial pipeline * Install sharpfuzz to the working directory * Initial instructions * Add a few helpful links * Enable OneFuzz deployment task * Remove BlameAlias default * Speed up headers fuzzer * Add BoundedMemory reference * Use BoundedMemory in SearchValues targets * Swap property order * Add a UTF8 fuzzing target * Reuse instrumented assemblies when unchanged * Add support for using dictionaries * Add simple json fuzzing target * Mention SharpFuzz in THIRD-PARTY-NOTICES.TXT * Tweak readme * Don't reuse assembly if prefixes changed * Temporarily disable dictionary files * Avoid name conflicts between CI jobs and test submissions * Add some basic OneFuzz docs * Add PooledBoundedMemory to fuzzer sample * Typo * More docs * Avoid transcoding overhead in Json fuzzer * Enable cron schedule * Tweak docs * Fix OneFuzz dictionary file paths * Workaround OneFuzz issue with multiple jobs in deployment * Clarify what alias to use * Test JsonDocument instead of JsonSerializer * Get rid of BlameAlias * Tweak getters * Remove a few unused helpers * Tweak OneFuzz workaround comment * Remove StringBuilder use * Avoid misaligned-span UB
* Initial fuzzing setup * Initial pipeline * Install sharpfuzz to the working directory * Initial instructions * Add a few helpful links * Enable OneFuzz deployment task * Remove BlameAlias default * Speed up headers fuzzer * Add BoundedMemory reference * Use BoundedMemory in SearchValues targets * Swap property order * Add a UTF8 fuzzing target * Reuse instrumented assemblies when unchanged * Add support for using dictionaries * Add simple json fuzzing target * Mention SharpFuzz in THIRD-PARTY-NOTICES.TXT * Tweak readme * Don't reuse assembly if prefixes changed * Temporarily disable dictionary files * Avoid name conflicts between CI jobs and test submissions * Add some basic OneFuzz docs * Add PooledBoundedMemory to fuzzer sample * Typo * More docs * Avoid transcoding overhead in Json fuzzer * Enable cron schedule * Tweak docs * Fix OneFuzz dictionary file paths * Workaround OneFuzz issue with multiple jobs in deployment * Clarify what alias to use * Test JsonDocument instead of JsonSerializer * Get rid of BlameAlias * Tweak getters * Remove a few unused helpers * Tweak OneFuzz workaround comment * Remove StringBuilder use * Avoid misaligned-span UB
This PR introduces a new
DotnetFuzzing
project undersrc/libraries/Fuzzing
which contains fuzzing targets and relevant automation for fuzzing locally, and to automatically submit jobs to OneFuzz.The goal is that it should be easy to author new fuzzing targets without having to deal with the infrastructure aspects.
I included the following targets for now:
HttpHeadersFuzzer
JsonDocumentFuzzer
SearchValuesByteCharFuzzer
SearchValuesStringFuzzer
UTF8Fuzzer
The new
deploy-to-onefuzz.yml
internal pipeline will periodically build the runtime and resubmit fuzzing jobs to OneFuzz.See the new
README.md
for details about what it looks like to run locally / add new targets.