Skip to content

fix: Static-link OpenSSL in secp256r1 to prevent symbol leaking#308

Merged
usmansaleem merged 2 commits intobesu-eth:mainfrom
usmansaleem:static-openssl-secp256r1
Mar 20, 2026
Merged

fix: Static-link OpenSSL in secp256r1 to prevent symbol leaking#308
usmansaleem merged 2 commits intobesu-eth:mainfrom
usmansaleem:static-openssl-secp256r1

Conversation

@usmansaleem
Copy link
Copy Markdown
Contributor

Summary

  • Static-link OpenSSL (libcrypto.a) into libbesu_native_ec.so/.dylib with symbol hiding, exporting only p256_* functions
  • Remove the separate libbesu_native_ec_crypto shared library that previously leaked all OpenSSL symbols into the JVM process
  • This prevents symbol conflicts with other native libraries (e.g. SoftHSM2, cloud HSM PKCS#11 clients) that depend on system OpenSSL

Changes

  • secp256r1/besu-native-ec submodule updated to Consensys/besu-native-ec@062fb79 (static OpenSSL linking with version script / exported_symbols_list)
  • build.sh — Build OpenSSL with no-shared -fPIC -fvisibility=hidden, target libcrypto.a
  • BesuNativeEC.java — Remove besu_native_ec_crypto library loading
  • secp256r1/build.gradle — Remove libbesu_native_ec_crypto from all platform copy tasks
  • .github/workflows/build.yml, native-build.sh, README.md — Remove patchelf dependency

Verification

After building, confirm no OpenSSL symbols leak:

nm -D release/libbesu_native_ec.so | grep " T.*EVP_\| T.*EC_\| T.*ossl_"
# Should return nothing

nm -D release/libbesu_native_ec.so | grep " T "
# Should show only: p256_key_recovery, p256_sign, p256_verify, p256_verify_malleable_signature

Test plan

  • CI native builds pass on all platforms (linux-x86-64, linux-arm64, macos-x86-64, macos-arm64)
  • ./gradlew :secp256r1:test passes
  • Verify no OpenSSL symbols exported from libbesu_native_ec

…JVM process

Previously, libcrypto.so.3 was copied and renamed to
libbesu_native_ec_crypto.so, exporting all OpenSSL symbols globally.
When loaded into the JVM, these symbols contaminated the global symbol
table, causing conflicts with other native libraries that depend on
system OpenSSL (e.g. SoftHSM2 for PKCS#11 HSM plugins).

Changes:
- Update besu-native-ec submodule to static OpenSSL build with symbol
  hiding (exports only p256_* functions)
- Build OpenSSL as static library (libcrypto.a) with no-shared, -fPIC,
  and -fvisibility=hidden
- Remove separate libbesu_native_ec_crypto shared library loading
- Remove libbesu_native_ec_crypto from all Gradle copy tasks
- Remove patchelf dependency (no longer needed)

Signed-off-by: Usman Saleem <usman@usmans.info>
@usmansaleem usmansaleem force-pushed the static-openssl-secp256r1 branch from 0edfc6a to e7c878c Compare March 19, 2026 16:51
The macos-15-intel runner has llvm@18 pre-installed which places an
x86_64-only libunwind.dylib in /usr/local/lib/. When Rust cross-compiles
for aarch64-apple-darwin (to create universal binaries via lipo), the
linker finds this library, ignores it due to architecture mismatch, and
then fails with undefined _Unwind_* symbols.

Unlinking llvm@18 removes its symlinks from /usr/local/lib/, allowing
the linker to fall back to the system libunwind which supports all
architectures.

Signed-off-by: Usman Saleem <usman@usmans.info>
@usmansaleem usmansaleem requested a review from Copilot March 19, 2026 17:54
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the secp256r1 native build to static-link OpenSSL into libbesu_native_ec with symbol hiding, eliminating the separate crypto shared library to prevent OpenSSL symbol leakage into the JVM process.

Changes:

  • Stop loading/copying libbesu_native_ec_crypto and rely on a single libbesu_native_ec artifact.
  • Update native build scripts and CI deps to drop patchelf and build OpenSSL as a static libcrypto.a.
  • Bump the secp256r1/besu-native-ec submodule to a commit that implements symbol-hiding/static OpenSSL linking.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
secp256r1/src/main/java/org/hyperledger/besu/nativelib/secp256r1/besuNativeEC/BesuNativeEC.java Removes loading of the separate crypto JNI/JNA library.
secp256r1/build.gradle Stops copying the libbesu_native_ec_crypto artifacts into resources.
secp256r1/besu-native-ec Updates submodule to version that performs static OpenSSL linking/symbol hiding.
native-build.sh Removes patchelf from native build container dependencies.
build.sh Builds OpenSSL as static libcrypto.a and removes checks for the removed crypto dylib.
README.md Updates Linux dependency list to remove patchelf.
CHANGELOG.md Adds an Unreleased entry describing the OpenSSL static-linking fix.
.github/workflows/build.yml Removes patchelf from CI deps; adds a step to unlink Homebrew LLVM.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown

@jframe jframe left a comment

Choose a reason for hiding this comment

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

LGTM

@usmansaleem usmansaleem merged commit c1bd615 into besu-eth:main Mar 20, 2026
14 of 15 checks passed
@usmansaleem usmansaleem deleted the static-openssl-secp256r1 branch March 20, 2026 05:38
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.

3 participants