Add symbol prefixing feature for BoringSSL#401
Add symbol prefixing feature for BoringSSL#401BarbossHack wants to merge 1 commit intocloudflare:masterfrom
Conversation
|
This PR would help resolve #197. Would it be possible for a maintainer to take a look or assign a reviewer? Thank you! |
|
I don’t think Cloudflare will review it because this patch doesn’t support Windows or macOS yet. But I’m working on it (or at least trying to). |
|
I don't expect to use this internally at Cloudflare, since we have pretty strict requirements about which libraries we use, and even if symbols don't collide, we can't end up with random copies of openssl. I don't mind if this is unix-only. However, I am concerned about reliability. What are the failure modes here? If it fails to rename some symbols, does the result fail to link, or is there a risk of mixing symbols between libraries? |
668b208 to
a8cd92f
Compare
a8cd92f to
317c09a
Compare
Perfect, then I will focus on linux and android for this PR. I’ve added a check (panic!) to disable this feature on macOS, iOS, and Windows for now, since it doesn’t work on those targets yet. If the PR is merged, I’ll open a follow-up PR for those platforms later.
I’ve added a GitHub Action to verify that the On macOS, the linker (ld64) allows duplicate symbols in static libraries by default, simply picking one of the definitions to include. So the link will succeed. However, this can lead to a runtime failure with a “segmentation fault”, which is what happened in my experiments. Linux and Android linkers are strict about multiple definitions in the same executable. If two objects define the same symbol and are linked statically, the link will fail with duplicate symbol errors. So, if my symbol prefixing misses some symbols (not detected by |
Goal
Add a prefix to all symbols in libcrypto and libssl to prevent conflicts with other OpenSSL or BoringSSL versions that might be linked in the same process.
Why?
When statically linking both OpenSSL and BoringSSL in the same project, we encountered duplicate symbols, for example:
How?
The first approach was to use the BoringSSL-provided Go script
make_prefix_headers.go. It mostly worked, but:read_symbols.go, then to generateboringssl_prefix_symbols.hwithmake_prefix_headers.go, and finally rebuild again the static libraries with this header. (We could have prebuilt it like gRPC does, but I preferred a fully automated workflow.)boringssl_prefix_symbols.h), which I ended up fixing with the Binutilsobjcopytool, not very straightforward.Therefore, I decided to use only the Binutils tools
nmandobjcopyto fully automate the symbol prefixing.Steps (build.rs):
libssl.aandlibcrypto.a).nmto list all exported symbols in these static libraries.objcopyto prefix all symbols.bindings.rs) with#[link_name]where necessary.Cross-compilation
Currently, this workflow is tested for Linux and Android only.
For Android, the target-specific
nmandobjcopyfrom the NDK are used.macOS/iOS and Windows toolchains are not tested. I currently don’t have access to a macOS environment and have limited experience with Windows toolchains.
Usage
I've added an opt-in feature
prefix-symbols, as it is not tested on macOS/iOS/Windows yet.