Description
Starting with Android Oreo (8), Android started using a seccomp based filter approach to syscalls, explicitly allowing syscalls, see https://android-developers.googleblog.com/2017/07/seccomp-filter-in-android-o.html.
https://android.googlesource.com/platform/bionic.git/+/master/libc/SYSCALLS.TXT enumerates the allowed syscalls.
This means, that dispatching a generic syscall mechanism as introduced with this PR #78572 will result in a panic.
On top of that, I found that older versions of Android, such as Android 6, will return Function not implemented (os error 38)
for this syscall.
My tests showed that this only happens on x86, although I can't explain why.
As there's no way to detect the target android API level, the safest way would probably be to always use the accept
syscall, and remove the special handling of the accept4
syscall. This could also be just guarded for x86 -- but would be happy to get an explanation on why it's only on that architecture (see tokio-rs/mio#1446).
I have tested this with both real devices as well as Android emulators.
Code
I tried this code:
use std::net::TcpListener;
let listener = TcpListener::bind("0.0.0.0:8080").unwrap();
match listener.accept() {
Ok((_socket, addr)) => println!("new client: {:?}", addr),
Err(e) => println!("couldn't get client: {:?}", e),
}
and poked it with telnet <android_host> 8080
.
I expected to see this happen: accept
returns Ok(_)
Instead, this happened:
- Android >= 8.0: panic because of seccomp
02-22 13:14:23.287 6015 6041 F my.app.DEBUG: Build fingerprint: 'Android/sdk_phone_x86/generic_x86:10/QPP6.190730.005.B1/5775370:userdebug/test-keys'
02-22 13:14:23.287 6015 6041 F my.app.DEBUG: Revision: '0'
02-22 13:14:23.287 6015 6041 F my.app.DEBUG: ABI: 'x86'
02-22 13:14:23.288 6015 6041 F my.app.DEBUG: Timestamp: 2021-02-22 13:14:23+0000
02-22 13:14:23.288 6015 6041 F my.app.DEBUG: pid: 6015, tid: 6057, name: tokio-runtime-w >>> my.app:background_services <<<
02-22 13:14:23.288 6015 6041 F my.app.DEBUG: uid: 10103
02-22 13:14:23.288 6015 6041 F my.app.DEBUG: signal 31 (SIGSYS), code 1 (SYS_SECCOMP), fault addr --------
02-22 13:14:23.288 6015 6041 F my.app.DEBUG: Cause: seccomp prevented call to disallowed x86 system call 364
02-22 13:14:23.289 6015 6041 F my.app.DEBUG: Abort message: 'Fatal signal 31 (SIGSYS), code 1 (SYS_SECCOMP) in tid 4784 (tokio-runtime-w), pid 4735 (ground_services)'
02-22 13:14:23.289 6015 6041 F my.app.DEBUG: eax 0000016c ebx 0000003f ecx bfccfdb0 edx bfccfd6c
02-22 13:14:23.289 6015 6041 F my.app.DEBUG: edi eae65c34 esi 00080000
02-22 13:14:23.289 6015 6041 F my.app.DEBUG: ebp bfccfd88 esp bfccfd18 eip ee70cad9
- Android < 8.0: strace output
[pid 10918] syscall_364(0x34, 0x9d5c9cf8, 0x9d5c9ca0, 0x80800, 0x9fda9dc8, 0x9fda9dc8 <unfinished ...>
[pid 10918] <... syscall_364 resumed> ) = -1 (errno 38)
Which translate to Function not implemented.
Version it worked on
It most recently worked on: Rust 1.48
Version with regression
rustc --version --verbose
:
rustc --version --verbose
rustc 1.49.0 (e1884a8e3 2020-12-29)
binary: rustc
commit-hash: e1884a8e3c3e813aada8254edfa120e85bf5ffca
commit-date: 2020-12-29
host: x86_64-unknown-linux-gnu
release: 1.49.0
Backtrace
Backtrace
<backtrace>