Skip to content

Accepting Incoming TCP Connections fails on Android #82400

Closed
@wngr

Description

@wngr

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>

Metadata

Metadata

Assignees

No one assigned

    Labels

    O-androidOperating system: AndroidT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-libsRelevant to the library team, which will review and decide on the PR/issue.regression-from-stable-to-stablePerformance or correctness regression from one stable version to another.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions