-
Notifications
You must be signed in to change notification settings - Fork 231
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
2ae8e0d
commit 398218e
Showing
10 changed files
with
489 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
FROM ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder-lite:latest AS LITE_BUILDER | ||
|
||
# Base image with clang toolchain | ||
FROM gcr.io/oss-fuzz-base/base-builder:v1 | ||
|
||
# Copy the project's source code. | ||
COPY . $SRC/app-ethereum | ||
COPY --from=LITE_BUILDER /opt/ledger-secure-sdk $SRC/app-ethereum/BOLOS_SDK | ||
|
||
# Working directory for build.sh | ||
WORKDIR $SRC/app-ethereum | ||
|
||
# Copy build.sh into $SRC dir. | ||
COPY ./.clusterfuzzlite/build.sh $SRC/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
#!/bin/bash -eu | ||
|
||
# build fuzzers | ||
|
||
pushd tests/fuzzing | ||
cmake -DBOLOS_SDK=../BOLOS_SDK -Bbuild -H. | ||
make -C build | ||
mv ./build/fuzz_app_eth "${OUT}" | ||
popd |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
language: c |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
name: ClusterFuzzLite cron tasks | ||
on: | ||
workflow_dispatch: | ||
push: | ||
branches: | ||
- main # Use your actual default branch here. | ||
schedule: | ||
- cron: '0 13 * * 6' # At 01:00 PM, only on Saturday | ||
permissions: read-all | ||
jobs: | ||
Fuzzing: | ||
runs-on: ubuntu-latest | ||
strategy: | ||
fail-fast: false | ||
matrix: | ||
include: | ||
- mode: batch | ||
sanitizer: address | ||
- mode: batch | ||
sanitizer: memory | ||
- mode: prune | ||
sanitizer: address | ||
- mode: coverage | ||
sanitizer: coverage | ||
steps: | ||
- name: Build Fuzzers (${{ matrix.mode }} - ${{ matrix.sanitizer }}) | ||
id: build | ||
uses: google/clusterfuzzlite/actions/build_fuzzers@v1 | ||
with: | ||
github-token: ${{ secrets.GITHUB_TOKEN }} | ||
language: c # Change this to the language you are fuzzing. | ||
sanitizer: ${{ matrix.sanitizer }} | ||
- name: Run Fuzzers (${{ matrix.mode }} - ${{ matrix.sanitizer }}) | ||
id: run | ||
uses: google/clusterfuzzlite/actions/run_fuzzers@v1 | ||
with: | ||
github-token: ${{ secrets.GITHUB_TOKEN }} | ||
fuzz-seconds: 300 # 5 minutes | ||
mode: ${{ matrix.mode }} | ||
sanitizer: ${{ matrix.sanitizer }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
name: ClusterFuzzLite PR fuzzing | ||
on: | ||
pull_request: | ||
paths: | ||
- '**' | ||
permissions: read-all | ||
jobs: | ||
PR: | ||
runs-on: ubuntu-latest | ||
concurrency: | ||
group: ${{ github.workflow }}-${{ matrix.sanitizer }}-${{ github.ref }} | ||
cancel-in-progress: true | ||
strategy: | ||
fail-fast: false | ||
matrix: | ||
sanitizer: [address, undefined, memory] # Override this with the sanitizers you want. | ||
steps: | ||
- name: Build Fuzzers (${{ matrix.sanitizer }}) | ||
id: build | ||
uses: google/clusterfuzzlite/actions/build_fuzzers@v1 | ||
with: | ||
language: c # Change this to the language you are fuzzing. | ||
github-token: ${{ secrets.GITHUB_TOKEN }} | ||
sanitizer: ${{ matrix.sanitizer }} | ||
# Optional but recommended: used to only run fuzzers that are affected | ||
# by the PR. | ||
# storage-repo: https://${{ secrets.PERSONAL_ACCESS_TOKEN }}@github.com/OWNER/STORAGE-REPO-NAME.git | ||
# storage-repo-branch: main # Optional. Defaults to "main" | ||
# storage-repo-branch-coverage: gh-pages # Optional. Defaults to "gh-pages". | ||
- name: Run Fuzzers (${{ matrix.sanitizer }}) | ||
id: run | ||
uses: google/clusterfuzzlite/actions/run_fuzzers@v1 | ||
with: | ||
github-token: ${{ secrets.GITHUB_TOKEN }} | ||
fuzz-seconds: 300 # 5 minutes | ||
mode: 'code-change' | ||
sanitizer: ${{ matrix.sanitizer }} | ||
output-sarif: true | ||
# Optional but recommended: used to download the corpus produced by | ||
# batch fuzzing. | ||
# storage-repo: https://${{ secrets.PERSONAL_ACCESS_TOKEN }}@github.com/OWNER/STORAGE-REPO-NAME.git | ||
# storage-repo-branch: main # Optional. Defaults to "main" | ||
# storage-repo-branch-coverage: gh-pages # Optional. Defaults to "gh-pages". |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
cmake_minimum_required(VERSION 3.10) | ||
|
||
if(${CMAKE_VERSION} VERSION_LESS 3.10) | ||
cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}) | ||
endif() | ||
|
||
# project information | ||
project(Fuzzer | ||
VERSION 1.0 | ||
DESCRIPTION "Eth Fuzzer" | ||
LANGUAGES C) | ||
|
||
set(CMAKE_C_COMPILER clang) | ||
|
||
set(CMAKE_BUILD_TYPE "Debug") | ||
|
||
set(CMAKE_C_STANDARD 11) | ||
set(CMAKE_C_FLAGS | ||
"${CMAKE_C_FLAGS} -Wall -Wextra -pedantic -Wno-unused-parameter -Wno-embedded-directive -g -O0 -fsanitize=fuzzer,address,undefined -fprofile-instr-generate -fcoverage-mapping" | ||
) | ||
|
||
# guard against in-source builds | ||
if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR}) | ||
message(FATAL_ERROR "In-source builds not allowed. Please make a new directory (called a build directory) and run CMake from there. You may need to remove CMakeCache.txt. ") | ||
endif() | ||
|
||
set(TARGET_DEVICE flex) | ||
set(BOLOS_SDK /opt/${TARGET_DEVICE}-secure-sdk) | ||
if (NOT DEFINED BOLOS_SDK) | ||
message(FATAL_ERROR "BOLOS_SDK environment variable not found.") | ||
endif() | ||
|
||
set(DEFINES | ||
gcc | ||
APPNAME=\"Fuzzing\" | ||
API_LEVEL=21 | ||
TARGET=\"flex\" | ||
TARGET_NAME=\"TARGET_FLEX\" | ||
APPVERSION=\"1.1.0\" | ||
SDK_NAME=\"ledger-secure-sdk\" | ||
SDK_VERSION=\"v21.3.3\" | ||
SDK_HASH=\"d88d4db3c93665f52b5b1f45099d9d36dfaa06ba\" | ||
gcc | ||
__IO=volatile | ||
NDEBUG | ||
HAVE_BAGL_FONT_INTER_REGULAR_28PX | ||
HAVE_BAGL_FONT_INTER_SEMIBOLD_28PX | ||
HAVE_BAGL_FONT_INTER_MEDIUM_36PX | ||
HAVE_INAPP_BLE_PAIRING | ||
HAVE_NBGL | ||
HAVE_PIEZO_SOUND | ||
HAVE_SE_TOUCH | ||
HAVE_SE_EINK_DISPLAY | ||
NBGL_PAGE | ||
NBGL_USE_CASE | ||
SCREEN_SIZE_WALLET | ||
HAVE_FAST_HOLD_TO_APPROVE | ||
HAVE_LEDGER_PKI | ||
HAVE_NES_CRYPT | ||
HAVE_ST_AES | ||
NATIVE_LITTLE_ENDIAN | ||
HAVE_CRC | ||
HAVE_HASH | ||
HAVE_RIPEMD160 | ||
HAVE_SHA224 | ||
HAVE_SHA256 | ||
HAVE_SHA3 | ||
HAVE_SHA384 | ||
HAVE_SHA512 | ||
HAVE_SHA512_WITH_BLOCK_ALT_METHOD | ||
HAVE_SHA512_WITH_BLOCK_ALT_METHOD_M0 | ||
HAVE_BLAKE2 | ||
HAVE_HMAC | ||
HAVE_PBKDF2 | ||
HAVE_AES | ||
HAVE_MATH | ||
HAVE_RNG | ||
HAVE_RNG_RFC6979 | ||
HAVE_RNG_SP800_90A | ||
HAVE_ECC | ||
HAVE_ECC_WEIERSTRASS | ||
HAVE_ECC_TWISTED_EDWARDS | ||
HAVE_ECC_MONTGOMERY | ||
HAVE_SECP256K1_CURVE | ||
HAVE_SECP256R1_CURVE | ||
HAVE_SECP384R1_CURVE | ||
HAVE_SECP521R1_CURVE | ||
HAVE_FR256V1_CURVE | ||
HAVE_STARK256_CURVE | ||
HAVE_BRAINPOOL_P256R1_CURVE | ||
HAVE_BRAINPOOL_P256T1_CURVE | ||
HAVE_BRAINPOOL_P320R1_CURVE | ||
HAVE_BRAINPOOL_P320T1_CURVE | ||
HAVE_BRAINPOOL_P384R1_CURVE | ||
HAVE_BRAINPOOL_P384T1_CURVE | ||
HAVE_BRAINPOOL_P512R1_CURVE | ||
HAVE_BRAINPOOL_P512T1_CURVE | ||
HAVE_BLS12_381_G1_CURVE | ||
HAVE_CV25519_CURVE | ||
HAVE_CV448_CURVE | ||
HAVE_ED25519_CURVE | ||
HAVE_ED448_CURVE | ||
HAVE_ECDH | ||
HAVE_ECDSA | ||
HAVE_EDDSA | ||
HAVE_ECSCHNORR | ||
HAVE_X25519 | ||
HAVE_X448 | ||
HAVE_AES_GCM | ||
HAVE_CMAC | ||
HAVE_AES_SIV | ||
COIN_VARIANT=1 | ||
HAVE_BOLOS_APP_STACK_CANARY | ||
IO_SEPROXYHAL_BUFFER_SIZE_B=300 | ||
HAVE_BLE | ||
BLE_COMMAND_TIMEOUT_MS=2000 | ||
HAVE_BLE_APDU | ||
BLE_SEGMENT_SIZE=32 | ||
HAVE_DEBUG_THROWS | ||
NBGL_QRCODE | ||
MAJOR_VERSION=1 | ||
MINOR_VERSION=1 | ||
PATCH_VERSION=0 | ||
IO_HID_EP_LENGTH=64 | ||
HAVE_SPRINTF | ||
HAVE_SNPRINTF_FORMAT_U | ||
HAVE_IO_USB | ||
HAVE_L4_USBLIB | ||
IO_USB_MAX_ENDPOINTS=4 | ||
HAVE_USB_APDU | ||
USB_SEGMENT_SIZE=64 | ||
HAVE_WEBUSB | ||
WEBUSB_URL_SIZE_B=0 | ||
WEBUSB_URL= | ||
OS_IO_SEPROXYHAL | ||
STANDARD_APP_SYNC_RAPDU | ||
HAVE_GENERIC_TX_PARSER | ||
HAVE_TRUSTED_NAME | ||
HAVE_DYN_MEM_ALLOC | ||
HAVE_SWAP | ||
HAVE_ENUM_VALUE | ||
HAVE_NFT_SUPPORT | ||
) | ||
set(DEFINE ${DEFINES} HAVE_PRINTF PRINTF=printf) | ||
|
||
add_compile_definitions(${DEFINES}) | ||
|
||
FILE(GLOB_RECURSE SDK_STD_SOURCES ${BOLOS_SDK}/lib_standard_app/write.c src/mock.c) | ||
|
||
|
||
include_directories( | ||
${CMAKE_SOURCE_DIR}/../../ethereum-plugin-sdk/src/ | ||
${CMAKE_SOURCE_DIR}/../../src | ||
${CMAKE_SOURCE_DIR}/../../src_features/provideDynamicNetwork/ | ||
${BOLOS_SDK}/include | ||
${BOLOS_SDK}/lib_standard_app | ||
${BOLOS_SDK}/target/${TARGET_DEVICE}/include | ||
${BOLOS_SDK}/lib_cxng/include | ||
${BOLOS_SDK}/lib_cxng/src | ||
${BOLOS_SDK}/lib_ux_nbgl | ||
${BOLOS_SDK}/lib_nbgl/include | ||
${CMAKE_SOURCE_DIR}/src | ||
) | ||
|
||
FILE(GLOB_RECURSE SOURCES | ||
${CMAKE_SOURCE_DIR}/../../src_features/provideDynamicNetwork/*.c | ||
${CMAKE_SOURCE_DIR}/../../src/hash_bytes.c | ||
) | ||
|
||
add_executable(fuzz_app_eth src/fuzz_app_eth.c ${SDK_STD_SOURCES} ${SOURCES}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
# Fuzzing Tests | ||
|
||
## Fuzzing | ||
|
||
Fuzzing allows us to test how a program behaves when provided with invalid, unexpected, or random data as input. | ||
|
||
Our fuzz target needs to implement `int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)`, | ||
which provides an array of random bytes that can be used to simulate a serialized buffer. | ||
If the application crashes, or a [sanitizer](https://github.com/google/sanitizers) detects | ||
any kind of access violation, the fuzzing process is stopped, a report regarding the vulnerability is shown, | ||
and the input that triggered the bug is written to disk under the name `crash-*`. | ||
The vulnerable input file created can be passed as an argument to the fuzzer to triage the issue. | ||
|
||
> **Note**: Usually we want to write a separate fuzz target for each functionality. | ||
## Manual usage based on Ledger container | ||
|
||
### Preparation | ||
|
||
The fuzzer can run from the docker `ledger-app-builder-legacy`. You can download it from the `ghcr.io` docker repository: | ||
|
||
```console | ||
sudo docker pull ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder-legacy:latest | ||
``` | ||
|
||
You can then enter this development environment by executing the following command from the repository root directory: | ||
|
||
```console | ||
sudo docker run --rm -ti --user "$(id -u):$(id -g)" -v "$(realpath .):/app" ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder-legacy:latest | ||
``` | ||
|
||
### Compilation | ||
|
||
Once in the container, go into the `tests/fuzzing` folder to compile the fuzzer: | ||
|
||
```console | ||
cd tests/fuzzing | ||
|
||
# cmake initialization | ||
cmake -DBOLOS_SDK=/opt/ledger-secure-sdk -DCMAKE_C_COMPILER=/usr/bin/clang -Bbuild -H. | ||
|
||
# Fuzzer compilation | ||
make -C build | ||
``` | ||
|
||
### Run | ||
|
||
```console | ||
./build/fuzz_app_eth | ||
``` | ||
|
||
## Full usage based on `clusterfuzzlite` container | ||
|
||
Exactly the same context as the CI, directly using the `clusterfuzzlite` environment. | ||
|
||
More info can be found here: | ||
<https://google.github.io/clusterfuzzlite/> | ||
|
||
### Preparation | ||
|
||
The principle is to build the container, and run it to perform the fuzzing. | ||
|
||
> **Note**: The container contains a copy of the sources (they are not cloned), | ||
> which means the `docker build` command must be re-executed after each code modification. | ||
```console | ||
# Prepare directory tree | ||
mkdir tests/fuzzing/{corpus,out} | ||
# Container generation | ||
docker build -t app-ethereum --file .clusterfuzzlite/Dockerfile . | ||
``` | ||
|
||
### Compilation | ||
|
||
```console | ||
docker run --rm --privileged -e FUZZING_LANGUAGE=c -v "$(realpath .)/tests/fuzzing/out:/out" -ti app-ethereum | ||
``` | ||
|
||
### Run | ||
|
||
```console | ||
docker run --rm --privileged -e FUZZING_ENGINE=libfuzzer -e RUN_FUZZER_MODE=interactive -v "$(realpath .)/tests/fuzzing/corpus:/tmp/fuzz_corpus" -v "$(realpath .)/tests/fuzzing/out:/out" -ti gcr.io/oss-fuzz-base/base-runner run_fuzzer fuzz_app_eth | ||
``` |
Oops, something went wrong.