From 5ac1fd55eea9d4b5e9b34be50d3b684693e3a935 Mon Sep 17 00:00:00 2001 From: mtg0001 <106211915+mtg0001@users.noreply.github.com> Date: Tue, 4 Aug 2026 15:25:34 -0300 Subject: build: pin external source dependencies (#139) Co-authored-by: Gilcimar Duarte --- Makefile | 43 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 7 deletions(-) (limited to 'Makefile') diff --git a/Makefile b/Makefile index ea720f1..0788b61 100644 --- a/Makefile +++ b/Makefile @@ -12,6 +12,11 @@ NPROC := $(shell nproc 2>/dev/null || echo 2) SUDO := $(shell [ "$$(id -u)" = "0" ] && echo "" || echo "sudo") VERSION := 1.2.15 +SECP256K1_REPO := https://github.com/bitcoin-core/secp256k1 +SECP256K1_COMMIT := 7fecac74aed8e1fd9078380d67dd04663705c989 +RANDOMX_REPO := https://github.com/tevador/RandomX +RANDOMX_COMMIT := 1e9d4b2df63fa6edf46b06789486e23c0fcaa55a + # ---- Linux ---------------------------------------------------------------- linux: deps-linux @@ -47,7 +52,13 @@ deps-secp256k1: @if [ ! -f /usr/local/lib/libsecp256k1.a ]; then \ echo "==> building libsecp256k1"; \ rm -rf $(ROOT)/secp256k1-build; \ - git clone --depth 1 https://github.com/bitcoin-core/secp256k1 $(ROOT)/secp256k1-build; \ + git init -q $(ROOT)/secp256k1-build; \ + cd $(ROOT)/secp256k1-build && \ + git remote add origin $(SECP256K1_REPO) && \ + git fetch -q --depth 1 origin $(SECP256K1_COMMIT) && \ + git checkout -q --detach FETCH_HEAD && \ + test "$$(git rev-parse HEAD)" = "$(SECP256K1_COMMIT)" && \ + echo "==> libsecp256k1 pinned at $(SECP256K1_COMMIT)" && \ cd $(ROOT)/secp256k1-build && ./autogen.sh && \ ./configure --enable-module-schnorrsig --enable-module-extrakeys \ --disable-shared --with-pic --disable-benchmark --disable-tests && \ @@ -61,7 +72,13 @@ deps-randomx: @if [ ! -f $(HOME)/RandomX/build/librandomx.a ]; then \ echo "==> building RandomX"; \ rm -rf $(HOME)/RandomX; \ - git clone --depth 1 https://github.com/tevador/RandomX $(HOME)/RandomX; \ + git init -q $(HOME)/RandomX; \ + cd $(HOME)/RandomX && \ + git remote add origin $(RANDOMX_REPO) && \ + git fetch -q --depth 1 origin $(RANDOMX_COMMIT) && \ + git checkout -q --detach FETCH_HEAD && \ + test "$$(git rev-parse HEAD)" = "$(RANDOMX_COMMIT)" && \ + echo "==> RandomX pinned at $(RANDOMX_COMMIT)" && \ mkdir -p $(HOME)/RandomX/build; \ cd $(HOME)/RandomX/build && cmake .. -DCMAKE_BUILD_TYPE=Release && \ make -j$(NPROC) randomx; \ @@ -120,8 +137,14 @@ deps-windows: autoconf automake libtool @if [ ! -f deps/lib/libsecp256k1.a ]; then \ rm -rf secp256k1-build; \ - git clone --depth 1 https://github.com/bitcoin-core/secp256k1 secp256k1-build; \ - cd secp256k1-build && ./autogen.sh && \ + git init -q secp256k1-build; \ + cd secp256k1-build && \ + git remote add origin $(SECP256K1_REPO) && \ + git fetch -q --depth 1 origin $(SECP256K1_COMMIT) && \ + git checkout -q --detach FETCH_HEAD && \ + test "$$(git rev-parse HEAD)" = "$(SECP256K1_COMMIT)" && \ + echo "==> secp256k1 pinned at $(SECP256K1_COMMIT)" && \ + cd $(ROOT)/secp256k1-build && ./autogen.sh && \ ./configure --prefix=$(ROOT)/deps \ --enable-module-schnorrsig --enable-module-extrakeys \ --disable-shared --with-pic --disable-benchmark --disable-tests && \ @@ -132,9 +155,15 @@ deps-windows: fi @if [ ! -f RandomX/build/librandomx.a ]; then \ rm -rf RandomX; \ - git clone --depth 1 https://github.com/tevador/RandomX; \ - mkdir -p RandomX/build; \ - cd RandomX/build && cmake .. -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release && \ + git init -q RandomX; \ + cd RandomX && \ + git remote add origin $(RANDOMX_REPO) && \ + git fetch -q --depth 1 origin $(RANDOMX_COMMIT) && \ + git checkout -q --detach FETCH_HEAD && \ + test "$$(git rev-parse HEAD)" = "$(RANDOMX_COMMIT)" && \ + echo "==> RandomX pinned at $(RANDOMX_COMMIT)" && \ + mkdir -p $(ROOT)/RandomX/build; \ + cd $(ROOT)/RandomX/build && cmake .. -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release && \ make randomx; \ echo "==> RandomX done"; \ else \ -- cgit v1.2.3 From b3a5a858e536acf65e6c6761293626628f2227bf Mon Sep 17 00:00:00 2001 From: mtg0001 <106211915+mtg0001@users.noreply.github.com> Date: Tue, 4 Aug 2026 15:31:55 -0300 Subject: fuzz: add P2P message parser harness (#142) * fuzz: add P2P message parser harness * fuzz: avoid duplicate legacy header includes * fuzz: seed the corpus with our network magic, not Bitcoin's The two seed inputs began f5 be b6 d9, which is Bitcoin's message start. Ours is bf 20 5c fd. CMessageHeader::IsValid rejects on that field first, so both seeds died at the first check and the smoke run exercised the reject path and nothing else. libFuzzer would have to mutate its way onto four exact bytes before reaching any parser, which does not happen in 128 runs. The job would have gone green while covering none of what it was added to cover. --------- Co-authored-by: Gilcimar Duarte Co-authored-by: Bitflash-sh --- .github/workflows/ci.yml | 3 +++ Makefile | 7 +++++-- src/Makefile | 34 +++++++++++++++++++++++++++++++++- src/fuzz_net_message.cpp | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 73 insertions(+), 3 deletions(-) create mode 100644 src/fuzz_net_message.cpp (limited to 'Makefile') diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 985ba8a..9efd66f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,6 +25,9 @@ jobs: - name: Run Linux selftests run: make tests + - name: Run P2P message fuzz smoke + run: make fuzz-net-message-smoke + windows-ucrt64: name: Windows UCRT64 selftests runs-on: windows-latest diff --git a/Makefile b/Makefile index 0788b61..736f5d8 100644 --- a/Makefile +++ b/Makefile @@ -42,7 +42,7 @@ deps-apt: @if command -v apt-get >/dev/null 2>&1; then \ $(SUDO) apt-get install -y build-essential cmake git pkg-config autoconf \ libtool libssl-dev libdb5.3++-dev libsodium-dev nlohmann-json3-dev \ - libboost-system-dev libglfw3-dev libgl-dev python3-pil; \ + libboost-system-dev libglfw3-dev libgl-dev python3-pil clang; \ else \ echo "Not an apt system — install: g++ cmake git autoconf libtool"; \ echo " libssl libdb++ libsodium nlohmann-json boost glfw3 opengl python3-pil"; \ @@ -191,6 +191,9 @@ clean: tests: $(MAKE) -C src -f Makefile tests +fuzz-net-message-smoke: deps-linux + $(MAKE) -C src -f Makefile fuzz-net-message-smoke + checksums: ./scripts/make-release-checksums.sh @@ -201,5 +204,5 @@ verify-release: ./scripts/verify-release.sh $(if $(TAG),$(TAG),latest) .PHONY: linux windows clean appimage \ - tests checksums sign-checksums verify-release \ + tests fuzz-net-message-smoke checksums sign-checksums verify-release \ deps-linux deps-windows deps-apt deps-secp256k1 deps-randomx diff --git a/src/Makefile b/src/Makefile index 3577dd6..ac0226e 100644 --- a/src/Makefile +++ b/src/Makefile @@ -2,6 +2,7 @@ # Called by: make linux (root Makefile) CXX ?= g++ +FUZZ_CXX ?= clang++ SECP_INC ?= /usr/local/include SECP_LIB ?= /usr/local/lib @@ -33,6 +34,9 @@ CXXFLAGS = -std=gnu++14 -O2 $(WARNFLAGS) -fpermissive -pthread \ -I$(SECP_INC) -I$(RANDOMX_DIR)/src \ -I/usr/include/nlohmann \ -I$(IMGUI_DIR) +FUZZ_CXXFLAGS = $(filter-out -O2,$(CXXFLAGS)) -O1 -g -fno-omit-frame-pointer \ + -fsanitize=fuzzer-no-link,address,undefined +FUZZ_LDFLAGS = -fsanitize=fuzzer,address,undefined LIBS = -L$(SECP_LIB) -lsecp256k1 \ -L$(RANDOMX_DIR)/build -lrandomx \ @@ -117,6 +121,9 @@ NODE_LIBS = -L$(SECP_LIB) -lsecp256k1 \ NODE_ONLY_OBJS = $(patsubst obj/%,obj-node/%,$(NODE_OBJS)) \ obj-node/main_gui.o obj-node/headless.o +FUZZ_OBJS = $(patsubst obj/%,obj-fuzz/%,$(NODE_OBJS)) \ + obj-fuzz/fuzz_net_message.o + obj-node/%.o: %.cpp $(HEADERS) @mkdir -p obj-node $(CXX) -c $(CXXFLAGS) -DBITFLASH_NO_GUI -o $@ $< @@ -129,8 +136,31 @@ bitflash-node: $(NODE_ONLY_OBJS) $(CXX) $(CXXFLAGS) -o $@ $^ $(NODE_LIBS) @echo "Built: bitflash-node (headless, no libGL needed)" +obj-fuzz/%.o: %.cpp $(HEADERS) + @mkdir -p obj-fuzz + $(FUZZ_CXX) -c $(FUZZ_CXXFLAGS) -DBITFLASH_FUZZ -o $@ $< + +obj-fuzz/sha.o: sha.cpp sha.h + @mkdir -p obj-fuzz + $(FUZZ_CXX) -c $(FUZZ_CXXFLAGS) -DBITFLASH_FUZZ -O1 -o $@ $< + +obj-fuzz/fuzz_net_message.o: fuzz_net_message.cpp $(HEADERS) + @mkdir -p obj-fuzz + $(FUZZ_CXX) -c $(FUZZ_CXXFLAGS) -DBITFLASH_FUZZ -o $@ $< + +fuzz-net-message: $(FUZZ_OBJS) + $(FUZZ_CXX) $(filter-out -fsanitize=fuzzer-no-link%,$(FUZZ_CXXFLAGS)) \ + $(FUZZ_LDFLAGS) -o $@ $^ $(NODE_LIBS) + @echo "Built: fuzz-net-message" + +fuzz-net-message-smoke: fuzz-net-message + @mkdir -p ../work/fuzz-corpus/net-message + @printf '\277\040\134\375ping\000\000\000\000\000\000\000\000\000\000\000\000' > ../work/fuzz-corpus/net-message/ping-header + @printf '\277\040\134\375version\000\000\000\000\000\000\000\000\000' > ../work/fuzz-corpus/net-message/version-header + ./fuzz-net-message -runs=128 ../work/fuzz-corpus/net-message + clean: - rm -rf obj obj-node bitflash bitflash-node test_bip32 + rm -rf obj obj-node obj-fuzz bitflash bitflash-node fuzz-net-message test_bip32 test_bip32: test_bip32.cpp bip32.cpp bip32.h bip39_english.h $(CXX) $(CXXFLAGS) -o $@ test_bip32.cpp bip32.cpp -lssl -lcrypto @@ -144,3 +174,5 @@ tests: test_bip32 bitflash-node ./bitflash-node -selftest=wallet-encrypt ./bitflash-node -selftest=net-message ./bitflash-node -selftest=consensus-limits + +.PHONY: tests fuzz-net-message-smoke diff --git a/src/fuzz_net_message.cpp b/src/fuzz_net_message.cpp new file mode 100644 index 0000000..1104d90 --- /dev/null +++ b/src/fuzz_net_message.cpp @@ -0,0 +1,32 @@ +// Copyright (c) 2026 Bitflash developers +// Distributed under the MIT/X11 software license. +// +// libFuzzer harness for the P2P message envelope parser. It feeds arbitrary +// receive-buffer bytes into ProcessMessages() through a dummy CNode, without +// opening sockets or starting node threads. + +#include "headers_core.h" + +#include +#include + +// Stand-ins normally supplied by the GUI/headless entry objects. +map mapAddressBook; +bool gPoolServerRunning = false; +void MainFrameRepaint() {} + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) +{ + // Keep this first target focused on parser behavior, not multi-megabyte + // allocation pressure. The protocol size guards have their own selftest. + if (size > 4096) + return 0; + + CNode node(INVALID_SOCKET, CAddress("127.0.0.1")); + node.nVersion = 0; // exercise pre-version gating plus the version parser + if (size > 0) + node.vRecv.write((const char*)data, (int)size); + + ProcessMessages(&node); + return 0; +} -- cgit v1.2.3 From 4de5cca7e7a0a7104dae8d414add33f6e9562e4a Mon Sep 17 00:00:00 2001 From: Nsable-sh Date: Fri, 7 Aug 2026 10:55:54 -0300 Subject: fuzz: add script parser harness (#5) --- .github/workflows/ci.yml | 3 +++ Makefile | 5 +++- src/Makefile | 27 ++++++++++++++++++---- src/fuzz_script.cpp | 59 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 88 insertions(+), 6 deletions(-) create mode 100644 src/fuzz_script.cpp (limited to 'Makefile') diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9efd66f..ba8074c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -28,6 +28,9 @@ jobs: - name: Run P2P message fuzz smoke run: make fuzz-net-message-smoke + - name: Run script fuzz smoke + run: make fuzz-script-smoke + windows-ucrt64: name: Windows UCRT64 selftests runs-on: windows-latest diff --git a/Makefile b/Makefile index 736f5d8..d0f1b26 100644 --- a/Makefile +++ b/Makefile @@ -194,6 +194,9 @@ tests: fuzz-net-message-smoke: deps-linux $(MAKE) -C src -f Makefile fuzz-net-message-smoke +fuzz-script-smoke: deps-linux + $(MAKE) -C src -f Makefile fuzz-script-smoke + checksums: ./scripts/make-release-checksums.sh @@ -204,5 +207,5 @@ verify-release: ./scripts/verify-release.sh $(if $(TAG),$(TAG),latest) .PHONY: linux windows clean appimage \ - tests fuzz-net-message-smoke checksums sign-checksums verify-release \ + tests fuzz-net-message-smoke fuzz-script-smoke checksums sign-checksums verify-release \ deps-linux deps-windows deps-apt deps-secp256k1 deps-randomx diff --git a/src/Makefile b/src/Makefile index ac0226e..cc52fd6 100644 --- a/src/Makefile +++ b/src/Makefile @@ -121,8 +121,9 @@ NODE_LIBS = -L$(SECP_LIB) -lsecp256k1 \ NODE_ONLY_OBJS = $(patsubst obj/%,obj-node/%,$(NODE_OBJS)) \ obj-node/main_gui.o obj-node/headless.o -FUZZ_OBJS = $(patsubst obj/%,obj-fuzz/%,$(NODE_OBJS)) \ - obj-fuzz/fuzz_net_message.o +FUZZ_BASE_OBJS = $(patsubst obj/%,obj-fuzz/%,$(NODE_OBJS)) +FUZZ_NET_MESSAGE_OBJS = $(FUZZ_BASE_OBJS) obj-fuzz/fuzz_net_message.o +FUZZ_SCRIPT_OBJS = $(FUZZ_BASE_OBJS) obj-fuzz/fuzz_script.o obj-node/%.o: %.cpp $(HEADERS) @mkdir -p obj-node @@ -148,19 +149,35 @@ obj-fuzz/fuzz_net_message.o: fuzz_net_message.cpp $(HEADERS) @mkdir -p obj-fuzz $(FUZZ_CXX) -c $(FUZZ_CXXFLAGS) -DBITFLASH_FUZZ -o $@ $< -fuzz-net-message: $(FUZZ_OBJS) +obj-fuzz/fuzz_script.o: fuzz_script.cpp $(HEADERS) + @mkdir -p obj-fuzz + $(FUZZ_CXX) -c $(FUZZ_CXXFLAGS) -DBITFLASH_FUZZ -o $@ $< + +fuzz-net-message: $(FUZZ_NET_MESSAGE_OBJS) $(FUZZ_CXX) $(filter-out -fsanitize=fuzzer-no-link%,$(FUZZ_CXXFLAGS)) \ $(FUZZ_LDFLAGS) -o $@ $^ $(NODE_LIBS) @echo "Built: fuzz-net-message" +fuzz-script: $(FUZZ_SCRIPT_OBJS) + $(FUZZ_CXX) $(filter-out -fsanitize=fuzzer-no-link%,$(FUZZ_CXXFLAGS)) \ + $(FUZZ_LDFLAGS) -o $@ $^ $(NODE_LIBS) + @echo "Built: fuzz-script" + fuzz-net-message-smoke: fuzz-net-message @mkdir -p ../work/fuzz-corpus/net-message @printf '\277\040\134\375ping\000\000\000\000\000\000\000\000\000\000\000\000' > ../work/fuzz-corpus/net-message/ping-header @printf '\277\040\134\375version\000\000\000\000\000\000\000\000\000' > ../work/fuzz-corpus/net-message/version-header ./fuzz-net-message -runs=128 ../work/fuzz-corpus/net-message +fuzz-script-smoke: fuzz-script + @mkdir -p ../work/fuzz-corpus/script + @printf '\000\121' > ../work/fuzz-corpus/script/op-true + @printf '\001\166\251\024\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\210\254' > ../work/fuzz-corpus/script/p2pkh-shape + @printf '\000\115\377\377' > ../work/fuzz-corpus/script/truncated-pushdata2 + ./fuzz-script -runs=128 ../work/fuzz-corpus/script + clean: - rm -rf obj obj-node obj-fuzz bitflash bitflash-node fuzz-net-message test_bip32 + rm -rf obj obj-node obj-fuzz bitflash bitflash-node fuzz-net-message fuzz-script test_bip32 test_bip32: test_bip32.cpp bip32.cpp bip32.h bip39_english.h $(CXX) $(CXXFLAGS) -o $@ test_bip32.cpp bip32.cpp -lssl -lcrypto @@ -175,4 +192,4 @@ tests: test_bip32 bitflash-node ./bitflash-node -selftest=net-message ./bitflash-node -selftest=consensus-limits -.PHONY: tests fuzz-net-message-smoke +.PHONY: tests fuzz-net-message-smoke fuzz-script-smoke diff --git a/src/fuzz_script.cpp b/src/fuzz_script.cpp new file mode 100644 index 0000000..28c84f6 --- /dev/null +++ b/src/fuzz_script.cpp @@ -0,0 +1,59 @@ +// Copyright (c) 2026 Bitflash developers +// Distributed under the MIT/X11 software license. +// +// libFuzzer harness for raw script parsing and evaluation. It keeps the +// target deliberately small: arbitrary bytes become one CScript, then the +// parser, standard-script extractors and EvalScript all see that same input. + +#include "headers_core.h" + +#include +#include + +// Stand-ins normally supplied by the GUI/headless entry objects. +map mapAddressBook; +bool gPoolServerRunning = false; +void MainFrameRepaint() {} + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) +{ + if (size < 1 || size > 4096) + return 0; + + try + { + int nHashType = data[0]; + const unsigned char* pbegin = data + 1; + const unsigned char* pend = data + size; + CScript script(pbegin, pend); + + CScript::const_iterator pc = script.begin(); + opcodetype opcode; + vector vchPush; + while (pc < script.end()) + { + if (!script.GetOp(pc, opcode, vchPush)) + break; + } + + script.GetSigOpCount(); + script.ToString(); + + vector vchPubKey; + ExtractPubKey(script, false, vchPubKey); + uint160 hash160; + ExtractHash160(script, hash160); + + CTransaction tx; + tx.vin.push_back(CTxIn(COutPoint(), CScript())); + tx.vout.push_back(CTxOut(0, CScript())); + + vector > stack; + EvalScript(script, tx, 0, nHashType, &stack); + } + catch (...) + { + } + + return 0; +} -- cgit v1.2.3 From dfab2226330ccf5b6529a0e7355e1f574526de94 Mon Sep 17 00:00:00 2001 From: Bitflash Date: Mon, 10 Aug 2026 09:43:27 -0300 Subject: release: bump version to 1.2.16 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Makefile') diff --git a/Makefile b/Makefile index d0f1b26..1d9965a 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ ROOT := $(shell pwd) NPROC := $(shell nproc 2>/dev/null || echo 2) SUDO := $(shell [ "$$(id -u)" = "0" ] && echo "" || echo "sudo") -VERSION := 1.2.15 +VERSION := 1.2.16 SECP256K1_REPO := https://github.com/bitcoin-core/secp256k1 SECP256K1_COMMIT := 7fecac74aed8e1fd9078380d67dd04663705c989 -- cgit v1.2.3 From 0d125b59899258400ad3ffa73e1efb80e9fcf81a Mon Sep 17 00:00:00 2001 From: bitflash Date: Wed, 12 Aug 2026 09:09:03 -0300 Subject: release: bump version to 1.2.17 (hardened audit tooling) --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Makefile') diff --git a/Makefile b/Makefile index 1d9965a..6cea1a8 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ ROOT := $(shell pwd) NPROC := $(shell nproc 2>/dev/null || echo 2) SUDO := $(shell [ "$$(id -u)" = "0" ] && echo "" || echo "sudo") -VERSION := 1.2.16 +VERSION := 1.2.17 SECP256K1_REPO := https://github.com/bitcoin-core/secp256k1 SECP256K1_COMMIT := 7fecac74aed8e1fd9078380d67dd04663705c989 -- cgit v1.2.3 From bc3de301d9ed0e5fb5e2034be2e066d77cf23804 Mon Sep 17 00:00:00 2001 From: bitflash Date: Wed, 12 Aug 2026 10:36:49 -0300 Subject: release: v1.2.18 (Tor/SOCKS5 outbound privacy, poll() socket handler, new app icon) --- Makefile | 2 +- src/rc/bitcoin.ico | Bin 372526 -> 150897 bytes 2 files changed, 1 insertion(+), 1 deletion(-) (limited to 'Makefile') diff --git a/Makefile b/Makefile index 6cea1a8..b4d0cf7 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ ROOT := $(shell pwd) NPROC := $(shell nproc 2>/dev/null || echo 2) SUDO := $(shell [ "$$(id -u)" = "0" ] && echo "" || echo "sudo") -VERSION := 1.2.17 +VERSION := 1.2.18 SECP256K1_REPO := https://github.com/bitcoin-core/secp256k1 SECP256K1_COMMIT := 7fecac74aed8e1fd9078380d67dd04663705c989 diff --git a/src/rc/bitcoin.ico b/src/rc/bitcoin.ico index b768077..33323de 100644 Binary files a/src/rc/bitcoin.ico and b/src/rc/bitcoin.ico differ -- cgit v1.2.3