Skip to content

Commit bce613c

Browse files
authored
Merge pull request #2 from fedimint/om/sdallocx
fix: Android SIGSEGV caused by weak sdallocx symbol in aws-lc-sys
2 parents 5f9acba + bef7590 commit bce613c

5 files changed

Lines changed: 68 additions & 10 deletions

File tree

fedimint-client-uniffi/Cargo.lock

Lines changed: 17 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

fedimint-client-uniffi/Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ path = "uniffi-bindgen.rs"
1919

2020
[dependencies]
2121
anyhow = "1.0.98"
22+
# Pin aws-lc-rs to 1.15.1 / aws-lc-sys to 0.34.0 (same as Fedi).
23+
# aws-lc-sys v0.35.0 introduced a jitter entropy init bug: SIGSEGV on
24+
# aarch64-android via aws_lc_0_35_0_tree_jitter_initialize → pthread_once → [anon:.bss]
25+
aws-lc-rs = { version = "=1.15.1" }
2226
fedimint-client-rpc = { version = "0.10.0" }
2327
fedimint-connectors = { version = "0.10.0" }
2428
fedimint-core = { version = "0.10.0" }
@@ -32,6 +36,7 @@ tokio = "1.48.0"
3236
uniffi = { version = "0.29", features = ["cli"] }
3337

3438
[build-dependencies]
39+
cc = "1"
3540
fedimint-build = { version= "0.10.0" }
3641
uniffi = { version = "0.29", features = ["build"] }
3742

fedimint-client-uniffi/build.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
11
fn main() {
22
fedimint_build::set_code_version();
3+
4+
// On Android, aws-lc declares `sdallocx` as a weak symbol and checks
5+
// `if (sdallocx)` before calling it. Android's linker resolves the GLOB_DAT
6+
// entry for weak undefined symbols to the PLT stub (non-NULL) while the
7+
// JUMP_SLOT remains 0, causing a SIGSEGV. Provide a strong stub that
8+
// delegates to free() so both GOT entries resolve correctly.
9+
let target_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap_or_default();
10+
if target_os == "android" {
11+
cc::Build::new()
12+
.file("sdallocx_stub.c")
13+
.compile("sdallocx_stub");
14+
}
315
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Stub for sdallocx to fix Android weak symbol resolution bug.
2+
//
3+
// aws-lc declares sdallocx as a weak symbol and checks `if (sdallocx)` before
4+
// calling it. On Android's linker, weak undefined symbols can have their
5+
// GLOB_DAT GOT entry resolved to the PLT stub (non-NULL) while the JUMP_SLOT
6+
// still resolves to 0. This causes the NULL check to pass but the actual call
7+
// to jump to address 0 (in .bss) → SIGSEGV "trying to execute non-executable
8+
// memory".
9+
//
10+
// Providing a strong definition of sdallocx that delegates to free() fixes this
11+
// by ensuring both the GOT and PLT entries resolve to a valid function.
12+
13+
#include <stdlib.h>
14+
15+
void sdallocx(void *ptr, size_t size, int flags) {
16+
(void)size;
17+
(void)flags;
18+
free(ptr);
19+
}

fedimint-client-uniffi/src/lib.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,22 @@ use fedimint_client_rpc::{RpcGlobalState, RpcRequest, RpcResponse, RpcResponseHa
44
use fedimint_connectors::ConnectorRegistry;
55
use fedimint_core::db::Database;
66

7+
// Force the linker to pull in our strong sdallocx stub from sdallocx_stub.c.
8+
// On Android, aws-lc declares sdallocx as a weak symbol. The Android linker
9+
// resolves weak GLOB_DAT entries to the PLT stub (non-NULL) while JUMP_SLOT
10+
// stays 0 → SIGSEGV. Our stub provides a strong definition that delegates to free().
11+
#[cfg(target_os = "android")]
12+
extern "C" {
13+
fn sdallocx(ptr: *mut std::ffi::c_void, size: usize, flags: i32);
14+
}
15+
16+
#[cfg(target_os = "android")]
17+
#[used]
18+
static FORCE_SDALLOCX: unsafe extern "C" fn(*mut std::ffi::c_void, usize, i32) = sdallocx;
19+
720
uniffi::setup_scaffolding!();
821

9-
const DB_FILE_NAME: &str = "fedimint.redb";
22+
const DB_DIR_NAME: &str = "fedimint_db";
1023

1124
#[derive(Debug, thiserror::Error, uniffi::Error)]
1225
pub enum FedimintError {
@@ -93,7 +106,7 @@ impl RpcResponseHandler for CallbackWrapper {
93106
async fn create_database(path: &str) -> anyhow::Result<Database> {
94107
tokio::fs::create_dir_all(path).await?;
95108

96-
let db_path = std::path::Path::new(path).join(DB_FILE_NAME);
109+
let db_path = std::path::Path::new(path).join(DB_DIR_NAME);
97110
let db = fedimint_rocksdb::RocksDb::build(db_path).open().await?;
98111

99112
Ok(Database::new(db, Default::default()))

0 commit comments

Comments
 (0)