Skip to content

Set up CI Fuzz #1

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

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 82 additions & 0 deletions .github/workflows/main.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
name: CI Fuzz
# Set an action secret called "CI_FUZZ_API_TOKEN" with an API token
# generated in CI Fuzz web interface.

on:
workflow_dispatch:
push:
branches: [ main ]
pull_request:
branches: [ main ]

env:
# CI Sense gRPC URL.
FUZZING_SERVER_ADDRESS: grpc.code-intelligence.com:443
# CI Sense HTTP URL.
WEB_APP_ADDRESS: https://app.code-intelligence.com
# Directory in which the repository will be cloned.
CHECKOUT_DIR: checkout-dir/
CIFUZZ_DOWNLOAD_URL: "https://github.com/CodeIntelligenceTesting/cifuzz/releases/latest/download/cifuzz_installer_linux_amd64"
CIFUZZ_INSTALL_DIR: ./cifuzz
FUZZING_ARTIFACT: fuzzing-artifact.tar.gz
jobs:
fuzz_tests:
runs-on: ubuntu-latest
container: cifuzz/builder-zint:llvm-13
steps:
- id: checkout
name: Checkout Repository
uses: actions/checkout@v2
with:
path: ${{ env.CHECKOUT_DIR }}
- id: install-cifuzz
name: Install cifuzz
run: |
curl --fail --silent --show-error --location -o cifuzz_installer "$CIFUZZ_DOWNLOAD_URL"
chmod u+x cifuzz_installer
./cifuzz_installer --install-dir $CIFUZZ_INSTALL_DIR
- id: build-fuzzers
name: Build Fuzzers
run: |
export cifuzz_DIR="$GITHUB_WORKSPACE/$CIFUZZ_INSTALL_DIR/share/cmake"
cd $CHECKOUT_DIR/
$GITHUB_WORKSPACE/$CIFUZZ_INSTALL_DIR/bin/cifuzz bundle \
--commit $GITHUB_SHA \
--branch $GITHUB_REF_NAME \
--output $GITHUB_WORKSPACE/$CHECKOUT_DIR/$FUZZING_ARTIFACT
shell: "bash"
- id: start-fuzzing
name: Start Fuzzing
uses: CodeIntelligenceTesting/github-actions/start-fuzzing@v5
with:
ci_fuzz_api_token: ${{ secrets.CI_FUZZ_API_TOKEN }}
fuzzing_server_address: ${{ env.FUZZING_SERVER_ADDRESS }}
fuzzing_artifact: ${{ env.CHECKOUT_DIR }}/${{ env.FUZZING_ARTIFACT }}
checkout_directory: ${{ env.CHECKOUT_DIR }}
project: "projects/automotive-example-9b3e6a66"
- id: monitor-fuzzing
name: Fuzzing
uses: CodeIntelligenceTesting/github-actions/monitor-fuzzing@v5
with:
ci_fuzz_api_token: ${{ secrets.CI_FUZZ_API_TOKEN }}
test_collection_run: ${{ steps.start-fuzzing.outputs.test_collection_run }}
fuzzing_server_address: ${{ env.FUZZING_SERVER_ADDRESS }}
dashboard_address: ${{ env.WEB_APP_ADDRESS }}
- id: save-results
name: Save Fuzz Test Results
uses: CodeIntelligenceTesting/github-actions/save-results@v5
if: ${{ success() || failure() }}
with:
ci_fuzz_api_token: ${{ secrets.CI_FUZZ_API_TOKEN }}
test_collection_run: ${{ steps.start-fuzzing.outputs.test_collection_run }}
fuzzing_server_address: ${{ env.FUZZING_SERVER_ADDRESS }}
dashboard_address: ${{ env.WEB_APP_ADDRESS }}
- id: upload-artifact
uses: actions/upload-artifact@v2
if: ${{ (success() || failure()) }}
with:
name: ci_fuzz_results
path: |
findings.json
coverage.json
web_app_address.txt
Empty file added .gitmodules
Empty file.
18 changes: 16 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
cmake_minimum_required(VERSION 3.10)
cmake_minimum_required(VERSION 3.16)

project(AUTOMOTIVE-FUZZING-EXAMPLE)

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

find_package(cifuzz NO_SYSTEM_ENVIRONMENT_PATH)
enable_fuzz_testing()

add_library(AUTOMOTIVE-FUZZING-EXAMPLE
modules/crypto_module/src/crypto_module_1.c
modules/crypto_module/src/crypto_module_2.c
Expand All @@ -15,4 +20,13 @@ target_include_directories(AUTOMOTIVE-FUZZING-EXAMPLE PRIVATE
modules/time_module/src
modules/key_management_module/src
modules/GPS_module/src
)
)

add_fuzz_test(module_fuzzer fuzz_test.cpp mocks.cpp)
target_link_libraries(module_fuzzer PRIVATE AUTOMOTIVE-FUZZING-EXAMPLE)
target_include_directories(module_fuzzer PRIVATE
modules/crypto_module/src
modules/time_module/src
modules/key_management_module/src
modules/GPS_module/src
)
49 changes: 2 additions & 47 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,49 +1,4 @@
# automotive-fuzzing-example
For the demo:
- Initialize Project
- Create fuzz test for a function
- To compile it the "extern" functions need to be implemented for this use the scripts in fuzzing/auto-mock-fuzz:
- ```python3 gen_template.py /path_to_project/automotive-fuzzing-example/modules/*/src/*.c /path_to_project/automotive-fuzzing-example/modules/*/src/*.h```
- This will create two excel sheets. The Sheet called testgen_mocks.xlsx will contain information about the functions that are declared as extern
- Fill in the excel sheet like this:

| int GPS_driver_obtain_current_position(uint8_t * position_as_bytes, uint8_t * hmac_as_bytes) | return: RETURN_INT(int) | position_as_bytes: WRITE_BYTES(12) | hmac_as_bytes: WRITE_BYTES(64) | | |
|---------------------------------------------------------------------------------------------------------------------------|-----------------------------|------------------------------------|--------------------------------|------------------------|-----------------------|
| int third_party_library_calc_hmac(uint8_t * const message, int len, char * const key, char * const nonce, uint8_t * hmac) | return: RETURN_INT(int) | message: WRITE_BYTES(len) | key: WRITE_BYTES(64) | nonce: WRITE_BYTES(64) | hmac: WRITE_BYTES(64) |
| uint8_t HSM_get_random_byte() | return: RETURN_INT(uint8_t) | | | | |
| int driver_get_current_time() | return: RETURN_INT(int) | | | | |
- Run the second script to generate the mocking library from this:
- ```python3 gen_tests.py mocklib gen_template/testgen_mocks.xlsx ../mocks```
- This creates mocklib.h and mocklib.cpp in fuzzing/mocks
- Add the mocklib.cpp to the compiler options and also add the include path fuzzing/mocks
- In the fuzztest you need to create a FuzzedDataProvider object and give a pointer to it to the mocking library. Add the following to the beginning of the FUZZ function:
```FuzzedDataProvider fuzz_data(Data, Size);```
```mocklib_set_data(&fuzz_data);```
- You also need to include the FuzzedDataProvider.h and mocklib.h in the fuzztest
- Now the fuzz test can run
- To create a fuzz test for all the functions fill in the excel sheet testgen_functions.xlsx like this:

| enum crypto_return_status crypto_calculate_hmac(const uint8_t * message, int len, crypto_hmac * hmac) | message: ARG_DATA() | len: ARG_SIZE() | hmac: ARG_STRUCT_PTR(crypto_hmac) | |
|-------------------------------------------------------------------------------------------------------|----------------------------------------|--------------------|-----------------------------------|---|
| enum crypto_return_status crypto_set_key(crypto_key key) | key: ARG_STRUCT(crypto_key) | | | |
| enum crypto_return_status crypto_set_nonce(crypto_nonce nonce) | nonce: ARG_STRUCT(crypto_nonce) | | | |
| enum crypto_return_status crypto_verify_hmac(const uint8_t * message, int len, crypto_hmac * hmac) | message: ARG_DATA() | len: ARG_SIZE() | hmac: ARG_STRUCT_PTR(crypto_hmac) | |
| enum crypto_return_status crypto_verify_key(crypto_key key) | key: ARG_STRUCT(crypto_key) | | | |
| enum crypto_return_status crypto_verify_nonce(crypto_nonce * nonce) | nonce: ARG_STRUCT_PTR(crypto_nonce) | | | |
| uint8_t * generate_random_bytes(uint8_t * buffer, uint8_t length) | buffer: ARG_DATA() | length: ARG_SIZE() | | |
| enum GPS_return_status get_current_position(GPS_position * position) | position: ARG_STRUCT_PTR(GPS_position) | | | |
| void key_management_create_key(uint8_t * key, uint8_t length) | key: ARG_DATA() | length: ARG_SIZE() | | |
| void key_management_create_nonce(uint8_t * nonce, uint8_t length) | nonce: ARG_DATA() | length: ARG_SIZE() | | |
| enum GPS_return_status set_destination_postition(GPS_position position) | position: ARG_STRUCT(GPS_position) | | | |
| enum crypto_state crypto_get_state() | | | | |
| void crypto_init() | | | | |
| GPS_position get_destination_position() | | | | |
| enum GPS_return_status init_crypto_module() | | | | |
| int time_current_time() | | | | |
- Then generate the fuzz test with the following command:
- ```python3 gen_tests.py fuzztests gen_template/testgen_functions.xlsx .```
- This will create a file fuzztest.c. Copy its content to your own fuzztest
- Include crypto_module_types.h and GPS_module_types.h in the fuzztest
- Run the fuzztest
# automotive-example

This is an example project to demonstrate testing C/C++ automotive software with CI Fuzz. Both the fuzz test and the corresponding mocks are automatically generated so that the target module is tested under all possible circumstances.

46 changes: 46 additions & 0 deletions cifuzz.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
## Configuration for a CI Fuzz project
## Generated on 2023-06-06

## The build system used to build this project. If not set, cifuzz tries
## to detect the build system automatically.
## Valid values: "bazel", "cmake", "maven", "gradle", "other".
#build-system: cmake

## If the build system type is "other", this command is used by
## `cifuzz run` to build the fuzz test.
#build-command: "make my_fuzz_test"

## Directories containing sample inputs for the code under test.
## See https://llvm.org/docs/LibFuzzer.html#corpus
#seed-corpus-dirs:
# - path/to/seed-corpus

## A file containing input language keywords or other interesting byte
## sequences.
## See https://llvm.org/docs/LibFuzzer.html#dictionaries
#dict: path/to/dictionary.dct

## Command-line arguments to pass to libFuzzer.
## See https://llvm.org/docs/LibFuzzer.html#options
#engine-args:
# - -rss_limit_mb=4096

## Maximum time to run fuzz tests. The default is to run indefinitely.
#timeout: 30m

## By default, fuzz tests are executed in a sandbox to prevent accidental
## damage to the system. Set to false to run fuzz tests unsandboxed.
## Only supported on Linux.
#use-sandbox: false

## Set to true to print output of the `cifuzz run` command as JSON.
#print-json: true

## Set to true to disable desktop notifications
#no-notifications: true

## Set URL of the CI App
#server: https://app.code-intelligence.com

## Set the project name on the CI App
#project: my-project-1a2b3c4d
Loading