Skip to content

Commit ec0d6eb

Browse files
author
Ludea
committed
android support
1 parent 076cef4 commit ec0d6eb

20 files changed

Lines changed: 215 additions & 88 deletions

File tree

Cargo.lock

Lines changed: 13 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/fspy/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ fspy_seccomp_unotify = { workspace = true, features = ["supervisor"] }
2929
nix = { workspace = true, features = ["uio"] }
3030
tokio = { workspace = true, features = ["bytes"] }
3131

32-
[target.'cfg(all(unix, not(target_env = "musl")))'.dependencies]
33-
fspy_preload_unix = { workspace = true }
32+
#[target.'cfg(all(unix, any(not(target_env = "musl"), not(target_os = "android"))))'.dependencies]
33+
#fspy_preload_unix = { workspace = true }
3434

3535
[target.'cfg(unix)'.dependencies]
3636
fspy_shared_unix = { workspace = true }

crates/fspy/src/artifact.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ macro_rules! artifact {
2828
pub use artifact;
2929

3030
impl Artifact {
31-
#[cfg(not(target_os = "linux"))]
31+
#[cfg(all(not(target_os = "android"), not(target_os = "linux")))]
3232
pub const fn new(name: &'static str, content: &'static [u8], hash: &'static str) -> Self {
3333
Self { name, content, hash }
3434
}

crates/fspy/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
#![cfg_attr(target_os = "windows", feature(windows_process_extensions_main_thread_handle))]
2-
#![feature(once_cell_try)]
2+
#![cfg_attr(not(target_os = "android"), feature(once_cell_try))]
33

44
// Persist the injected DLL/shared library somewhere in the filesystem.
55
// Not needed on musl (seccomp-only tracking).
6-
#[cfg(not(target_env = "musl"))]
6+
#[cfg(all(not(target_os = "android"), not(target_env = "musl")))]
77
mod artifact;
88

99
pub mod error;

crates/fspy/src/unix/mod.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use std::{io, path::Path};
88

99
#[cfg(target_os = "linux")]
1010
use fspy_seccomp_unotify::supervisor::supervise;
11-
#[cfg(not(target_env = "musl"))]
11+
#[cfg(all(not(target_os = "android"), not(target_env = "musl")))]
1212
use fspy_shared::ipc::NativeStr;
1313
use fspy_shared::ipc::{PathAccess, channel::channel};
1414
#[cfg(target_os = "macos")]
@@ -36,20 +36,22 @@ pub struct SpyImpl {
3636
#[cfg(target_os = "macos")]
3737
artifacts: Artifacts,
3838

39-
#[cfg(not(target_env = "musl"))]
39+
#[cfg(all(not(target_os = "android"), not(target_env = "musl")))]
4040
preload_path: Box<NativeStr>,
4141
}
4242

43-
#[cfg(not(target_env = "musl"))]
43+
#[cfg(all(not(target_os = "android"), not(target_env = "musl")))]
4444
const PRELOAD_CDYLIB_BINARY: &[u8] = include_bytes!(env!("CARGO_CDYLIB_FILE_FSPY_PRELOAD_UNIX"));
4545

4646
impl SpyImpl {
4747
/// Initialize the fs access spy by writing the preload library on disk.
4848
///
4949
/// On musl targets, we don't build a preload library —
5050
/// only seccomp-based tracking is used.
51-
pub fn init_in(#[cfg_attr(target_env = "musl", allow(unused))] dir: &Path) -> io::Result<Self> {
52-
#[cfg(not(target_env = "musl"))]
51+
pub fn init_in(
52+
#[cfg_attr(any(target_os = "android", target_env = "musl"), allow(unused))] dir: &Path,
53+
) -> io::Result<Self> {
54+
#[cfg(all(not(target_os = "android"), not(target_env = "musl")))]
5355
let preload_path = {
5456
use const_format::formatcp;
5557
use xxhash_rust::const_xxh3::xxh3_128;
@@ -67,7 +69,7 @@ impl SpyImpl {
6769
};
6870

6971
Ok(Self {
70-
#[cfg(not(target_env = "musl"))]
72+
#[cfg(all(not(target_os = "android"), not(target_env = "musl")))]
7173
preload_path,
7274
#[cfg(target_os = "macos")]
7375
artifacts: {
@@ -98,7 +100,7 @@ impl SpyImpl {
98100
#[cfg(target_os = "macos")]
99101
artifacts: self.artifacts.clone(),
100102

101-
#[cfg(not(target_env = "musl"))]
103+
#[cfg(all(not(target_os = "android"), not(target_env = "musl")))]
102104
preload_path: self.preload_path.clone(),
103105

104106
#[cfg(target_os = "linux")]
Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
// On musl targets, fspy_preload_unix is not needed since we can track accesses via seccomp-only.
22
// Compile as an empty crate to avoid build failures from missing libc symbols.
3-
#![cfg_attr(not(target_env = "musl"), feature(c_variadic))]
3+
#![cfg_attr(not(target_os = "android"), not(target_env = "musl"), feature(c_variadic))]
44

5-
#[cfg(all(unix, not(target_env = "musl")))]
5+
#[cfg(all(target_os = "linux", not(target_env = "musl")))]
66
mod client;
7-
#[cfg(all(unix, not(target_env = "musl")))]
7+
8+
#[cfg(all(target_os = "linux", not(target_env = "musl")))]
89
mod interceptions;
9-
#[cfg(all(unix, not(target_env = "musl")))]
10+
11+
#[cfg(all(target_os = "linux", not(target_env = "musl")))]
1012
mod libc;
11-
#[cfg(all(unix, not(target_env = "musl")))]
13+
14+
#[cfg(all(target_os = "linux", not(target_env = "musl")))]
1215
mod macros;

crates/fspy_seccomp_unotify/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ version = "0.1.0"
44
edition = "2024"
55
publish = false
66

7-
[target.'cfg(target_os = "linux")'.dependencies]
7+
[target.'cfg(any(target_os = "android", target_os = "linux"))'.dependencies]
88
bincode = { workspace = true }
99
libc = { workspace = true }
1010
nix = { workspace = true, features = ["process", "fs", "poll", "socket", "uio"] }

crates/fspy_seccomp_unotify/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#![cfg(target_os = "linux")]
1+
#![cfg(any(target_os = "android", target_os = "linux"))]
22

33
#[cfg(any(feature = "supervisor", feature = "target"))]
44
mod bindings;

crates/fspy_seccomp_unotify/src/target.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use std::{
77
};
88

99
use libc::sock_filter;
10+
#[cfg(not(target_os = "android"))]
1011
use nix::sys::prctl::set_no_new_privs;
1112
use passfd::FdPassingExt;
1213

@@ -19,7 +20,16 @@ use crate::{bindings::install_unotify_filter, payload::SeccompPayload};
1920
/// Returns an error if setting no-new-privs fails, the filter cannot be installed,
2021
/// or the IPC socket communication fails.
2122
pub fn install_target(payload: &SeccompPayload) -> nix::Result<()> {
23+
#[cfg(not(target_os = "android"))]
2224
set_no_new_privs()?;
25+
#[cfg(target_os = "android")]
26+
use libc::{PR_SET_NO_NEW_PRIVS, prctl};
27+
28+
let ret = unsafe { prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) };
29+
if ret != 0 {
30+
return Err(nix::Error::last());
31+
}
32+
2333
let sock_filters =
2434
payload.filter.0.iter().copied().map(sock_filter::from).collect::<Vec<sock_filter>>();
2535
let notify_fd = install_unotify_filter(&sock_filters)?;

crates/fspy_shared/Cargo.toml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,17 @@ bincode = { workspace = true }
1010
bitflags = { workspace = true }
1111
bstr = { workspace = true }
1212
bytemuck = { workspace = true, features = ["must_cast", "derive"] }
13-
shared_memory = { workspace = true, features = ["logging"] }
1413
thiserror = { workspace = true }
1514
tracing = { workspace = true }
1615
uuid = { workspace = true, features = ["v4"] }
1716

17+
[target.'cfg(not(target_os = "android"))'.dependencies]
18+
shared_memory = { workspace = true, features = ["logging"] }
19+
20+
[target.'cfg(target_os = "android")'.dependencies]
21+
memmap2 = "0.9.10"
22+
memfd = "0.6"
23+
1824
[target.'cfg(target_os = "windows")'.dependencies]
1925
bytemuck = { workspace = true }
2026
os_str_bytes = { workspace = true }

0 commit comments

Comments
 (0)