Skip to content

fix: Android SIGSEGV caused by weak sdallocx symbol in aws-lc-sys#2

Merged
MrImmortal09 merged 1 commit intomainfrom
om/sdallocx
Mar 8, 2026
Merged

fix: Android SIGSEGV caused by weak sdallocx symbol in aws-lc-sys#2
MrImmortal09 merged 1 commit intomainfrom
om/sdallocx

Conversation

@MrImmortal09
Copy link
Copy Markdown
Member

Problem

On Android, the app crashes with SIGSEGV (signal 11, "trying to execute non-executable memory") during federation join. The crash occurs inside aws_lc_sys during jitter entropy initialization:

OPENSSL_free → sdallocx → [anon:.bss] (address 0x0)

Root cause: aws-lc-sys declares sdallocx (a jemalloc deallocator) as a weak symbol and guards calls with if (sdallocx). On Android's Bionic linker, weak undefined symbols have a split resolution:

  • GLOB_DAT (used for the if check) → resolves to the PLT stub address (non-NULL)
  • JUMP_SLOT (used for the actual call) → resolves to 0

So the null check passes, but the call jumps to address 0 in .bss — crash.

Fix

  1. sdallocx_stub.c — Provides strong definitions of sdallocx, sallocx, and nallocx that delegate to standard free()/malloc(), ensuring both GOT entries resolve to valid function addresses.

  2. build.rs — Conditionally compiles the stub via the cc crate when target_os == "android".

  3. lib.rs — References sdallocx via extern "C" + #[used] static to force the linker to include the strong symbol.

  4. Cargo.toml — Pins aws-lc-rs to =1.15.1 (aws-lc-sys v0.34.0) to avoid a separate cmake bug in v0.35.0 that adds -DCMAKE_OSX_ARCHITECTURES for Android targets on macOS hosts.

Also switched the database path constant from fedimint.redb to fedimint_db to match the RocksDB directory-based storage.

Verified

  • Physical device (RMX3312, Android 15, arm64-v8a)
  • Emulator (x86_64)

@MrImmortal09 MrImmortal09 merged commit bce613c into main Mar 8, 2026
4 checks passed
@MrImmortal09
Copy link
Copy Markdown
Member Author

Ref:

1. BoringSSL (and forks like AWS-LC)

The root cause of this hack originates directly in BoringSSL (Google's OpenSSL fork, which aws-lc is based on). BoringSSL itself includes a weak symbol fallback for sdallocx in its memory allocation code (crypto/mem.c):

// BoringSSL's crypto/mem.c
void sdallocx(void *ptr, size_t size, int flags);

__attribute((weak, noinline))
void sdallocx(void *ptr, size_t size, int flags) {
  free(ptr);
}

Projects that consume BoringSSL/AWS-LC on Android often run into the aforementioned linker bug and have to override it with a strong symbol in their own codebase, exactly as Fedimint did.

2. React Native (via Meta's folly library)

Meta's C++ library, folly (used extensively in React Native for Android), explicitly handles sdallocx and other jemalloc functions as weak symbols. To prevent Android crash issues, the React Native Android build process and folly's memory detail headers do similar manipulations to ensure memory functions safely resolve:

// ReactAndroid/build/third-party-ndk/folly/folly/detail/Malloc.h
#if FOLLY_HAVE_WEAK_SYMBOLS
void sdallocx(void*, size_t, int) __attribute__((__weak__));

3. Telegram (Android App)

The open-source Android app for Telegram includes BoringSSL in its JNI (Java Native Interface) layer (TMessagesProj/jni/boringssl/crypto/mem.c). They maintain the same weak-symbol fallbacks to keep their cryptography library from crashing on older Android devices.

4. TCMalloc / Jemalloc Overrides

Several database and high-performance projects that swap out standard memory allocators (like Memgraph or Datadog profiling tools) define strong overrides for sdallocx. While their goal is usually performance rather than fixing a linker bug, they use the exact same signature mapping trick to intercept and safely route the memory deallocation:

// memgraph/memgraph
extern "C" void sdallocx(void *ptr, size_t size, int flags) {
  if (!ptr) [[unlikely]] return;
  free_tracking(ptr, flags);
  je_sdallocx(ptr, size, flags);
}

In short, any cross-platform C/Rust project that heavily utilizes cryptography (BoringSSL/AWS-LC) or highly optimized allocators (Jemalloc) and targets Android has likely implemented this specific strong-symbol sdallocx workaround to bypass Android's legacy dynamic linker bugs.

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.

1 participant