Skip to content

Commit acffb98

Browse files
committed
fuzzing: gate fuzz-only relaxations on FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
1 parent caf9b1e commit acffb98

4 files changed

Lines changed: 17 additions & 14 deletions

File tree

fuzzing/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ foreach(header ${APP_HEADERS})
4444
endforeach()
4545
list(REMOVE_DUPLICATES APP_INCLUDE_DIRS)
4646

47+
# Enable the app's UI auto-approve (display.c) so the harness never blocks on confirmations.
4748
set(_fuzz_compile_defs HAVE_AUTOAPPROVE_FOR_PERF_TESTS=1)
4849
message(STATUS "Bitcoin fuzz build: single structured harness")
4950

fuzzing/README.md

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Bitcoin Fuzzing
22

3-
Bitcoin is the advanced integration in this repository. It runs on the same
4-
campaign pipeline as Boilerplate and uses the SDK's framework-driven entry
3+
This app integrates the fuzzing framework shipped with `ledger-secure-sdk`
4+
(on its fuzzing-framework branch). It uses the SDK's framework-driven entry
55
(`fuzz_harness_entry`) for APDU routing — the Bitcoin-specific pieces are
66
per-lane weighted `fuzz_commands[]` maps (via the SDK's
77
`FUZZ_PICK_COMMAND_RAW` / `FUZZ_PICK_COMMAND_STRUCTURED` override hooks),
@@ -11,16 +11,16 @@ through `os_io_rx_evt()`.
1111

1212
## Run it
1313

14-
From the workspace root:
14+
Point `BOLOS_SDK` at a `ledger-secure-sdk` checkout on the fuzzing-framework
15+
branch, then run the SDK campaign script from this app's root:
1516

1617
```bash
17-
BOLOS_SDK="$(pwd)/ledger-secure-sdk" \
18-
"$BOLOS_SDK"/fuzzing/scripts/app-campaign.sh \
19-
--app-dir "$(pwd)/app-bitcoin-new" bitcoin-run
18+
export BOLOS_SDK=/path/to/ledger-secure-sdk
19+
"$BOLOS_SDK"/fuzzing/scripts/app-campaign.sh --app-dir "$(pwd)" bitcoin-run
2020
```
2121

2222
- **`bitcoin-run`** is the campaign name (optional); outputs go to
23-
`app-bitcoin-new/.fuzz-artifacts/bitcoin-run/`. Omit for a UTC timestamp.
23+
`.fuzz-artifacts/bitcoin-run/` under the app root. Omit for a UTC timestamp.
2424
- Defaults: **`WARMUP_SEC=30`**, **`MAIN_SEC=60`**, **`WORKERS=min(2, nproc)`**.
2525
For longer campaigns, raise all three (see
2626
`ledger-secure-sdk/fuzzing/docs/APP_CONTRACT.md`).
@@ -36,9 +36,11 @@ checked-in corpus is stale for your layout.
3636
## Single harness
3737

3838
Bitcoin builds one fuzzing harness configuration. Two small fuzz-only repairs
39-
are gated behind `HAVE_AUTOAPPROVE_FOR_PERF_TESTS`: a wallet-policy
39+
are gated behind `FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION`: a wallet-policy
4040
repeated-pubkey bypass (the crypto mock returns a constant pubkey) and a relaxed
4141
cross-chain swap output-count check (so the OP_RETURN parser stays reachable).
42+
UI confirmations are auto-approved separately via the app's own
43+
`HAVE_AUTOAPPROVE_FOR_PERF_TESTS` flag (`display.c`).
4244
MuSig signing runs against the SDK crypto mock, so its consistency checks reject
4345
the mocked values early; descriptor parsing is still fully exercised.
4446

@@ -260,8 +262,8 @@ files.
260262
in `harness/fuzz_dispatcher.c` and keep the README's slot/fault tables
261263
in sync when you add new targeted operations.
262264
5. **Adjust fuzz-only repairs** — keep repairs gated with
263-
`#ifdef HAVE_AUTOAPPROVE_FOR_PERF_TESTS` and document any new one in the
264-
source site that applies it.
265+
`#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION` and document any new one in
266+
the source site that applies it.
265267
6. **Promote corpus inputs** — drop the hashed corpus files under
266268
`fuzzing/base-corpus/`. They are auto-loaded by `app-campaign.sh`
267269
unless their `.compat-key` is stale for the current build.

src/handler/lib/policy.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2015,7 +2015,7 @@ int is_policy_sane(dispatcher_context_t *dispatcher_context,
20152015
if (memcmp(pubkey_i.compressed_pubkey,
20162016
pubkey_j.compressed_pubkey,
20172017
sizeof(pubkey_i.compressed_pubkey)) == 0) {
2018-
#ifndef HAVE_AUTOAPPROVE_FOR_PERF_TESTS
2018+
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
20192019
// duplicated pubkey
20202020
return WITH_ERROR(-1, "Repeated pubkey in wallet policy");
20212021
#else

src/handler/sign_psbt/swap_checks.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ bool __attribute__((noinline)) execute_swap_checks(dispatcher_context_t *dc,
4141

4242
// Swap feature: check that wallet policy is a default one
4343
if (!st->account.is_default) {
44-
#ifdef HAVE_AUTOAPPROVE_FOR_PERF_TESTS
44+
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
4545
// Fuzzing repair: force the default-wallet branch so swap validation runs.
4646
st->account.is_default = true;
4747
#else
@@ -59,7 +59,7 @@ bool __attribute__((noinline)) execute_swap_checks(dispatcher_context_t *dc,
5959
}
6060

6161
if (st->warnings.missing_nonwitnessutxo || st->warnings.non_default_sighash) {
62-
#ifdef HAVE_AUTOAPPROVE_FOR_PERF_TESTS
62+
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
6363
// Fuzzing repair: clear warnings so the swap-validation tail runs.
6464
st->warnings.missing_nonwitnessutxo = false;
6565
st->warnings.non_default_sighash = false;
@@ -93,7 +93,7 @@ bool __attribute__((noinline)) execute_swap_checks(dispatcher_context_t *dc,
9393
swap_dest_idx = 1;
9494

9595
if (st->n_external_outputs != 2) {
96-
#ifdef HAVE_AUTOAPPROVE_FOR_PERF_TESTS
96+
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
9797
// Fuzzing repair: the exact "2 external outputs" count depends on
9898
// mocked change-classification and is rarely hit by mutation. Relax to
9999
// >=1 so the OP_RETURN parser below still runs; swap_dest_idx=0 keeps the

0 commit comments

Comments
 (0)