Skip to content

Commit

Permalink
add target for addrv2
Browse files Browse the repository at this point in the history
  • Loading branch information
brunoerg committed Jun 25, 2024
1 parent e62d377 commit 976b5fd
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 3 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
CXX = clang++
CC = clang
SOURCES := targets/script.cpp targets/psbt.cpp targets/bech32.cpp targets/tx_des.cpp targets/miniscript_string.cpp targets/block_des.cpp targets/prefilledtransaction.cpp
SOURCES := targets/addrv2.cpp targets/script.cpp targets/psbt.cpp targets/bech32.cpp targets/tx_des.cpp targets/miniscript_string.cpp targets/block_des.cpp targets/prefilledtransaction.cpp
INCLUDES = dependencies/ dependencies/bitcoin/src/ dependencies/bitcoin/src/secp256k1/include
LIB_DIR = dependencies/bitcoin/src/ dependencies/bitcoin/src/.libs dependencies/bitcoin/src/secp256k1/.libs rust_bitcoin_lib/target/debug btcd_lib
OBJS := $(patsubst %.cpp, build/%.o, $(SOURCES))
Expand Down
20 changes: 20 additions & 0 deletions btcd_lib/wrapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ package main

import "C"
import (
"bytes"
"unsafe"

"github.com/btcsuite/btcd/blockchain"
"github.com/btcsuite/btcd/btcutil"
"github.com/btcsuite/btcd/btcutil/bech32"
"github.com/btcsuite/btcd/wire"
)

//export go_btcd_des_block
Expand Down Expand Up @@ -50,6 +52,24 @@ func go_btcd_bech32(cinput *C.uchar, len C.int) *C.char {
return C.CString("")
}

//export go_btcd_addrv2
func go_btcd_addrv2(cinput *C.uchar, datalen C.int, count *C.ulonglong) bool {
data := C.GoBytes(unsafe.Pointer(cinput), datalen)
r := bytes.NewReader(data)
m := &wire.MsgAddrV2{}
err := m.BtcDecode(r, 0, 0)

actual_count := 0
for i := 0; i < len(m.AddrList); i++ {
if m.AddrList[i].Addr != nil {
actual_count++
}
}
*count = C.ulonglong(actual_count)

return err == nil
}

func main() {

}
3 changes: 3 additions & 0 deletions fuzzer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "targets/bech32.h"
#include "targets/psbt.h"
#include "targets/script.h"
#include "targets/addrv2.h"

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
FuzzedDataProvider provider(data, size);
Expand All @@ -34,6 +35,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
Psbt(provider);
} else if (target == "script") {
Script(provider);
} else if (target == "addrv2") {
Addrv2(provider);
}

return 0; // Values other than 0 and -1 are reserved for future use.
Expand Down
5 changes: 3 additions & 2 deletions rust_bitcoin_lib/rust_bitcoin_lib.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
#include <string>

extern bool rust_miniscript_from_str(const char* miniscript_str);
extern bool rust_bitcoin_script(const char* miniscript_str);
extern char* rust_bitcoin_psbt(const char* miniscript_str);
extern bool rust_bitcoin_script(const uint8_t *data, size_t len);
extern char* rust_bitcoin_psbt(const uint8_t *data, size_t len);
extern char* rust_miniscript_from_str_check_key(const char* miniscript_str);
extern char* rust_bitcoin_des_block(const uint8_t *data, size_t len);
extern char* rust_bitcoin_prefilledtransaction(const uint8_t *data, size_t len);
extern bool rust_bitcoin_addrv2(uint8_t *data, size_t len, uint64_t *count);
17 changes: 17 additions & 0 deletions rust_bitcoin_lib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,23 @@ pub unsafe extern "C" fn rust_bitcoin_script(data: *const u8, len: usize) -> boo
}
}

#[no_mangle]
pub unsafe extern "C" fn rust_bitcoin_addrv2(data: *const u8, len: usize, actual_count: *mut u64) -> bool {
// Safety: Ensure that the data pointer is valid for the given length
let data_slice = slice::from_raw_parts(data, len);

let addr: Result<(Vec<bitcoin::p2p::address::AddrV2Message>, usize), _> = encode::deserialize_partial(data_slice);
match addr {
Err(_) => {
false
},
Ok(vec_addr) => {
*actual_count = vec_addr.0.len() as u64;
return true
}
}
}

#[no_mangle]
pub unsafe extern "C" fn rust_miniscript_from_str_check_key(input: *const c_char) -> *mut c_char {
let Ok(desc) = c_str_to_str(input) else {
Expand Down
49 changes: 49 additions & 0 deletions targets/addrv2.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#include <fuzzer/FuzzedDataProvider.h>
#include <string>
#include <iostream>
#include <optional>
#include <stdio.h>

#include "addrv2.h"
#include "bitcoin/src/protocol.h"
#include "bitcoin/src/streams.h"

extern "C" bool rust_bitcoin_addrv2(uint8_t *data, size_t len, uint64_t *count);
extern "C" bool go_btcd_addrv2(uint8_t *data, size_t len, uint64_t *count);

std::optional<uint64_t> Core(Span<const uint8_t> buffer)
{
std::vector<CAddress> addrs;
DataStream ds{buffer};
try {
ds >> CAddress::V2_NETWORK(addrs);
if (addrs.size() > 1000) return false;
for (auto& addr : addrs) if (!addr.IsValid()) return false;
} catch (const std::ios_base::failure&) {
return false;
}

return addrs.size();
}

void Addrv2(FuzzedDataProvider& provider)
{
std::vector<uint8_t> buffer{provider.ConsumeRemainingBytes<uint8_t>()};
uint64_t count_rust = 0, count_btcd = 0;
bool rust_bitcoin{rust_bitcoin_addrv2(buffer.data(), buffer.size(), &count_rust)};
bool btcd{go_btcd_addrv2(buffer.data(), buffer.size(), &count_btcd)};
std::optional<uint64_t> core{Core(buffer)};

if (core.has_value() && *core > 0) {
assert(rust_bitcoin);
assert(btcd);
assert(*core == count_rust);
// btcd excludes i2p and cjdns
assert(*core >= count_btcd);
}

if (!core.has_value()) {
assert(!rust_bitcoin);
assert(!btcd);
}
}
7 changes: 7 additions & 0 deletions targets/addrv2.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#ifndef NET_ADDRESS_H
#define NET_ADDRESS_H

#include <fuzzer/FuzzedDataProvider.h>

void Addrv2(FuzzedDataProvider& provider);
#endif

0 comments on commit 976b5fd

Please sign in to comment.