Skip to content
This repository has been archived by the owner on Nov 1, 2023. It is now read-only.

Commit

Permalink
Add GoodBad C# example project, integration test (#2148)
Browse files Browse the repository at this point in the history
  • Loading branch information
ranweiler authored Jul 12, 2022
1 parent c1f9d73 commit 69b11f6
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 2 deletions.
42 changes: 40 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ jobs:
- uses: actions/cache@v3
id: cache-radamsa-build-linux
with:
# key on the shell script only: this script fixes the
# key on the shell script only: this script fixes the
# version to a particular commit, so if it changes we need to rebuild
key: radamsa-linux-${{ hashFiles('src/ci/radamsa-linux.sh') }}
path: artifacts
Expand All @@ -388,7 +388,7 @@ jobs:
- uses: actions/cache@v3
id: cache-radamsa-build-windows
with:
# key on the shell script only: this script fixes the
# key on the shell script only: this script fixes the
# version to a particular commit, so if it changes we need to rebuild
key: radamsa-windows-${{ hashFiles('src/ci/radamsa-windows.sh') }}
path: artifacts
Expand Down Expand Up @@ -524,6 +524,11 @@ jobs:
(cd libfuzzer-aarch64-crosscompile; make)
cp -r libfuzzer-aarch64-crosscompile/fuzz.exe libfuzzer-aarch64-crosscompile/inputs artifacts/linux-libfuzzer-aarch64-crosscompile
# C# target.
sudo apt-get install -y dotnet-sdk-6.0
(cd GoodBad; dotnet publish -c Release -o out)
mv GoodBad/out artifacts/GoodBadDotnet
- uses: actions/upload-artifact@v2.2.2
with:
name: integration-test-artifacts
Expand Down Expand Up @@ -603,3 +608,36 @@ jobs:
with:
name: integration-test-artifacts
path: src/integration-tests/artifacts
integration-tests-linux:
runs-on: ubuntu-18.04
needs:
- build-integration-tests-linux
- dotnet-fuzzing-tools-linux
steps:
- uses: actions/checkout@v2
- uses: actions/download-artifact@v2.0.8
with:
name: build-artifacts
path: build-artifacts
- uses: actions/download-artifact@v2.0.8
with:
name: integration-test-artifacts
path: integration-test-artifacts
- name: test
shell: bash
run: |
set -ex -o pipefail
# Must be absolute paths.
export GOODBAD_DOTNET="${GITHUB_WORKSPACE}/integration-test-artifacts/GoodBadDotnet"
export LIBFUZZER_DOTNET="${GITHUB_WORKSPACE}/build-artifacts/third-party/dotnet-fuzzing-linux/libfuzzer-dotnet/libfuzzer-dotnet"
chmod +x $LIBFUZZER_DOTNET
export LIBFUZZER_DOTNET_LOADER="${GITHUB_WORKSPACE}/build-artifacts/third-party/dotnet-fuzzing-linux/LibFuzzerDotnetLoader/LibFuzzerDotnetLoader"
chmod +x $LIBFUZZER_DOTNET_LOADER
export SHARPFUZZ="${GITHUB_WORKSPACE}/build-artifacts/third-party/dotnet-fuzzing-linux/sharpfuzz/SharpFuzz.CommandLine"
chmod +x $SHARPFUZZ
./src/ci/test-libfuzzer-dotnet.sh
45 changes: 45 additions & 0 deletions src/ci/test-libfuzzer-dotnet.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#!/usr/bin/env bash
set -ex -o pipefail

# Required environment variables:
# - GOODBAD_DOTNET
# - LIBFUZZER_DOTNET
# - LIBFUZZER_DOTNET_LOADER
# - SHARPFUZZ

export GOODBAD_DLL='GoodBad/GoodBad.dll'

TMP=$(mktemp -d)
cd $TMP

cp -r ${GOODBAD_DOTNET} GoodBad

# Instrument DLL under test.
${SHARPFUZZ} GoodBad/GoodBad.dll

# Create seed and crash inputs.
printf 'good' > good.txt
printf 'bad!' > bad.txt

# Test individual env vars.
export LIBFUZZER_DOTNET_TARGET_ASSEMBLY="${GOODBAD_DLL}"
export LIBFUZZER_DOTNET_TARGET_CLASS='GoodBad.Fuzzer'
export LIBFUZZER_DOTNET_TARGET_METHOD='TestInput'

${LIBFUZZER_DOTNET} --target_path=${LIBFUZZER_DOTNET_LOADER} good.txt

# Expect nonzero exit.
! ${LIBFUZZER_DOTNET} --target_path=${LIBFUZZER_DOTNET_LOADER} bad.txt

# Test delimited env var.
export LIBFUZZER_DOTNET_TARGET="${LIBFUZZER_DOTNET_TARGET_ASSEMBLY}:${LIBFUZZER_DOTNET_TARGET_CLASS}:${LIBFUZZER_DOTNET_TARGET_METHOD}"
unset LIBFUZZER_DOTNET_TARGET_ASSEMBLY
unset LIBFUZZER_DOTNET_TARGET_CLASS
unset LIBFUZZER_DOTNET_TARGET_METHOD

${LIBFUZZER_DOTNET} --target_path=${LIBFUZZER_DOTNET_LOADER} good.txt

# Expect nonzero exit.
! ${LIBFUZZER_DOTNET} --target_path=${LIBFUZZER_DOTNET_LOADER} bad.txt

rm -rf $TMP
46 changes: 46 additions & 0 deletions src/integration-tests/GoodBad/GoodBad.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

namespace GoodBad;

public class BinaryParser
{
int count = 0;

public void ProcessInput(ReadOnlySpan<byte> data) {
if (data.Length < 4) {
return;
}

if (data[0] == 'b') { count++; }
if (data[1] == 'a') { count++; }
if (data[2] == 'd') { count++; }
if (data[3] == '!') { count++; }

// Simulate an out-of-bounds access while parsing.
if (count >= 4) {
var _ = data[0xdead];
}
}
}

public class Fuzzer {
/// Preferred test method.
public static void TestInput(ReadOnlySpan<byte> data) {
var parser = new BinaryParser();
parser.ProcessInput(data);
}

/// Backwards-compatible test method for legacy code that can't use `Span` types.
///
/// Incurs an extra copy of `data` per fuzzing iteration.
public static void TestInputCompat(byte[] data) {
var parser = new BinaryParser();
parser.ProcessInput(data);
}

/// Invalid static method that has a fuzzing-incompatible signature.
public static void BadSignature(ReadOnlySpan<int> data) {
return;
}
}
10 changes: 10 additions & 0 deletions src/integration-tests/GoodBad/GoodBad.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<LangVersion>10.0</LangVersion>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

</Project>

0 comments on commit 69b11f6

Please sign in to comment.