Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions boring-sys/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ rpk = []
# `BORING_BSSL{,_FIPS}_SOURCE_PATH`.
underscore-wildcards = []

# Add a prefix to all symbols in libcrypto and libssl to prevent conflicts
# with other OpenSSL/BoringSSL versions in the same process.
prefix-symbols = []

[build-dependencies]
bindgen = { workspace = true }
cmake = { workspace = true }
Expand Down
3 changes: 3 additions & 0 deletions boring-sys/build/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ pub(crate) struct Features {
pub(crate) fips: bool,
pub(crate) rpk: bool,
pub(crate) underscore_wildcards: bool,
pub(crate) prefix_symbols: bool,
}

pub(crate) struct Env {
Expand Down Expand Up @@ -105,11 +106,13 @@ impl Features {
let fips = env::var_os("CARGO_FEATURE_FIPS").is_some();
let rpk = env::var_os("CARGO_FEATURE_RPK").is_some();
let underscore_wildcards = env::var_os("CARGO_FEATURE_UNDERSCORE_WILDCARDS").is_some();
let prefix_symbols = env::var_os("CARGO_FEATURE_PREFIX_SYMBOLS").is_some();

Self {
fips,
rpk,
underscore_wildcards,
prefix_symbols,
}
}

Expand Down
16 changes: 16 additions & 0 deletions boring-sys/build/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ use std::process::{Command, Output};
use std::sync::OnceLock;

use crate::config::Config;
use crate::prefix::{apply_symbol_prefixes, SymbolPrefixCallbacks};

mod config;
mod prefix;

fn should_use_cmake_cross_compilation(config: &Config) -> bool {
if config.host == config.target {
Expand Down Expand Up @@ -543,6 +545,13 @@ fn built_boring_source_path(config: &Config) -> &PathBuf {
.define("FIPS", "1");
}

// We must enable Position Independent Code to ensure that the
// resulting prefixed symbols remain compatible with the relocatable
// nature of the final Rust test binaries to prevent linker errors
if config.features.prefix_symbols {
cfg.define("CMAKE_POSITION_INDEPENDENT_CODE", "ON");
}

cfg.build_target("ssl").build();
cfg.build_target("crypto").build()
})
Expand Down Expand Up @@ -570,6 +579,9 @@ fn main() {
if !config.env.docs_rs {
emit_link_directives(&config);
}
if config.features.prefix_symbols {
apply_symbol_prefixes(&config);
}
generate_bindings(&config);
}

Expand Down Expand Up @@ -658,6 +670,10 @@ fn generate_bindings(config: &Config) {
.clang_arg("-I")
.clang_arg(include_path.display().to_string());

if config.features.prefix_symbols {
builder = builder.parse_callbacks(Box::new(SymbolPrefixCallbacks));
}

if let Some(sysroot) = &config.env.sysroot {
builder = builder
.clang_arg("--sysroot")
Expand Down
98 changes: 98 additions & 0 deletions boring-sys/build/prefix.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
use crate::{config::Config, run_command};
use std::{fs, io::Write, path::PathBuf, process::Command};

/// Prefix applied to all BoringSSL symbols so they don't collide with OpenSSL.
/// Uses the crate version to generate a dynamic prefix.
const SYMBOL_PREFIX: &str = concat!(
"BSSL_",
env!("CARGO_PKG_VERSION_MAJOR"),
"_",
env!("CARGO_PKG_VERSION_MINOR"),
"_",
env!("CARGO_PKG_VERSION_PATCH"),
);

/// Bindgen callback that rewrites link names to use the prefixed symbol.
///
/// C symbol `SSL_new` → Rust binding `#[link_name = "BSSL_SSL_new"]`.
#[derive(Debug)]
pub struct SymbolPrefixCallbacks;

impl bindgen::callbacks::ParseCallbacks for SymbolPrefixCallbacks {
fn generated_link_name_override(
&self,
item_info: bindgen::callbacks::ItemInfo<'_>,
) -> Option<String> {
Some(format!("{SYMBOL_PREFIX}_{}", item_info.name))
}
}

/// Rewrite all global symbols in libssl.a/libcrypto.a to use the S2N_BSSL_ prefix.
///
/// This runs `nm` to list symbols and `objcopy --redefine-syms` to edit the archives
/// in-place, so they can safely coexist with other {libssl,libcrypto} in the process.
pub fn apply_symbol_prefixes(config: &Config) {
// CMake output directories where libssl.a/libcrypto.a are expected.
let static_lib_dirs = [
config.out_dir.join("build"),
config.out_dir.join("build").join("ssl"),
config.out_dir.join("build").join("crypto"),
];

let static_libs: Vec<PathBuf> = static_lib_dirs
.iter()
.flat_map(|dir| {
["libssl.a", "libcrypto.a"]
.into_iter()
.map(move |file| dir.join(file))
})
.filter(|path| path.exists())
.collect();

if static_libs.is_empty() {
eprintln!("warning: no libssl.a/libcrypto.a archives found to prefix");
return;
}

// 1. Use `nm` to list global symbols in the archives.
let nm_output = run_command(Command::new("nm").args(&static_libs))
.expect("failed to run `nm` on BoringSSL archives");

let mut mappings: Vec<String> = String::from_utf8_lossy(&nm_output.stdout)
.lines()
// Keep only global symbol types we care about.
.filter(|line| {
[" T ", " D ", " B ", " C ", " R ", " W "]
.iter()
.any(|marker| line.contains(marker))
})
// Symbol name is usually the 3rd column.
.filter_map(|line| line.split_whitespace().nth(2).map(str::to_owned))
// Skip leading-underscore internals.
.filter(|sym| !sym.starts_with('_'))
// Compose `old new` mapping line: `sym S2N_BSSL_sym`.
.map(|sym| format!("{sym} {SYMBOL_PREFIX}_{sym}"))
.collect();

mappings.sort();
mappings.dedup();

let mapping_file = config.out_dir.join("redefine_syms.txt");
let mut f = fs::File::create(&mapping_file)
.expect("failed to create redefine_syms.txt for symbol prefixing");

for mapping in &mappings {
writeln!(f, "{mapping}").expect("failed to write symbol mapping");
}
f.flush().expect("failed to flush symbol mapping file");

// 2. Use `objcopy` to apply the mapping to each archive in-place.
for static_lib in &static_libs {
run_command(
Command::new("objcopy")
.arg(format!("--redefine-syms={}", mapping_file.display()))
.arg(static_lib),
)
.expect("failed to run `objcopy` to redefine symbols");
}
}
2 changes: 2 additions & 0 deletions boring/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ rpk = ["boring-sys/rpk"]
# feature set can be provided by setting `BORING_BSSL{,_FIPS}_SOURCE_PATH` and
# `BORING_BSSL{,_FIPS}_ASSUME_PATCHED`.
underscore-wildcards = ["boring-sys/underscore-wildcards"]
# Enable symbol prefixing in the underlying BoringSSL build (for s2n tests).
prefix-symbols = ["boring-sys/prefix-symbols"]

[dependencies]
bitflags = { workspace = true }
Expand Down