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
88 changes: 88 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,12 @@ jobs:
- name: Set Android Linker path
if: endsWith(matrix.thing, '-android')
run: echo "CARGO_TARGET_$(echo ${{ matrix.target }} | tr \\-a-z _A-Z)_LINKER=$ANDROID_NDK/toolchains/llvm/prebuilt/linux-x86_64/bin/$(echo ${{ matrix.target }} | sed s/armv7/armv7a/)21-clang++" >> "$GITHUB_ENV"
# https://github.com/rust-lang/cmake-rs/pull/259 breaks handling of long Windows paths
# https://github.com/cloudflare/boring/issues/414
# https://github.com/0x676e67/boring/commit/efacedb5bf409d0d773e8ce4f5080cb4b4c10f54
- name: Pin some dependencies, temporary patch for cmake breakage
run: |
cargo update --package cmake --precise 0.1.54
- name: Build tests
# We `build` because we want the linker to verify we are cross-compiling correctly for check-only targets.
run: cargo build --target ${{ matrix.target }} --tests ${{ matrix.extra_test_args }}
Expand Down Expand Up @@ -340,3 +346,85 @@ jobs:
token: ${{ secrets.GITHUB_TOKEN }}
prerelease: ${{ contains(github.ref, 'beta') || contains(github.ref, 'rc') }}
generate_release_notes: true

prefix-symbols:
runs-on: ${{ matrix.os }}
strategy:
matrix:
include:
- target: x86_64-unknown-linux-gnu
os: ubuntu-latest
bin: ""
test: true
custom_env: {}
- target: aarch64-unknown-linux-gnu
os: ubuntu-latest
bin: ""
test: false
apt_packages: crossbuild-essential-arm64 binutils-multiarch
custom_env:
CC_aarch64_unknown_linux_gnu: aarch64-linux-gnu-gcc
CXX_aarch64_unknown_linux_gnu: aarch64-linux-gnu-g++
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-g++
- target: armv7-linux-androideabi
os: ubuntu-latest
bin: ndk
test: false
custom_env: {}
- target: aarch64-linux-android
os: ubuntu-latest
bin: ndk
test: false
custom_env: {}
- target: x86_64-linux-android
os: ubuntu-latest
bin: ndk
test: false
custom_env: {}
defaults:
run:
working-directory: test-project
steps:
- name: Checkout repository
uses: actions/checkout@v5
- name: Create test project
working-directory: .
run: |
cargo init test-project
cd test-project
cargo add boring-sys2 --path ../boring-sys/
cargo add openssl-sys -F vendored
echo "fn main() {boring_sys2::init(); openssl_sys::init();}" > src/main.rs
- name: Install Rust toolchain
shell: bash
run: rustup target add ${{ matrix.target }}
- name: Install target-specific APT dependencies
if: matrix.apt_packages != ''
run: sudo apt update && sudo apt install -y ${{ matrix.apt_packages }}
- name: Install cargo-ndk
if: contains(matrix.target, 'android')
run: cargo install cargo-ndk
- name: Build without prefixing
env: ${{ matrix.custom_env }}
shell: bash
run: |
RC=0
cargo ${{ matrix.bin }} build --target ${{ matrix.target }} >logs 2>&1 || RC=$?
if [[ $RC == 0 || (! $(cat logs | grep "lld: error: duplicate symbol") && ! $(cat logs | grep "multiple definition of")) ]]; then
cat logs
echo "Build finished without duplicate symbols: $RC"
exit 1
fi
cat logs
echo "Failed as expected: $RC"
- name: Add prefix-symbols feature
shell: bash
run: cargo add boring-sys2 --path ../boring-sys/ -F prefix-symbols
- name: Build with prefixing
env: ${{ matrix.custom_env }}
shell: bash
run: cargo ${{ matrix.bin }} build --target ${{ matrix.target }}
- name: Check if the is no runtime failures
if: matrix.test == true
shell: bash
run: cargo ${{ matrix.bin }} run --target ${{ matrix.target }}
4 changes: 4 additions & 0 deletions boring-sys/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ fips = []
# `BORING_BSSL{,_FIPS}_SOURCE_PATH`.
underscore-wildcards = []

# 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.
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
19 changes: 19 additions & 0 deletions boring-sys/build/main.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use core::panic;
use fslock::LockFile;
use std::env;
use std::ffi::OsString;
Expand All @@ -9,8 +10,10 @@ use std::process::{Command, Output};
use std::sync::OnceLock;

use crate::config::Config;
use crate::prefix::{prefix_symbols, PrefixCallback};

mod config;
mod prefix;

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

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 @@ -571,6 +578,14 @@ fn main() {
if !config.env.docs_rs {
emit_link_directives(&config);
}
if config.features.prefix_symbols
&& ["macos", "ios", "windows"].contains(&config.target_os.as_str())
{
panic!("The `prefix_symbols` feature is not supported on macOS/iOS or windows targets.");
}
if config.features.prefix_symbols {
prefix_symbols(&config);
}
generate_bindings(&config);
}

Expand Down Expand Up @@ -665,6 +680,10 @@ fn generate_bindings(config: &Config) {
.clang_arg(sysroot.display().to_string());
}

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

let headers = [
"aes.h",
"asn1_mac.h",
Expand Down
89 changes: 89 additions & 0 deletions boring-sys/build/prefix.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
use crate::{config::Config, pick_best_android_ndk_toolchain, run_command};
use std::{fs, io::Write, path::PathBuf, process::Command};

// The prefix to add to all symbols
// Using crate name to avoid collisions with other projects
const PREFIX: &str = env!("CARGO_CRATE_NAME");

// Callback to add a `link_name` macro with the prefix to all generated bindings
#[derive(Debug)]
pub struct PrefixCallback;

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

fn android_toolchain(config: &Config) -> PathBuf {
let mut android_bin_path = config
.env
.android_ndk_home
.clone()
.expect("Please set ANDROID_NDK_HOME for Android build");
android_bin_path.extend(["toolchains", "llvm", "prebuilt"]);
android_bin_path.push(pick_best_android_ndk_toolchain(&android_bin_path).unwrap());
android_bin_path.push("bin");
android_bin_path
}

pub fn prefix_symbols(config: &Config) {
// List static libraries to prefix symbols in
let static_libs: Vec<PathBuf> = [
config.out_dir.join("build"),
config.out_dir.join("build").join("ssl"),
config.out_dir.join("build").join("crypto"),
]
.iter()
.flat_map(|dir| {
["libssl.a", "libcrypto.a"]
.into_iter()
.map(move |file| PathBuf::from(dir).join(file))
})
.filter(|p| p.exists())
.collect();

// Use `nm` to list symbols in these static libraries
let nm = match &*config.target_os {
"android" => android_toolchain(config).join("llvm-nm"),
_ => PathBuf::from("nm"),
};
let out = run_command(Command::new(nm).args(&static_libs)).unwrap();
let mut redefine_syms: Vec<String> = String::from_utf8_lossy(&out.stdout)
.lines()
.filter(|l| {
[" T ", " D ", " B ", " C ", " R ", " W "]
.iter()
.any(|s| l.contains(s))
})
.filter_map(|l| l.split_whitespace().nth(2).map(|s| s.to_string()))
.filter(|l| !l.starts_with("_"))
.map(|l| format!("{l} {PREFIX}_{l}"))
.collect();
redefine_syms.sort();
redefine_syms.dedup();

let redefine_syms_path = config.out_dir.join("redefine_syms.txt");
let mut f = fs::File::create(&redefine_syms_path).unwrap();
for sym in &redefine_syms {
writeln!(f, "{sym}").unwrap();
}
f.flush().unwrap();

// Use `objcopy` to prefix symbols in these static libraries
let objcopy = match &*config.target_os {
"android" => android_toolchain(config).join("llvm-objcopy"),
_ => PathBuf::from("objcopy"),
};
for static_lib in &static_libs {
run_command(
Command::new(&objcopy)
.arg(format!("--redefine-syms={}", redefine_syms_path.display()))
.arg(static_lib),
)
.unwrap();
}
}
3 changes: 2 additions & 1 deletion boring-sys/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ use std::os::raw::{c_char, c_int, c_uint, c_ulong};
clippy::derive_partial_eq_without_eq,
clippy::ptr_offset_with_cast,
unpredictable_function_pointer_comparisons, // TODO: remove Eq/PartialEq in v5
dead_code
dead_code,
unnecessary_transmutes
)]
mod generated {
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
Expand Down
4 changes: 4 additions & 0 deletions boring/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ legacy-compat-deprecated = []
# `BORING_BSSL{,_FIPS}_ASSUME_PATCHED`.
underscore-wildcards = ["boring-sys/underscore-wildcards"]

# 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.
prefix-symbols = ["boring-sys/prefix-symbols"]

[dependencies]
bitflags = { workspace = true }
foreign-types = { workspace = true }
Expand Down
9 changes: 2 additions & 7 deletions quinn-boring/src/version.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::result::Result as StdResult;
/// Governs version-specific behavior in the TLS layer
// TODO: add support for draft version 2.
#[non_exhaustive]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[derive(Clone, Copy, Debug, Eq, PartialEq, Default)]
pub enum QuicVersion {
V1Draft29,
V1Draft30,
Expand All @@ -16,15 +16,10 @@ pub enum QuicVersion {
V1Draft34,

/// First stable RFC version.
#[default]
V1,
}

impl Default for QuicVersion {
fn default() -> Self {
Self::V1
}
}

impl QuicVersion {
const DRAFT_INDICATOR: u32 = 0xff00_0000;
const VERSION_1_DRAFT_29: u32 = Self::DRAFT_INDICATOR | 29;
Expand Down
Loading