From 724a487a02e4255d535198e18a6e93b7971cbafb Mon Sep 17 00:00:00 2001 From: Jamil Date: Tue, 13 Feb 2024 22:22:46 -0800 Subject: [PATCH] fix(android): prevent null pointer segfault on 32-bit platforms (#3619) Without this alignment, accessing the `name` field reliably produces a segfault: ``` Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x1d in tid 13835 (Thread-7), pid 13757 (irezone.android) ``` Interestingly, this only happens in release builds on 32-bit platforms. Logging the returned name fixes it too which hints at some kind of optimisation issue. Adding a padding is the most reliable fix. Fixes: #3637. --------- Signed-off-by: Jamil Co-authored-by: Thomas Eizinger --- rust/connlib/tunnel/src/device_channel/tun_android.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/rust/connlib/tunnel/src/device_channel/tun_android.rs b/rust/connlib/tunnel/src/device_channel/tun_android.rs index ec94c326f..6376cb5bf 100644 --- a/rust/connlib/tunnel/src/device_channel/tun_android.rs +++ b/rust/connlib/tunnel/src/device_channel/tun_android.rs @@ -109,7 +109,12 @@ impl ioctl::Request { #[derive(Default)] #[repr(C)] -struct GetInterfaceNamePayload; +struct GetInterfaceNamePayload { + // Fixes a nasty alignment bug on 32-bit architectures on Android. + // The `name` field in `ioctl::Request` is only 16 bytes long and accessing it causes a NPE without this alignment. + // Why? Not sure. It seems to only happen in release mode which hints at an optimisation issue. + alignment: [std::ffi::c_uchar; 16], +} /// Read from the given file descriptor in the buffer. fn read(fd: RawFd, dst: &mut [u8]) -> io::Result {