diff --git a/userspace/ksud/Cargo.lock b/userspace/ksud/Cargo.lock index aa625d01..0032ac3a 100644 --- a/userspace/ksud/Cargo.lock +++ b/userspace/ksud/Cargo.lock @@ -59,6 +59,15 @@ dependencies = [ "once_cell", ] +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "anyhow" version = "1.0.68" @@ -111,6 +120,12 @@ dependencies = [ "generic-array", ] +[[package]] +name = "bumpalo" +version = "3.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" + [[package]] name = "byteorder" version = "1.4.3" @@ -162,6 +177,18 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f" +dependencies = [ + "iana-time-zone", + "num-integer", + "num-traits", + "winapi", +] + [[package]] name = "cipher" version = "0.3.0" @@ -219,6 +246,16 @@ dependencies = [ "os_str_bytes", ] +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", +] + [[package]] name = "const_format" version = "0.2.30" @@ -245,6 +282,12 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" +[[package]] +name = "core-foundation-sys" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" + [[package]] name = "cpufeatures" version = "0.2.5" @@ -340,6 +383,50 @@ dependencies = [ "typenum", ] +[[package]] +name = "cxx" +version = "1.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc831ee6a32dd495436e317595e639a587aa9907bef96fe6e6abc290ab6204e9" +dependencies = [ + "cc", + "cxxbridge-flags", + "cxxbridge-macro", + "link-cplusplus", +] + +[[package]] +name = "cxx-build" +version = "1.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94331d54f1b1a8895cd81049f7eaaaef9d05a7dcb4d1fd08bf3ff0806246789d" +dependencies = [ + "cc", + "codespan-reporting", + "once_cell", + "proc-macro2", + "quote", + "scratch", + "syn", +] + +[[package]] +name = "cxxbridge-flags" +version = "1.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48dcd35ba14ca9b40d6e4b4b39961f23d835dbb8eed74565ded361d93e1feb8a" + +[[package]] +name = "cxxbridge-macro" +version = "1.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81bbeb29798b407ccd82a3324ade1a7286e0d29851475990b612670f6f5124d2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "derive-new" version = "0.5.9" @@ -529,6 +616,12 @@ dependencies = [ "libc", ] +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + [[package]] name = "hmac" version = "0.12.1" @@ -553,6 +646,30 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +[[package]] +name = "iana-time-zone" +version = "0.1.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "winapi", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" +dependencies = [ + "cxx", + "cxx-build", +] + [[package]] name = "include-flate" version = "0.1.4" @@ -644,6 +761,15 @@ dependencies = [ "libc", ] +[[package]] +name = "js-sys" +version = "0.3.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730" +dependencies = [ + "wasm-bindgen", +] + [[package]] name = "jwalk" version = "0.8.1" @@ -674,6 +800,7 @@ dependencies = [ "libc", "log", "nom", + "procfs", "regex", "retry", "rust-embed", @@ -738,6 +865,15 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "348108ab3fba42ec82ff6e9564fc4ca0247bdccdc68dd8af9764bbc79c3c8ffb" +[[package]] +name = "link-cplusplus" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5" +dependencies = [ + "cc", +] + [[package]] name = "linux-raw-sys" version = "0.1.4" @@ -804,6 +940,25 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +dependencies = [ + "autocfg", +] + [[package]] name = "num_cpus" version = "1.15.0" @@ -918,6 +1073,21 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "procfs" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1de8dacb0873f77e6aefc6d71e044761fcc68060290f5b1089fcdf84626bb69" +dependencies = [ + "bitflags", + "byteorder", + "chrono", + "flate2", + "hex", + "lazy_static", + "rustix", +] + [[package]] name = "quote" version = "1.0.23" @@ -1087,6 +1257,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "scratch" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddccb15bcce173023b3fedd9436f882a0739b8dfb45e4f6b6002bee5929f61b2" + [[package]] name = "serde" version = "1.0.152" @@ -1280,6 +1456,12 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" +[[package]] +name = "unicode-width" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" + [[package]] name = "unicode-xid" version = "0.2.4" @@ -1315,6 +1497,60 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasm-bindgen" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" + [[package]] name = "winapi" version = "0.3.9" diff --git a/userspace/ksud/Cargo.toml b/userspace/ksud/Cargo.toml index 741d46b3..d9b582d7 100644 --- a/userspace/ksud/Cargo.toml +++ b/userspace/ksud/Cargo.toml @@ -36,6 +36,7 @@ rust-embed = { version = "6.4.2", features = [ sys-mount = "2.0.1" # some android specific dependencies which compiles under unix are also listed here for convenience of coding android-properties = { version = "0.2.2", features = ["bionic-deprecated"] } +procfs = "0.14" [target.'cfg(target_os = "android")'.dependencies] android_logger = "0.12" diff --git a/userspace/ksud/src/event.rs b/userspace/ksud/src/event.rs index 59842446..903ed00e 100644 --- a/userspace/ksud/src/event.rs +++ b/userspace/ksud/src/event.rs @@ -137,11 +137,17 @@ pub fn on_post_data_fs() -> Result<()> { return Ok(()); } + // umount all stock overlayfs and remount them after module mounted + let stock_overlay = mount::StockOverlay::new(); + stock_overlay.umount_all(); + // mount systemless overlay if let Err(e) = mount_systemlessly(module_dir) { warn!("do systemless mount failed: {}", e); } + stock_overlay.mount_all(); + // module mounted, exec modules post-fs-data scripts // todo: Add timeout if let Err(e) = crate::module::exec_common_scripts("post-fs-data.d", true) { diff --git a/userspace/ksud/src/mount.rs b/userspace/ksud/src/mount.rs index b7c62f7f..7d3c4997 100644 --- a/userspace/ksud/src/mount.rs +++ b/userspace/ksud/src/mount.rs @@ -7,6 +7,11 @@ use retry::delay::NoDelay; #[cfg(any(target_os = "linux", target_os = "android"))] use sys_mount::{unmount, FilesystemType, Mount, MountFlags, Unmount, UnmountFlags}; +#[cfg(any(target_os = "linux", target_os = "android"))] +use procfs::process::{MountInfo, Process}; +#[cfg(any(target_os = "linux", target_os = "android"))] +use std::collections::HashSet; + pub struct AutoMountExt4 { mnt: String, #[cfg(any(target_os = "linux", target_os = "android"))] @@ -147,3 +152,103 @@ pub fn umount_dir(_src: &str) -> Result<()> { pub fn mount_overlay(_lowerdir: &str, _mnt: &str) -> Result<()> { unimplemented!() } + +pub struct StockOverlay { + #[cfg(any(target_os = "linux", target_os = "android"))] + mountinfos: Vec, +} + +#[cfg(not(any(target_os = "linux", target_os = "android")))] +impl StockOverlay { + pub fn new() -> Self { + unimplemented!() + } + + pub fn mount_all(&self) { + unimplemented!() + } + + pub fn umount_all(&self) { + unimplemented!() + } +} + +#[cfg(any(target_os = "linux", target_os = "android"))] +impl StockOverlay { + pub fn new() -> Self { + if let std::result::Result::Ok(process) = Process::myself() { + if let std::result::Result::Ok(mountinfos) = process.mountinfo() { + let overlay_mounts = mountinfos + .into_iter() + .filter(|m| m.fs_type == "overlay") + .collect::>(); + return Self { + mountinfos: overlay_mounts, + }; + } + } + Self { mountinfos: vec![] } + } + + pub fn mount_all(&self) { + log::info!("stock overlay: mount all: {:?}", self.mountinfos); + for mount in self.mountinfos.clone() { + let Some(mnt) = mount.mount_point.to_str() else { + log::warn!("Failed to get mount point"); + continue; + }; + + if mnt == "/system" { + log::warn!("stock overlay found /system, skip!"); + continue; + } + + let (_flags, b): (HashSet<_>, HashSet<_>) = mount + .mount_options + .into_iter() + .chain(mount.super_options) + .partition(|&(_, ref m)| m.is_none()); + + let mut overlay_opts = vec![]; + for (opt, val) in b { + if let Some(val) = val { + overlay_opts.push(format!("{}={}", opt, val)); + } else { + log::warn!("opt empty: {}", opt); + } + } + let overlay_data = overlay_opts.join(","); + let result = Mount::builder() + .fstype(FilesystemType::from("overlay")) + .flags(MountFlags::RDONLY) + .data(&overlay_data) + .mount("overlay", mnt); + if let Err(e) = result { + log::error!( + "stock mount overlay: {} failed: {}", + mount.mount_point.display(), + e + ); + } else { + log::info!( + "stock mount :{} overlay_opts: {}", + mount.mount_point.display(), + overlay_opts.join(",") + ); + } + } + } + + pub fn umount_all(&self) { + log::info!("stock overlay: umount all: {:?}", self.mountinfos); + for mnt in &self.mountinfos { + let Some(p) = mnt.mount_point.to_str() else { + log::warn!("Failed to umount: {}", mnt.mount_point.display()); + continue; + }; + + let result = umount_dir(p); + log::info!("stock umount {}: {:?}", p, result); + } + } +}