8000 Gadget SIGSEGV at startup on 32-bit Android (armeabi-v7a): GumUnwindBroker arm32 activation faults in gum_interceptor_replace() on Bionic · Issue #1124 · frida/frida-gum · GitHub
[go: up one dir, main page]

Skip to content

Gadget SIGSEGV at startup on 32-bit Android (armeabi-v7a): GumUnwindBroker arm32 activation faults in gum_interceptor_replace() on Bionic #1124

Open

Description

@radubogdan2k

Summary

On 32-bit Android (armeabi-v7a, Bionic), the frida-gadget crashes with a SIGSEGV
during its own bootstrap — before any script is loaded — inside the new
GumUnwindBroker arm32 activation path. The same build runs fine on arm64-v8a.
This is a regression introduced by the unwind broker (absent in pre-17.10 builds,
which worked on the same devices).

Environment

  • frida-gum 17.10.0 → current (GumUnwindBroker present); reproduced with a gadget
    built from frida-gum 17.15.x.
  • Mode: Gadget, ABI armeabi-v7a (32-bit ARM).
  • OS: Android 11, Bionic libc, on an embedded Android device.
  • arm64-v8a builds of the exact same frida are unaffected.

Symptom

The gadget faults at init, before running the configured script (no script output at all):

signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x24
Cause: null pointer dereference
r0 00000000 ... r11 00000034
backtrace:
#00 pc 006d3870 .so (single frame, inside the gadget)

r0 == 0 and the faulting access is [r0 + 0x24] — a struct-field deref on a NULL
object, deep in the interceptor replace machinery.

Root cause

gum_interceptor_obtain() now obtains the unwind broker on creation
(guminterceptor.c: interceptor->unwind_broker = gum_unwind_broker_obtain();), and
that runs during gum_init bootstrap. On 32-bit ARM,
_gum_unwind_broker_backend_activate() (the #ifdef HAVE_ARM branch in
gum/backend-linux/gumunwindbroker-linux.c) does, at startup:

if (__gxx_personality_v0 == NULL)
  return;
...
res = gum_interceptor_replace (..., __gxx_personality_v0, ...);
g_assert (res == GUM_REPLACE_OK);

res = gum_interceptor_replace (..., __gnu_Unwind_Find_exidx, ...);   // <-- faults here on Bionic
g_assert (res == GUM_REPLACE_OK);

On Android/Bionic, replacing these EH-ABI routines (__gxx_personality_v0,
__gnu_Unwind_Find_exidx) faults inside gum_interceptor_replace() at install time.
Notes:
- __gnu_Unwind_Find_exidx is a plain extern with no NULL guard (unlike
__gxx_personality_v0, which is weak + guarded).
- Both replaces are followed by g_assert(res == GUM_REPLACE_OK), so any non-OK
result also aborts in-bootstrap.
- arm64-v8a takes the Itanium #else branch and is unaffected — matching the
observed 64-bit-OK / 32-bit-crash split.

Introduced by:
- 3b225881 "Add unwind broker for generated code"
- e5de2a30 "unwind-broker: Support 32-bit ARM EH ABI"

Reproduction

1. Build a frida-gadget for android-arm from frida-gum ≥ 17.10.0.
2. Load it into a 32-bit (armeabi-v7a) app on Android 11/Bionic.
3. Gadget SIGSEGVs at startup before the script runs.

Confirmation / workaround

Early-returning from _gum_unwind_broker_backend_activate() in the HAVE_ARM
branch (skipping the broker activation on arm32) makes the gadget start cleanly,
with all instrumentation working — i.e. it reverts arm32 to pre-17.10 behavior.
So the broker activation is conclusively the trigger.

A proper fix presumably needs the arm32 replace of these Bionic EH-ABI routines to
not fault during init (and/or graceful handling instead of g_assert), but I'm not
sure why gum_interceptor_replace() of __gnu_Unwind_Find_exidx faults on Bionic
specifically — happy to provide a symbolized backtrace / more detail if useful.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      0