Skip to content

Commit

Permalink
Add bpf2c fuzzer and execution context fuzzer to CI/CD (#1164)
Browse files Browse the repository at this point in the history
* Enable bpf2c fuzzer and execution context fuzzer in CI/CD

Signed-off-by: Dave Thaler <dthaler@microsoft.com>

* Create bpf2c fuzzer corpus

Signed-off-by: Dave Thaler <dthaler@microsoft.com>

* Make absolute path and strip trailing slash from it. (#1175)

Signed-off-by: Alan Jowett <alan.jowett@microsoft.com>

Co-authored-by: Alan Jowett <alan.jowett@microsoft.com>

* Add libsancov.lib when building fuzzer (#1179)

* Add libsancov.lib when building fuzzer

Signed-off-by: Alan Jowett <alan.jowett@microsoft.com>

* upload artifacts as dumps

Signed-off-by: Alan Jowett <alan.jowett@microsoft.com>

Co-authored-by: Alan Jowett <alan.jowett@microsoft.com>

* Bpf2c fuzzer fix build (#1180)

* Disable caching of verifier cmake project for now

Signed-off-by: Alan Jowett <alan.jowett@microsoft.com>

* Fix dump upload path

Signed-off-by: Alan Jowett <alan.jowett@microsoft.com>

* Fix dump upload path

Signed-off-by: Alan Jowett <alan.jowett@microsoft.com>

* Fix crash dump upload

Signed-off-by: Alan Jowett <alan.jowett@microsoft.com>

* Add Execution Context corpus

Signed-off-by: Alan Jowett <alan.jowett@microsoft.com>

* Limit fuzzing to 15 minutes

Signed-off-by: Alan Jowett <alan.jowett@microsoft.com>

* Fix artifact path

Signed-off-by: Alan Jowett <alan.jowett@microsoft.com>

* Fix yaml to corectly upload artifacts

Signed-off-by: Alan Jowett <alan.jowett@microsoft.com>

* Fix yaml to corectly upload artifacts

Signed-off-by: Alan Jowett <alan.jowett@microsoft.com>

* Fix yaml to corectly upload artifacts

Signed-off-by: Alan Jowett <alan.jowett@microsoft.com>

Co-authored-by: Alan Jowett <alan.jowett@microsoft.com>

* Bpf2c fuzzer fix build (#1182)

* Disable caching of verifier cmake project for now

Signed-off-by: Alan Jowett <alan.jowett@microsoft.com>

* Limit fuzzing memory

Signed-off-by: Alan Jowett <alan.jowett@microsoft.com>

* Validate symbols offset

Signed-off-by: Alan Jowett <alan.jowett@microsoft.com>

Co-authored-by: Alan Jowett <alan.jowett@microsoft.com>

* Reject maps that have no associated symbols

Signed-off-by: Alan Jowett <alan.jowett@microsoft.com>

Co-authored-by: Alan Jowett <alanjo@microsoft.com>
Co-authored-by: Alan Jowett <alan.jowett@microsoft.com>
  • Loading branch information
3 people committed Jun 9, 2022
1 parent 4e3aace commit e11f1d3
Show file tree
Hide file tree
Showing 15 changed files with 123 additions and 5 deletions.
27 changes: 27 additions & 0 deletions .github/workflows/cicd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,33 @@ jobs:
code_coverage: false
gather_dumps: true

bpf2c_fuzzer:
needs: libfuzzer
# Always run this job.
if: github.event_name == 'schedule' || github.event_name == 'pull_request'
uses: ./.github/workflows/reusable-test.yml
with:
name: bpf2c_fuzzer
test_command: bpf2c_fuzzer.exe bpf2c_fuzzer_corpus -use_value_profile=1 -max_total_time=900 -artifact_prefix=Artifacts\
build_artifact: Build-x64-fuzzer
environment: windows-2019
code_coverage: false
gather_dumps: true

execution_context_fuzzer:
needs: libfuzzer
# Always run this job.
if: github.event_name == 'schedule' || github.event_name == 'pull_request'
uses: ./.github/workflows/reusable-test.yml
with:
name: execution_context_fuzzer
pre_test: powershell Expand-Archive -Path .\corpus.zip -DestinationPath execution_context_fuzzer_corpus -Force
test_command: execution_context_fuzzer.exe execution_context_fuzzer_corpus -use_value_profile=1 -runs=3000 -artifact_prefix=Artifacts\
build_artifact: Build-x64-fuzzer
environment: windows-2019
code_coverage: false
gather_dumps: true

# Run Cilium regression tests in GitHub.
cilium_tests:
needs: regular
Expand Down
20 changes: 20 additions & 0 deletions .github/workflows/reusable-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@ jobs:
name: ${{inputs.build_artifact}} ${{matrix.configurations}}
path: ${{github.workspace}}/${{env.BUILD_PLATFORM}}/${{env.BUILD_CONFIGURATION}}

- name: Create generated artifact folder
run: |
mkdir ${{github.workspace}}\${{env.BUILD_PLATFORM}}\${{env.BUILD_CONFIGURATION}}\Artifacts
- name: Start ETW tracing
id: start_etw_tracing
if: inputs.capture_etw == true
Expand Down Expand Up @@ -242,6 +246,22 @@ jobs:
path: ./${{env.BUILD_PLATFORM}}/${{env.BUILD_CONFIGURATION}}/TestLogs
retention-days: 5

- name: Check for generated artifacts
if: always()
uses: andstor/file-existence-action@f02338908d150e00a4b8bebc2dad18bd9e5229b0
id: check_artifacts
with:
files: ${{github.workspace}}\${{env.BUILD_PLATFORM}}\${{env.BUILD_CONFIGURATION}}\Artifacts\*

- name: Upload generated artifacts
if: always() && steps.check_artifacts.outputs.files_exists == 'true'
id: upload_artifacts
uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8
with:
name: Artifacts-${{env.NAME}}-${{env.BUILD_PLATFORM}}-${{env.BUILD_CONFIGURATION}}
path: ${{github.workspace}}\${{env.BUILD_PLATFORM}}\${{env.BUILD_CONFIGURATION}}\Artifacts
retention-days: 5

- name: Mark run as failed if crash dumps are found
if: steps.check_dumps.outputs.files_exists == 'true'
run: exit 1
8 changes: 7 additions & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,15 @@
<PropertyGroup Condition="'$(AddressSanitizer)'=='True'">
<EnableASAN>true</EnableASAN>
</PropertyGroup>
<PropertyGroup Condition="'$(Fuzzer)'=='True'">
<PropertyGroup Condition="'$(Configuration)|$(Fuzzer)'=='Release|True'">
<EnableASAN>true</EnableASAN>
<AdditionalOptions>/fsanitize-coverage=inline-bool-flag /fsanitize-coverage=edge /fsanitize-coverage=trace-cmp /fsanitize-coverage=trace-div %(AdditionalOptions)</AdditionalOptions>
<SanitizerLibs>libsancov.lib;clang_rt.fuzzer_MD-x86_64.lib</SanitizerLibs>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Fuzzer)'=='Debug|True'">
<EnableASAN>true</EnableASAN>
<AdditionalOptions>/fsanitize-coverage=inline-bool-flag /fsanitize-coverage=edge /fsanitize-coverage=trace-cmp /fsanitize-coverage=trace-div %(AdditionalOptions)</AdditionalOptions>
<SanitizerLibs>libsancov.lib;clang_rt.fuzzer_MDd-x86_64.lib</SanitizerLibs>
</PropertyGroup>
<PropertyGroup Condition="'$(Fuzzer)'!='True'">
<SpectreMitigation>Spectre</SpectreMitigation>
Expand Down
3 changes: 3 additions & 0 deletions ebpf-for-windows.sln
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,9 @@ EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "execution_context_fuzzer", "tests\libfuzzer\execution_context\execution_context_fuzzer.vcxproj", "{6116AE11-5296-4DE9-8A8E-5380B789907E}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bpf2c_fuzzer", "tests\libfuzzer\bpf2c\bpf2c_fuzzer.vcxproj", "{A0A0D663-DCF7-4BB1-9DDB-7964C3C31603}"
ProjectSection(ProjectDependencies) = postProject
{B4AD72E3-754E-40CA-9CEA-D3F2C9170E51} = {B4AD72E3-754E-40CA-9CEA-D3F2C9170E51}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "verifier_fuzzer", "tests\libfuzzer\verifier\verifier_fuzzer.vcxproj", "{DCF12929-B975-4874-A80F-9EAF1CC5A5A0}"
EndProject
Expand Down
5 changes: 2 additions & 3 deletions ebpfapi/ebpfapi.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,7 @@
<EnableUAC>false</EnableUAC>
<ModuleDefinitionFile>Source.def</ModuleDefinitionFile>
<AdditionalLibraryDirectories>$(OutDir)</AdditionalLibraryDirectories>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>mincore.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>$(SanitizerLibs);mincore.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<ResourceCompile>
<AdditionalIncludeDirectories>$(SolutionDir)include</AdditionalIncludeDirectories>
Expand All @@ -101,7 +100,7 @@
<GenerateDebugInformation>DebugFull</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
<ModuleDefinitionFile>Source.def</ModuleDefinitionFile>
<AdditionalDependencies>mincore.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>$(SanitizerLibs);mincore.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(OutDir)</AdditionalLibraryDirectories>
</Link>
<ResourceCompile>
Expand Down
11 changes: 11 additions & 0 deletions libs/platform/user/ebpf_platform_user.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ bool _ebpf_platform_code_integrity_enabled = false;
bool _ebpf_platform_is_preemptible = true;

extern "C" bool ebpf_fuzzing_enabled = false;
extern "C" size_t ebfp_fuzzing_memory_limit = MAXSIZE_T;

// Thread pool related globals.
static TP_CALLBACK_ENVIRON _callback_environment;
Expand Down Expand Up @@ -243,6 +244,9 @@ __drv_allocatesMem(Mem) _Must_inspect_result_ _Ret_maybenull_
_Post_writable_byte_size_(size) void* ebpf_allocate(size_t size)
{
ebpf_assert(size);
if (size > ebfp_fuzzing_memory_limit) {
return nullptr;
}
void* memory;
memory = calloc(size, 1);
if (memory != nullptr)
Expand All @@ -255,6 +259,9 @@ __drv_allocatesMem(Mem) _Must_inspect_result_ _Ret_maybenull_
_Post_writable_byte_size_(new_size) void* ebpf_reallocate(_In_ void* memory, size_t old_size, size_t new_size)
{
UNREFERENCED_PARAMETER(old_size);
if (new_size > ebfp_fuzzing_memory_limit) {
return nullptr;
}
void* p = realloc(memory, new_size);
if (p && (new_size > old_size))
memset(((char*)p) + old_size, 0, new_size - old_size);
Expand All @@ -270,6 +277,10 @@ ebpf_free(_Frees_ptr_opt_ void* memory)
__drv_allocatesMem(Mem) _Must_inspect_result_ _Ret_maybenull_
_Post_writable_byte_size_(size) void* ebpf_allocate_cache_aligned(size_t size)
{
if (size > ebfp_fuzzing_memory_limit) {
return nullptr;
}

void* memory = _aligned_malloc(size, EBPF_CACHE_LINE_SIZE);
if (memory) {
memset(memory, 0, size);
Expand Down
10 changes: 10 additions & 0 deletions scripts/create_bpf2c_corpus.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
@echo off
rem Copyright (c) Microsoft Corporation
rem SPDX-License-Identifier: MIT
rem
rem Usage: create_bpf2c_corpus.bat <output_directory>
echo set OUTPUTPATH=%1
set OUTPUTPATH=%1
rem Strip the \ from the end of the path if present.
if %OUTPUTPATH:~-1% EQU \ set OUTPUTPATH=%OUTPUTPATH:~0,-1%
xcopy /d /i /y "%OUTPUTPATH%\*.o" "%OUTPUTPATH%\bpf2c_fuzzer_corpus"
9 changes: 9 additions & 0 deletions tests/libfuzzer/bpf2c/bpf2c_fuzzer.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,15 @@
<Project>{7d5b4e68-c0fa-3f86-9405-f6400219b440}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="$(SolutionDir)scripts\create_bpf2c_corpus.bat">
<FileType>Document</FileType>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(OutDir)bpf2c_fuzzer_corpus\bpf.o</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(OutDir)bpf2c_fuzzer_corpus\bpf.o</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)scripts\create_bpf2c_corpus.bat $(OutDir)</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)scripts\create_bpf2c_corpus.bat $(OutDir)</Command>
</CustomBuild>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
Expand Down
5 changes: 5 additions & 0 deletions tests/libfuzzer/bpf2c/bpf2c_fuzzer.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,9 @@
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="..\..\..\scripts\create_bpf2c_corpus.bat">
<Filter>Source Files</Filter>
</CustomBuild>
</ItemGroup>
</Project>
Binary file added tests/libfuzzer/execution_context/corpus.zip
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,11 @@
<ClInclude Include="..\..\libs\thunk\mock\mock.h" />
<ClInclude Include="..\end_to_end\test_helper.hpp" />
</ItemGroup>
<ItemGroup>
<CopyFileToFolders Include="corpus.zip">
<FileType>Document</FileType>
</CopyFileToFolders>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,7 @@
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<CopyFileToFolders Include="corpus.zip" />
</ItemGroup>
</Project>
8 changes: 7 additions & 1 deletion tests/libfuzzer/execution_context/libfuzz_harness.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
#include "libfuzzer.h"
#include "platform.h"

extern "C" size_t ebfp_fuzzing_memory_limit;

static std::vector<std::unique_ptr<_program_info_provider>> _program_information_providers;
static std::vector<GUID> _program_types = {
EBPF_PROGRAM_TYPE_XDP,
Expand Down Expand Up @@ -236,7 +238,11 @@ fuzz_ioctl(std::vector<uint8_t>& random_buffer)
}
}

FUZZ_EXPORT int __cdecl LLVMFuzzerInitialize(int*, char***) { return 0; }
FUZZ_EXPORT int __cdecl LLVMFuzzerInitialize(int*, char***)
{
ebfp_fuzzing_memory_limit = 1024 * 1024 * 10;
return 0;
}

FUZZ_EXPORT int __cdecl LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
Expand Down
2 changes: 2 additions & 0 deletions tools/bpf2c/bpf2c.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>$(SanitizerLibs);%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PreBuildEvent>
<Command>powershell -NonInteractive -ExecutionPolicy Unrestricted $(SolutionDir)scripts\Process-File.ps1 -InputFile Convert-BpfToNative.ps1.template -OutputFile $(OutDir)Convert-BpfToNative.ps1 -ConfigFile replacements.json</Command>
Expand All @@ -137,6 +138,7 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>$(SanitizerLibs);%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PreBuildEvent>
<Command>powershell -NonInteractive -ExecutionPolicy Unrestricted $(SolutionDir)scripts\Process-File.ps1 -InputFile Convert-BpfToNative.ps1.template -OutputFile $(OutDir)Convert-BpfToNative.ps1 -ConfigFile replacements.json</Command>
Expand Down
12 changes: 12 additions & 0 deletions tools/bpf2c/bpf_code_generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ bpf_code_generator::parse()

if (map_section) {
size_t data_size = map_section->get_size();
size_t map_count = data_size / sizeof(ebpf_map_definition_in_file_t);

if (data_size % sizeof(ebpf_map_definition_in_file_t) != 0) {
throw std::runtime_error(
Expand Down Expand Up @@ -276,12 +277,23 @@ bpf_code_generator::parse()
if (symbol_size != sizeof(ebpf_map_definition_in_file_t)) {
throw std::runtime_error("invalid map size");
}
if (symbol_value > map_section->get_size()) {
throw std::runtime_error("invalid symbol value");
}
if ((symbol_value + symbol_size) > map_section->get_size()) {
throw std::runtime_error("invalid symbol value");
}

map_definitions[symbol_name].definition =
*reinterpret_cast<const ebpf_map_definition_in_file_t*>(map_section->get_data() + symbol_value);

map_definitions[symbol_name].index = symbol_value / sizeof(ebpf_map_definition_in_file_t);
}
}

if (map_definitions.size() != map_count) {
throw std::runtime_error(std::string("bad maps section, map must have associated symbol"));
}
}
}

Expand Down

0 comments on commit e11f1d3

Please sign in to comment.