From fb7d8860bec8f8e229ae5705e919061e7f8e202d Mon Sep 17 00:00:00 2001 From: Dave Thaler Date: Fri, 20 Jan 2023 10:08:52 -0800 Subject: [PATCH] Remove the obsolete fuzz.exe (#1920) * Remove the obsolete fuzz.exe The functionality was replaced by execution_context_fuzzer.exe. Signed-off-by: Dave Thaler * Fix cmake build Signed-off-by: Dave Thaler * Update fuzzing docs Signed-off-by: Dave Thaler Signed-off-by: Dave Thaler --- .github/workflows/cicd.yml | 14 --- docs/Fuzzing.md | 30 +---- ebpf-for-windows.sln | 18 --- tests/CMakeLists.txt | 1 - tests/fuzz/CMakeLists.txt | 66 ----------- tests/fuzz/execution_context.cpp | 184 ------------------------------- tests/fuzz/fuzz.vcxproj | 144 ------------------------ tests/fuzz/fuzz.vcxproj.filters | 40 ------- 8 files changed, 4 insertions(+), 493 deletions(-) delete mode 100644 tests/fuzz/CMakeLists.txt delete mode 100644 tests/fuzz/execution_context.cpp delete mode 100644 tests/fuzz/fuzz.vcxproj delete mode 100644 tests/fuzz/fuzz.vcxproj.filters diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index 82f2c5daa2..ddb7df09f2 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -187,20 +187,6 @@ jobs: build_artifact: Build-x64-Sanitize build_options: /p:AddressSanitizer='True' - # Run the fuzzing tests in GitHub. - fuzzing: - needs: sanitize - # Always run this job. - if: github.event_name == 'schedule' || github.event_name == 'pull_request' - uses: ./.github/workflows/reusable-test.yml - with: - name: fuzzing - test_command: .\fuzz.exe -d yes - build_artifact: Build-x64-Sanitize - environment: windows-2022 - code_coverage: false - gather_dumps: true - bpf2c_fuzzer: needs: libfuzzer if: github.event_name == 'pull_request' diff --git a/docs/Fuzzing.md b/docs/Fuzzing.md index 7944e22d32..df4fd220f8 100644 --- a/docs/Fuzzing.md +++ b/docs/Fuzzing.md @@ -5,31 +5,9 @@ Fuzz testing is a test methodology that finds a class of bugs in the code-base by generating random inputs and verifying that the code doesn't crash. ## Tests -The fuzzing tests are in the repo under tests/fuzz. Fuzz tests execute as part -of each CI/CD workflow. The tests generate a random block of bytes with a -length in the range from minimum input size for that method to minimum input -size + 1024. Many eBPF-For-Windows protocol messages contain a handle as their -first element, so the tests create several valid handles and insert them at -the beginning of the message. - -## Reproducing a failure from CI/CD -At the start of each fuzzing run, the tests generate a random number seed and -prints it out to the console. The random seed appears similar to the following: -``` -[Begin random seed] -6bcd4d9f e4be3204 66f59b19 fc13dfd0 49aee1d3 a9fec550 1a6aea17 b0bf0eb6 -398939cd 565ea6ec 15e3c09d 1844f118 fcdf6860 1e892676 f8fa75af 84e23b43 -.. -02fc4779 15c10832 2c6a717c 79404590 7634d1fe f0ddd687 81d67357 091d3f2b -c447caca c0626a08 4c6c8656 0c88d48c e20e975b 5e7ff362 bd982986 6e50d38f -[End random seed] -``` - -To reproduce a failure observed in fuzzing, copy this random seed into a text -file (```random_seed.txt``` as an example) and then set the environment variable -```RANDOM_SEED``` to the path of the file containing the random seed. The tests -will then use the provided seed instead of generating a new one, which results -in the tests repeating the sequence of steps that resulted in the crash. +The fuzzing tests are in the repo under tests/libfuzzer. Fuzz tests execute as part +of each CI/CD workflow. The tests generate a random block of bytes that a fuzzer +uses as a test vector to determine what API to fuzz and what arguments to pass to it. ## Reproducing a failure from artifacts When a crash happens, a folder containing the unique crash will be created. Click on *Summary* in the build section. The following example shows the process of debugging for *verifier_fuzzer* which can then be used for other CI/CD steps as well. @@ -47,4 +25,4 @@ An alternative of running an admin CMD is to reproduce a crash to use the local ``` verifier_fuzzer.exe ``` -This method will show the line of crash in the source file. \ No newline at end of file +This method will show the line of crash in the source file. diff --git a/ebpf-for-windows.sln b/ebpf-for-windows.sln index 970af389b7..6d5b80273a 100644 --- a/ebpf-for-windows.sln +++ b/ebpf-for-windows.sln @@ -139,8 +139,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Catch2WithMain", "external\ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Catch2", "external\Catch2\build\src\Catch2.vcxproj", "{8D538CBE-01BF-4A2E-A98A-6C368FDF13D7}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fuzz", "tests\fuzz\fuzz.vcxproj", "{D88F9CE2-8DA2-44FB-AF7C-06466A180F31}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "socket_tests", "tests\socket\socket_tests.vcxproj", "{EED9DAC6-8B98-4C33-969A-E8CEDE8E985E}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bpftool_tests", "tests\bpftool_tests\bpftool_tests.vcxproj", "{8B5B061B-3170-4D1B-8C5B-E86B890C14B8}" @@ -774,21 +772,6 @@ Global {8D538CBE-01BF-4A2E-A98A-6C368FDF13D7}.RelWithDebInfo|ARM64.ActiveCfg = RelWithDebInfo|x64 {8D538CBE-01BF-4A2E-A98A-6C368FDF13D7}.RelWithDebInfo|x64.ActiveCfg = RelWithDebInfo|x64 {8D538CBE-01BF-4A2E-A98A-6C368FDF13D7}.RelWithDebInfo|x64.Build.0 = RelWithDebInfo|x64 - {D88F9CE2-8DA2-44FB-AF7C-06466A180F31}.Debug|ARM64.ActiveCfg = Debug|Win32 - {D88F9CE2-8DA2-44FB-AF7C-06466A180F31}.Debug|x64.ActiveCfg = Debug|x64 - {D88F9CE2-8DA2-44FB-AF7C-06466A180F31}.Debug|x64.Build.0 = Debug|x64 - {D88F9CE2-8DA2-44FB-AF7C-06466A180F31}.MinSizeRel|ARM64.ActiveCfg = Debug|Win32 - {D88F9CE2-8DA2-44FB-AF7C-06466A180F31}.MinSizeRel|ARM64.Build.0 = Debug|Win32 - {D88F9CE2-8DA2-44FB-AF7C-06466A180F31}.MinSizeRel|x64.ActiveCfg = Debug|x64 - {D88F9CE2-8DA2-44FB-AF7C-06466A180F31}.MinSizeRel|x64.Build.0 = Debug|x64 - {D88F9CE2-8DA2-44FB-AF7C-06466A180F31}.Release|ARM64.ActiveCfg = Release|x64 - {D88F9CE2-8DA2-44FB-AF7C-06466A180F31}.Release|ARM64.Build.0 = Release|x64 - {D88F9CE2-8DA2-44FB-AF7C-06466A180F31}.Release|x64.ActiveCfg = Release|x64 - {D88F9CE2-8DA2-44FB-AF7C-06466A180F31}.Release|x64.Build.0 = Release|x64 - {D88F9CE2-8DA2-44FB-AF7C-06466A180F31}.RelWithDebInfo|ARM64.ActiveCfg = Debug|Win32 - {D88F9CE2-8DA2-44FB-AF7C-06466A180F31}.RelWithDebInfo|ARM64.Build.0 = Debug|Win32 - {D88F9CE2-8DA2-44FB-AF7C-06466A180F31}.RelWithDebInfo|x64.ActiveCfg = Release|x64 - {D88F9CE2-8DA2-44FB-AF7C-06466A180F31}.RelWithDebInfo|x64.Build.0 = Release|x64 {EED9DAC6-8B98-4C33-969A-E8CEDE8E985E}.Debug|ARM64.ActiveCfg = Debug|Win32 {EED9DAC6-8B98-4C33-969A-E8CEDE8E985E}.Debug|x64.ActiveCfg = Debug|x64 {EED9DAC6-8B98-4C33-969A-E8CEDE8E985E}.Debug|x64.Build.0 = Debug|x64 @@ -1066,7 +1049,6 @@ Global {61DF9973-81B9-4006-9148-52F58259BBCF} = {492C9B22-9237-4996-9E33-CA14D3533616} {8BD3552A-2CFB-4A59-AB15-2031B97ADA1E} = {492C9B22-9237-4996-9E33-CA14D3533616} {8D538CBE-01BF-4A2E-A98A-6C368FDF13D7} = {492C9B22-9237-4996-9E33-CA14D3533616} - {D88F9CE2-8DA2-44FB-AF7C-06466A180F31} = {492C9B22-9237-4996-9E33-CA14D3533616} {EED9DAC6-8B98-4C33-969A-E8CEDE8E985E} = {492C9B22-9237-4996-9E33-CA14D3533616} {8B5B061B-3170-4D1B-8C5B-E86B890C14B8} = {492C9B22-9237-4996-9E33-CA14D3533616} {8DD6577A-CBBE-43FE-9FC3-E42CB013CC60} = {492C9B22-9237-4996-9E33-CA14D3533616} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index c131cd5efe..75f1f00997 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -6,7 +6,6 @@ add_subdirectory("bpf2c_plugin") add_subdirectory("bpf2c_tests") add_subdirectory("bpftool_tests") add_subdirectory("cilium") -add_subdirectory("fuzz") add_subdirectory("libs") add_subdirectory("performance") add_subdirectory("sample") diff --git a/tests/fuzz/CMakeLists.txt b/tests/fuzz/CMakeLists.txt deleted file mode 100644 index 895749d16d..0000000000 --- a/tests/fuzz/CMakeLists.txt +++ /dev/null @@ -1,66 +0,0 @@ -# Copyright (c) Microsoft Corporation -# SPDX-License-Identifier: MIT - -add_executable("fuzz" - ../../libs/thunk/mock/mock.cpp - ../../libs/thunk/mock/mock.h - - ../end_to_end/test_helper.cpp - ../end_to_end/test_helper.hpp - - execution_context.cpp -) - -target_include_directories("fuzz" PRIVATE - "${CMAKE_BINARY_DIR}" - "${CMAKE_SOURCE_DIR}/external/catch2/src" - "${CMAKE_SOURCE_DIR}/external/catch2/build/generated-includes" - "${CMAKE_SOURCE_DIR}/external/bpftool" - "${CMAKE_SOURCE_DIR}/external/ebpf-verifier/src" - "${CMAKE_SOURCE_DIR}/external/ubpf/vm" - "${CMAKE_BINARY_DIR}/external/ubpf/vm" - "${CMAKE_SOURCE_DIR}/include" - "${CMAKE_SOURCE_DIR}/libs/api" - "${CMAKE_SOURCE_DIR}/libs/api_common" - "${CMAKE_SOURCE_DIR}/libs/ebpfnetsh" - "${CMAKE_SOURCE_DIR}/libs/execution_context" - "${CMAKE_SOURCE_DIR}/libs/platform" - "${CMAKE_SOURCE_DIR}/libs/platform/user" - "${CMAKE_SOURCE_DIR}/libs/service" - "${CMAKE_SOURCE_DIR}/libs/thunk" - "${CMAKE_SOURCE_DIR}/libs/thunk/mock" - "${CMAKE_SOURCE_DIR}/netebpfext" - "${CMAKE_SOURCE_DIR}/rpc_interface" - "${CMAKE_SOURCE_DIR}/tests/end_to_end" - "${CMAKE_SOURCE_DIR}/tests/libs/common" - "${CMAKE_SOURCE_DIR}/tests/libs/util" - "${CMAKE_SOURCE_DIR}/tests/sample" - "${CMAKE_SOURCE_DIR}/tests/sample/ext/inc" - "${CMAKE_SOURCE_DIR}/tests/xdp" - "${CMAKE_SOURCE_DIR}/tools/export_program_info" - "${WDK_ROOT}/include/${WDK_VERSION}/km" - "${WDK_ROOT}/include/${WDK_VERSION}/shared" -) - -target_link_libraries("fuzz" PRIVATE - "ebpf_for_windows_cpp_settings" - "api" - "api_common" - "Catch2::Catch2" - "Catch2::Catch2WithMain" - "common_tests" - "EbpfApi" - "execution_context_user" - "external::ebpfverifier" - "mincore.lib" - "pe_parse" - "platform_user" - "service" - "test_util" - "ubpf_user" -) - -target_compile_definitions("fuzz" PRIVATE - _CONSOLE -) - diff --git a/tests/fuzz/execution_context.cpp b/tests/fuzz/execution_context.cpp deleted file mode 100644 index 1d44931856..0000000000 --- a/tests/fuzz/execution_context.cpp +++ /dev/null @@ -1,184 +0,0 @@ -// Copyright (c) Microsoft Corporation -// SPDX-License-Identifier: MIT - -#define CATCH_CONFIG_MAIN - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "api_internal.h" -#include "bpf/libbpf.h" -#include "catch_wrapper.hpp" -#include "device_helper.hpp" -#include "helpers.h" -#include "ebpf_core.h" -#include "mock.h" -#include "platform.h" -#include "test_helper.hpp" - -#define ONE_MB_IN_BYTE (1024 * 1024) - -extern "C" size_t ebpf_fuzzing_memory_limit; -extern "C" bool ebpf_fuzzing_enabled; - -std::vector -get_handles() -{ - std::vector handles; - const char* error_message = nullptr; - bpf_object* object = nullptr; - bpf_link* link; - fd_t program_fd; - std::vector map_names{ - "ARRAY", - "HASH", - "LRU_HASH", - "LRU_PERCPU_HASH", - "PERCPU_ARRAY", - "PERCPU_HASH", - "QUEUE", - "STACK", - }; - - single_instance_hook_t hook(EBPF_PROGRAM_TYPE_XDP, EBPF_ATTACH_TYPE_XDP); - program_info_provider_t xdp_program_info(EBPF_PROGRAM_TYPE_XDP); - - object = bpf_object__open("map.o"); - REQUIRE(object != nullptr); - bpf_program* program = bpf_object__next_program(object, nullptr); - int error = bpf_object__load(object); - size_t error_message_size; - error_message = bpf_program__log_buf(program, &error_message_size); - if (error_message) { - printf("ebpf_program_load failed with %s\n", error_message); - } - REQUIRE(error == 0); - program_fd = bpf_program__fd(program); - for (const auto& name : map_names) { - fd_t map_fd = bpf_object__find_map_fd_by_name(object, (name + "_map").c_str()); - handles.push_back(Platform::_get_osfhandle(map_fd)); - } - uint32_t if_index = 1; - - // Attach only to the single interface being tested. - REQUIRE(hook.attach_link(program_fd, &if_index, sizeof(if_index), &link) == EBPF_SUCCESS); - fd_t link_fd = bpf_link__fd(link); - - handles.push_back(Platform::_get_osfhandle(program_fd)); - handles.push_back(Platform::_get_osfhandle(link_fd)); - return handles; -} - -std::vector -create_random_seed() -{ - std::random_device source; - std::vector random_data(std::mt19937::state_size); - for (auto& value : random_data) { - value = source(); - } - return random_data; -} - -std::vector -load_random_seed(const std::filesystem::path& file) -{ - std::ifstream input(file); - std::vector random_data(std::mt19937::state_size); - for (size_t i = 0; i < random_data.size(); i++) { - input >> std::hex >> random_data[i]; - } - return random_data; -} - -std::mt19937 -seed_random_engine() -{ - std::vector random_data; - char* buffer; - size_t buffer_size; - REQUIRE(_dupenv_s(&buffer, &buffer_size, "RANDOM_SEED") == 0); - if (buffer) { - random_data = load_random_seed(buffer); - } else { - random_data = create_random_seed(); - } - - std::cout << "[Begin random seed]" << std::endl; - size_t i = 0; - for (const auto& value : random_data) { - std::cout << std::hex << std::setw(8) << std::setfill('0') << value << ' '; - if (++i % 8 == 0) { - std::cout << std::endl; - } - } - std::cout << "[End random seed]" << std::endl; - - std::seed_seq seeds(std::begin(random_data), std::end(random_data)); - return std::mt19937(seeds); -} - -TEST_CASE("execution_context_direct", "[fuzz]") -{ - _test_helper_end_to_end test_helper; - const size_t iterations = 10000000; - auto handles = get_handles(); - ebpf_fuzzing_enabled = true; - auto mt = seed_random_engine(); - - ebpf_fuzzing_memory_limit = 50 * ONE_MB_IN_BYTE; - - ebpf_protocol_buffer_t request; - ebpf_protocol_buffer_t reply; - - REQUIRE(handles.size() > 0); - request.reserve(UINT16_MAX); - reply.reserve(UINT16_MAX); - for (size_t i = 0; i < iterations; i++) { - ebpf_operation_id_t operation_id = - static_cast(mt() % (EBPF_OPERATION_LOAD_NATIVE_PROGRAMS + 1)); - size_t minimum_request_size; - size_t minimum_reply_size; - bool async; - if (i % (iterations / 100) == 0) { - std::cout << std::dec << (i * 100) / iterations << "% completed" << std::endl; - } - - if (ebpf_core_get_protocol_handler_properties( - operation_id, &minimum_request_size, &minimum_reply_size, &async) != EBPF_SUCCESS) { - continue; - } - - // TODO - Add support for fuzzing async requests. - // https://github.com/microsoft/ebpf-for-windows/issues/897 - if (async) { - continue; - } - - // The strategy for fuzzing this API surface is: - // 1. Create an input buffer of size minimum_request_size + [0,1023]. - // 2. Fill buffer with random values. - // 3. Insert a handle value at offset 0 in the request. - request.resize(minimum_request_size + mt() % 1024); - std::fill(request.begin(), request.end(), static_cast(mt())); - auto header = reinterpret_cast(request.data()); - header->id = operation_id; - header->length = static_cast(request.size()); - if (request.size() >= sizeof(ebpf_operation_header_t) + sizeof(handles[0])) { - *reinterpret_cast(request.data() + sizeof(ebpf_operation_header_t)) = - handles[mt() % handles.size()]; - } - if (minimum_reply_size != 0) { - reply.resize(minimum_reply_size + mt() % 1024); - invoke_ioctl(request, reply); - } else { - invoke_ioctl(request); - } - } -} \ No newline at end of file diff --git a/tests/fuzz/fuzz.vcxproj b/tests/fuzz/fuzz.vcxproj deleted file mode 100644 index 995988a1b3..0000000000 --- a/tests/fuzz/fuzz.vcxproj +++ /dev/null @@ -1,144 +0,0 @@ - - - - - - - Debug - x64 - - - Release - x64 - - - - 16.0 - Win32Proj - {d88f9ce2-8da2-44fb-af7c-06466a180f31} - fuzz - 10.0 - - - - Application - true - v143 - Unicode - - - Application - false - v143 - true - Unicode - - - - - - - - - - - - - - - true - - - false - - - - _DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - $(SolutionDir)libs\api_common;$(SolutionDir)include;$(SolutionDir)libs\api;$(SolutionDir)libs\ebpfnetsh;$(SolutionDir)tests\libs\util;$(SolutionDir)tests\libs\common;$(OutDir);$(SolutionDir)external\ebpf-verifier\src;$(SolutionDir)libs\service;$(SolutionDir)rpc_interface;$(SolutionDir)libs\platform;$(SolutionDir)libs\platform\user;$(SolutionDir)libs\execution_context;$(SolutionDir)tests\end_to_end;$(SolutionDir)tests\sample;$(SolutionDir)tests\sample\ext\inc;$(SolutionDir)\tests\xdp;$(SolutionDir)tools\export_program_info;$(SolutionDir)libs\thunk;$(SolutionDir)libs\thunk\mock;$(SolutionDir)\netebpfext;$(SolutionDir)external\catch2\src;$(SolutionDir)external\catch2\build\generated-includes;$(SolutionDir)external\bpftool;%(AdditionalIncludeDirectories) - - - Console - true - mincore.lib;%(AdditionalDependencies) - - - - - true - true - NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - $(SolutionDir)libs\api_common;$(SolutionDir)include;$(SolutionDir)libs\api;$(SolutionDir)libs\ebpfnetsh;$(SolutionDir)tests\libs\util;$(SolutionDir)tests\libs\common;$(OutDir);$(SolutionDir)external\ebpf-verifier\src;$(SolutionDir)libs\service;$(SolutionDir)rpc_interface;$(SolutionDir)libs\platform;$(SolutionDir)libs\platform\user;$(SolutionDir)libs\execution_context;$(SolutionDir)tests\end_to_end;$(SolutionDir)tests\sample;$(SolutionDir)tests\sample\ext\inc;$(SolutionDir)\tests\xdp;$(SolutionDir)tools\export_program_info;$(SolutionDir)libs\thunk;$(SolutionDir)libs\thunk\mock;$(SolutionDir)\netebpfext;$(SolutionDir)external\catch2\src;$(SolutionDir)external\catch2\build\generated-includes;$(SolutionDir)external\bpftool;%(AdditionalIncludeDirectories) - false - - - Console - true - true - true - mincore.lib;%(AdditionalDependencies) - true - - - - - - - - - - - {8d538cbe-01bf-4a2e-a98a-6c368fdf13d7} - - - {8bd3552a-2cfb-4a59-ab15-2031b97ada1e} - - - {7d5b4e68-c0fa-3f86-9405-f6400219b440} - - - {c8bf60c3-40a9-43ad-891a-8aa34f1c3a68} - - - {e79382b2-fed9-4cd4-9498-dbddd6c46c91} - - - {18127b0d-8381-4afe-9a3a-cf53241992d3} - - - {fe4fea79-bfbb-4822-abcb-0d3beea240a7} - - - {c26cb6a9-158c-4a9e-a243-755ddd98e5fe} - - - {af85c549-57cc-40a5-bdfc-dcf1998de80f} - - - {c3d2cd73-bf4c-47df-8808-2a9996124d5b} - - - {245f0ec7-1ebc-4d68-8b1f-f758ea9196ae} - - - {3617528a-cb85-418b-82c1-e9cfc16755f6} - - - {d6725f19-b9bf-435f-80f2-c5f3ef0f4b8f} - - - {b4ad72e3-754e-40ca-9cea-d3f2c9170e51} - - - - - - - - - - \ No newline at end of file diff --git a/tests/fuzz/fuzz.vcxproj.filters b/tests/fuzz/fuzz.vcxproj.filters deleted file mode 100644 index 4852910c40..0000000000 --- a/tests/fuzz/fuzz.vcxproj.filters +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - \ No newline at end of file