Skip to content

Add c-lightning module for differential fuzzing - DRAFT#132

Closed
erickcestari wants to merge 1 commit intobitcoinfuzz:v2from
erickcestari:clightning-rebased
Closed

Add c-lightning module for differential fuzzing - DRAFT#132
erickcestari wants to merge 1 commit intobitcoinfuzz:v2from
erickcestari:clightning-rebased

Conversation

@erickcestari
Copy link
Copy Markdown
Member

This commit introduces a c-lightning module to the bitcoinfuzz project, enabling differential fuzzing of lightning invoices.

Key changes:

Module Integration:

  • Add modules/clightning directory with module implementation and wrapper
  • Implement c-lightning library wrapper for invoice parsing

Build System:

  • Update GitHub workflow to include c-lightning module in fuzzing
  • Modify Makefile to handle c-lightning dependencies

Differential Fuzzing:

  • Enhance driver to compare invoice deserialization across implementations
  • Enable detection of discrepancies between c-lightning and other modules

Dependencies:

  • Add c-lightning as a submodule in external/lightning
  • Configure necessary build dependencies

Closes #96

@erickcestari erickcestari force-pushed the clightning-rebased branch 2 times, most recently from 73e158c to 17be704 Compare April 6, 2025 16:22
@yuvicc
Copy link
Copy Markdown
Contributor

yuvicc commented Apr 7, 2025

Concept ACK!

@brunoerg
Copy link
Copy Markdown
Collaborator

brunoerg commented Apr 7, 2025

I tried to build this module and got:

ar libccan.a
ar: creating archive libccan.a
ld ccan/ccan/cdump/tools/cdump-enumstr
ccan/ccan/cdump/tools/cdump-enumstr common/htlc_state.h > common/htlc_state_names_gen.h
wiregen common/status_wiregen.h
Traceback (most recent call last):
  File "/Users/brunogarcia/projects/bitcoinfuzz/external/lightning/tools/generate-wire.py", line 27, in <module>
    from mako.template import Template
ModuleNotFoundError: No module named 'mako'
make[1]: *** [common/status_wiregen.h] Error 1
rm external/build-arm64-apple-darwin23.3.0/libwally-core-build/src/secp256k1/libsecp256k1.la
make: *** [libclightning_wrapper.a] Error 2

@brunoerg
Copy link
Copy Markdown
Collaborator

brunoerg commented Apr 7, 2025

I installed mako and now I get the following error:

ar rc external/build-arm64-apple-darwin23.3.0/libjsmn.a external/build-arm64-apple-darwin23.3.0/jsmn-build/jsmn.o
ar libccan.a
ld ccan/ccan/cdump/tools/cdump-enumstr
ccan/ccan/cdump/tools/cdump-enumstr common/htlc_state.h > common/htlc_state_names_gen.h
cc clightning_lib.c
clightning_lib.c:52:57: error: format specifies type 'long' but the argument has type 'u64' (aka 'unsigned long long') [-Werror,-Wformat]
   52 |         snprintf(amount_str, sizeof(amount_str), "%ld", invoice->msat->millisatoshis);
      |                                                   ~~~   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
      |                                                   %llu
/Library/Developer/CommandLineTools/SDKs/MacOSX14.sdk/usr/include/secure/_stdio.h:57:62: note: expanded from macro 'snprintf'
   57 |   __builtin___snprintf_chk (str, len, 0, __darwin_obsz(str), __VA_ARGS__)
      |                                                              ^~~~~~~~~~~
clightning_lib.c:80:53: error: format specifies type 'long' but the argument has type 'u64' (aka 'unsigned long long') [-Werror,-Wformat]
   80 |     snprintf(expiry_str, sizeof(expiry_str), "%ld", invoice->expiry);
      |                                               ~~~   ^~~~~~~~~~~~~~~
      |                                               %llu
/Library/Developer/CommandLineTools/SDKs/MacOSX14.sdk/usr/include/secure/_stdio.h:57:62: note: expanded from macro 'snprintf'
   57 |   __builtin___snprintf_chk (str, len, 0, __darwin_obsz(str), __VA_ARGS__)
      |                                                              ^~~~~~~~~~~
clightning_lib.c:86:59: error: format specifies type 'long' but the argument has type 'u64' (aka 'unsigned long long') [-Werror,-Wformat]
   86 |     snprintf(timestamp_str, sizeof(timestamp_str), "%ld", invoice->timestamp);
      |                                                     ~~~   ^~~~~~~~~~~~~~~~~~
      |                                                     %llu
/Library/Developer/CommandLineTools/SDKs/MacOSX14.sdk/usr/include/secure/_stdio.h:57:62: note: expanded from macro 'snprintf'
   57 |   __builtin___snprintf_chk (str, len, 0, __darwin_obsz(str), __VA_ARGS__)
      |                                                              ^~~~~~~~~~~
3 errors generated.
make[1]: *** [clightning_lib.o] Error 1
make: *** [libclightning_wrapper.a] Error 2

@erickcestari
Copy link
Copy Markdown
Member Author

Yes, I forgot. Python and the Mako library are required to build c-lightning.

I tried to build this module and got:

ar libccan.a
ar: creating archive libccan.a
ld ccan/ccan/cdump/tools/cdump-enumstr
ccan/ccan/cdump/tools/cdump-enumstr common/htlc_state.h > common/htlc_state_names_gen.h
wiregen common/status_wiregen.h
Traceback (most recent call last):
  File "/Users/brunogarcia/projects/bitcoinfuzz/external/lightning/tools/generate-wire.py", line 27, in <module>
    from mako.template import Template
ModuleNotFoundError: No module named 'mako'
make[1]: *** [common/status_wiregen.h] Error 1
rm external/build-arm64-apple-darwin23.3.0/libwally-core-build/src/secp256k1/libsecp256k1.la
make: *** [libclightning_wrapper.a] Error 2

@erickcestari
Copy link
Copy Markdown
Member Author

ar rc external/build-arm64-apple-darwin23.3.0/libjsmn.a external/build-arm64-apple-darwin23.3.0/jsmn-build/jsmn.o
ar libccan.a
ld ccan/ccan/cdump/tools/cdump-enumstr
ccan/ccan/cdump/tools/cdump-enumstr common/htlc_state.h > common/htlc_state_names_gen.h
cc clightning_lib.c
clightning_lib.c:52:57: error: format specifies type 'long' but the argument has type 'u64' (aka 'unsigned long long') [-Werror,-Wformat]
   52 |         snprintf(amount_str, sizeof(amount_str), "%ld", invoice->msat->millisatoshis);
      |                                                   ~~~   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
      |                                                   %llu
/Library/Developer/CommandLineTools/SDKs/MacOSX14.sdk/usr/include/secure/_stdio.h:57:62: note: expanded from macro 'snprintf'
   57 |   __builtin___snprintf_chk (str, len, 0, __darwin_obsz(str), __VA_ARGS__)
      |                                                              ^~~~~~~~~~~
clightning_lib.c:80:53: error: format specifies type 'long' but the argument has type 'u64' (aka 'unsigned long long') [-Werror,-Wformat]
   80 |     snprintf(expiry_str, sizeof(expiry_str), "%ld", invoice->expiry);
      |                                               ~~~   ^~~~~~~~~~~~~~~
      |                                               %llu
/Library/Developer/CommandLineTools/SDKs/MacOSX14.sdk/usr/include/secure/_stdio.h:57:62: note: expanded from macro 'snprintf'
   57 |   __builtin___snprintf_chk (str, len, 0, __darwin_obsz(str), __VA_ARGS__)
      |                                                              ^~~~~~~~~~~
clightning_lib.c:86:59: error: format specifies type 'long' but the argument has type 'u64' (aka 'unsigned long long') [-Werror,-Wformat]
   86 |     snprintf(timestamp_str, sizeof(timestamp_str), "%ld", invoice->timestamp);
      |                                                     ~~~   ^~~~~~~~~~~~~~~~~~
      |                                                     %llu
/Library/Developer/CommandLineTools/SDKs/MacOSX14.sdk/usr/include/secure/_stdio.h:57:62: note: expanded from macro 'snprintf'
   57 |   __builtin___snprintf_chk (str, len, 0, __darwin_obsz(str), __VA_ARGS__)
      |                                                              ^~~~~~~~~~~
3 errors generated.
make[1]: *** [clightning_lib.o] Error 1
make: *** [libclightning_wrapper.a] Error 2

The issue was fixed by replacing the incorrect %ld format specifiers with "%" PRIu64 (from <inttypes.h>) to properly handle u64 values on both macOS (where it's defined as unsigned long long) and Linux (where it's defined as long unsigned int).

@erickcestari erickcestari requested a review from brunoerg April 7, 2025 19:15
@erickcestari erickcestari force-pushed the clightning-rebased branch 2 times, most recently from 467a530 to 0306c99 Compare April 7, 2025 19:17
Copy link
Copy Markdown
Contributor

@yuvicc yuvicc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested ACK 0306c99

Thanks for the PR

  • Tested on Ubuntu and works file
  • No memory leaks possible

I Will be running the target to see if there's any crash.

Comment on lines +4 to +12
#ifdef __cplusplus
/* C++ specific includes */
#include <cstdint>
extern "C" {
#else
/* C specific includes */
#include <stdint.h>
#include <stdbool.h>
#endif
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is the C++-conditional compilation needed? Shouldn't we always be compiling it one way (either as C or as C++)?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because the header is included in both C and C++ code. extern "C" is required when including C headers in C++ code to prevent name mangling, which ensures the C++ code can link properly to the C-compiled libclightning_wrapper.a library.

return hex;
}

char* clightning_des_invoice(const char* input) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice to use C++ for this.

Is it possible to compile CLN as a library that we link against instead of building this into CLN itself?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The CLN Makefile doesn't build a static library by default. We'll likely need to implement a workaround to generate one. Instead of copying and pasting the entire Makefile, we could simply append custom rules at the end to handle the static library build.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the library approach does end up being cleaner, maybe CLN would accept a patch to their Makefile upstream, so we don't have to append rules here.

CLIGHTNING_OBJS = \
clightning_lib.o

$(LIB_NAME): $(CLIGHTNING_OBJS) libccan.a $(BITCOIN_OBJS) $(COMMON_OBJS) $(WIRE_OBJS) $(EXTERNAL_LIBS)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having a copy-paste of CLN's Makefile with this one addition is kinda ugly, and might break in the future.

It would be nice if we could just link against CLN instead.

This commit introduces a c-lightning module to the bitcoinfuzz project, enabling differential fuzzing of lightning invoices.

Key changes:

Module Integration:
  - Add `modules/clightning` directory with module implementation and wrapper
  - Implement c-lightning library wrapper for invoice parsing

Build System:
  - Update GitHub workflow to include c-lightning module in fuzzing
  - Modify Makefile to handle c-lightning dependencies

Differential Fuzzing:
  - Enhance driver to compare invoice deserialization across implementations
  - Enable detection of discrepancies between c-lightning and other modules

Dependencies:
  - Add c-lightning as a submodule in `external/lightning`
  - Configure necessary build dependencies
@erickcestari erickcestari changed the title Add c-lightning module for differential fuzzing Add c-lightning module for differential fuzzing - DRAFT Apr 10, 2025
@erickcestari erickcestari marked this pull request as draft April 10, 2025 19:09
@erickcestari
Copy link
Copy Markdown
Member Author

Draft due to #149

@brunoerg
Copy link
Copy Markdown
Collaborator

Closing in favor of #149

@brunoerg brunoerg closed this Apr 29, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Lightning Core support to invoice_deserialization target

4 participants