ksud: make it compilable for non-android
This commit is contained in:
4
userspace/ksud/Cargo.lock
generated
4
userspace/ksud/Cargo.lock
generated
@@ -1032,9 +1032,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sys-mount"
|
name = "sys-mount"
|
||||||
version = "2.0.1"
|
version = "2.0.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "793d38aa916d55e979587ea7cf551106f5f091e548a91e89ee4f0698bc9cf289"
|
checksum = "d8b080a2fff4d267282506b4d5f2efe0dfa732fb2a5715f30662eed1c4f13390"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"libc",
|
"libc",
|
||||||
|
|||||||
@@ -22,14 +22,16 @@ encoding = "0.2.33"
|
|||||||
retry = "2.0.0"
|
retry = "2.0.0"
|
||||||
humansize = "2.0.0"
|
humansize = "2.0.0"
|
||||||
libc = "0.2"
|
libc = "0.2"
|
||||||
sys-mount = "2.0.1"
|
|
||||||
android-properties = { version = "0.2.2", features = ["bionic-deprecated"] }
|
|
||||||
extattr = "1.0.0"
|
extattr = "1.0.0"
|
||||||
jwalk = "0.8.1"
|
jwalk = "0.8.1"
|
||||||
is_executable = "1.0.1"
|
is_executable = "1.0.1"
|
||||||
nom = "7"
|
nom = "7"
|
||||||
derive-new = "0.5"
|
derive-new = "0.5"
|
||||||
|
|
||||||
|
[target.'cfg(target_os = "android")'.dependencies]
|
||||||
|
sys-mount = "2.0.1"
|
||||||
|
android-properties = { version = "0.2.2", features = ["bionic-deprecated"] }
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
strip = true
|
strip = true
|
||||||
opt-level = "z"
|
opt-level = "z"
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ pub fn get_apk_signature(apk: &str) -> Result<(u32, u32)> {
|
|||||||
|
|
||||||
if u32::from_le_bytes(size4) ^ 0xcafebabeu32 == 0xccfbf1eeu32 {
|
if u32::from_le_bytes(size4) ^ 0xcafebabeu32 == 0xccfbf1eeu32 {
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
println!("warning: comment length is {}", i);
|
println!("warning: comment length is {i}");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +1,21 @@
|
|||||||
use std::{collections::HashMap, path::Path};
|
use std::{collections::HashMap, path::Path};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
assets, defs,
|
assets, defs, mount,
|
||||||
utils::{ensure_clean_dir, ensure_dir_exists, mount_image},
|
utils::{ensure_clean_dir, ensure_dir_exists},
|
||||||
};
|
};
|
||||||
use anyhow::{bail, Context, Result};
|
use anyhow::{bail, Context, Result};
|
||||||
use sys_mount::{FilesystemType, Mount, MountFlags};
|
|
||||||
|
|
||||||
fn mount_partition(partition: &str, lowerdir: &mut Vec<String>) {
|
fn mount_partition(partition: &str, lowerdir: &mut Vec<String>) -> Result<()> {
|
||||||
if lowerdir.is_empty() {
|
if lowerdir.is_empty() {
|
||||||
println!("partition: {partition} lowerdir is empty");
|
println!("partition: {partition} lowerdir is empty");
|
||||||
return;
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
// if /partition is a symlink and linked to /system/partition, then we don't need to overlay it separately
|
// if /partition is a symlink and linked to /system/partition, then we don't need to overlay it separately
|
||||||
if Path::new(&format!("/{}", partition)).read_link().is_ok() {
|
if Path::new(&format!("/{}", partition)).read_link().is_ok() {
|
||||||
println!("partition: {} is a symlink", partition);
|
println!("partition: {} is a symlink", partition);
|
||||||
return;
|
return Ok(());
|
||||||
}
|
}
|
||||||
// add /partition as the lowerest dir
|
// add /partition as the lowerest dir
|
||||||
let lowest_dir = format!("/{partition}");
|
let lowest_dir = format!("/{partition}");
|
||||||
@@ -25,14 +24,7 @@ fn mount_partition(partition: &str, lowerdir: &mut Vec<String>) {
|
|||||||
let lowerdir = lowerdir.join(":");
|
let lowerdir = lowerdir.join(":");
|
||||||
println!("partition: {partition} lowerdir: {lowerdir}");
|
println!("partition: {partition} lowerdir: {lowerdir}");
|
||||||
|
|
||||||
if let Err(err) = Mount::builder()
|
mount::mount_overlay(&lowerdir, &lowest_dir)
|
||||||
.fstype(FilesystemType::from("overlay"))
|
|
||||||
.flags(MountFlags::RDONLY)
|
|
||||||
.data(&format!("lowerdir={lowerdir}"))
|
|
||||||
.mount("overlay", lowest_dir)
|
|
||||||
{
|
|
||||||
println!("mount partition: {partition} overlay failed: {err}");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn do_systemless_mount(module_dir: &str) -> Result<()> {
|
pub fn do_systemless_mount(module_dir: &str) -> Result<()> {
|
||||||
@@ -82,11 +74,11 @@ pub fn do_systemless_mount(module_dir: &str) -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// mount /system first
|
// mount /system first
|
||||||
mount_partition("system", &mut system_lowerdir);
|
let _ = mount_partition("system", &mut system_lowerdir);
|
||||||
|
|
||||||
// mount other partitions
|
// mount other partitions
|
||||||
for (k, mut v) in partition_lowerdir {
|
for (k, mut v) in partition_lowerdir {
|
||||||
mount_partition(&k, &mut v);
|
let _ = mount_partition(&k, &mut v);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -127,7 +119,7 @@ pub fn on_post_data_fs() -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
println!("mount {} to {}", target_update_img, module_dir);
|
println!("mount {} to {}", target_update_img, module_dir);
|
||||||
mount_image(target_update_img, module_dir)?;
|
mount::mount_ext4(target_update_img, module_dir)?;
|
||||||
|
|
||||||
// load sepolicy.rule
|
// load sepolicy.rule
|
||||||
if crate::module::load_sepolicy_rule().is_err() {
|
if crate::module::load_sepolicy_rule().is_err() {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ mod restorecon;
|
|||||||
mod utils;
|
mod utils;
|
||||||
mod sepolicy;
|
mod sepolicy;
|
||||||
mod assets;
|
mod assets;
|
||||||
|
mod mount;
|
||||||
|
|
||||||
fn main() -> anyhow::Result<()> {
|
fn main() -> anyhow::Result<()> {
|
||||||
cli::run()
|
cli::run()
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ use crate::{
|
|||||||
sepolicy,
|
sepolicy,
|
||||||
utils::*,
|
utils::*,
|
||||||
assets,
|
assets,
|
||||||
|
mount,
|
||||||
};
|
};
|
||||||
|
|
||||||
use const_format::concatcp;
|
use const_format::concatcp;
|
||||||
@@ -430,7 +431,7 @@ pub fn install_module(zip: String) -> Result<()> {
|
|||||||
// mount the modules_update.img to mountpoint
|
// mount the modules_update.img to mountpoint
|
||||||
println!("- Mounting image");
|
println!("- Mounting image");
|
||||||
|
|
||||||
mount_image(tmp_module_img, module_update_tmp_dir)?;
|
mount::mount_ext4(tmp_module_img, module_update_tmp_dir)?;
|
||||||
|
|
||||||
setsyscon(module_update_tmp_dir)?;
|
setsyscon(module_update_tmp_dir)?;
|
||||||
|
|
||||||
@@ -457,7 +458,7 @@ pub fn install_module(zip: String) -> Result<()> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// umount the modules_update.img
|
// umount the modules_update.img
|
||||||
let _ = umount_dir(module_update_tmp_dir);
|
let _ = mount::umount_dir(module_update_tmp_dir);
|
||||||
|
|
||||||
// remove modules_update dir, ignore the error
|
// remove modules_update dir, ignore the error
|
||||||
let _ = remove_dir_all(module_update_tmp_dir);
|
let _ = remove_dir_all(module_update_tmp_dir);
|
||||||
@@ -506,13 +507,13 @@ where
|
|||||||
ensure_clean_dir(update_dir)?;
|
ensure_clean_dir(update_dir)?;
|
||||||
|
|
||||||
// mount the modules_update img
|
// mount the modules_update img
|
||||||
mount_image(defs::MODULE_UPDATE_TMP_IMG, update_dir)?;
|
mount::mount_ext4(defs::MODULE_UPDATE_TMP_IMG, update_dir)?;
|
||||||
|
|
||||||
// call the operation func
|
// call the operation func
|
||||||
let result = func(id, update_dir);
|
let result = func(id, update_dir);
|
||||||
|
|
||||||
// umount modules_update.img
|
// umount modules_update.img
|
||||||
let _ = umount_dir(update_dir);
|
let _ = mount::umount_dir(update_dir);
|
||||||
let _ = remove_dir_all(update_dir);
|
let _ = remove_dir_all(update_dir);
|
||||||
|
|
||||||
std::fs::rename(modules_update_tmp_img, defs::MODULE_UPDATE_IMG)?;
|
std::fs::rename(modules_update_tmp_img, defs::MODULE_UPDATE_IMG)?;
|
||||||
|
|||||||
58
userspace/ksud/src/mount.rs
Normal file
58
userspace/ksud/src/mount.rs
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
use anyhow::Result;
|
||||||
|
|
||||||
|
#[cfg(target_os = "android")]
|
||||||
|
use anyhow::{ensure, Context, Ok};
|
||||||
|
#[cfg(target_os = "android")]
|
||||||
|
use retry::delay::NoDelay;
|
||||||
|
#[cfg(target_os = "android")]
|
||||||
|
use sys_mount::{unmount, FilesystemType, Mount, MountFlags, UnmountFlags};
|
||||||
|
|
||||||
|
#[cfg(target_os = "android")]
|
||||||
|
fn do_mount_image(src: &str, target: &str) -> Result<()> {
|
||||||
|
Mount::builder()
|
||||||
|
.fstype(FilesystemType::from("ext4"))
|
||||||
|
.mount(src, target)
|
||||||
|
.with_context(|| format!("Failed to do mount: {src} -> {target}"))?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "android")]
|
||||||
|
pub fn mount_ext4(src: &str, target: &str) -> Result<()> {
|
||||||
|
// umount target first.
|
||||||
|
let _ = umount_dir(target);
|
||||||
|
let result = retry::retry(NoDelay.take(3), || do_mount_image(src, target));
|
||||||
|
ensure!(result.is_ok(), "Failed to mount {} -> {}", src, target);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "android")]
|
||||||
|
pub fn umount_dir(src: &str) -> Result<()> {
|
||||||
|
unmount(src, UnmountFlags::empty()).with_context(|| format!("Failed to umount {src}"))?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "android")]
|
||||||
|
pub fn mount_overlay(lowerdir: &str, mnt: &str) -> Result<()> {
|
||||||
|
Mount::builder()
|
||||||
|
.fstype(FilesystemType::from("overlay"))
|
||||||
|
.flags(MountFlags::RDONLY)
|
||||||
|
.data(&format!("lowerdir={lowerdir}"))
|
||||||
|
.mount("overlay", mnt)
|
||||||
|
.map(|_| ())
|
||||||
|
.map_err(|e| anyhow::anyhow!("mount partition: {mnt} overlay failed: {e}"))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_os = "android"))]
|
||||||
|
pub fn mount_ext4(src: &str, target: &str) -> Result<()> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_os = "android"))]
|
||||||
|
pub fn umount_dir(src: &str) -> Result<()> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_os = "android"))]
|
||||||
|
pub fn mount_overlay(lowerdir: &str, mnt: &str) -> Result<()> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
use anyhow::{Context, Ok, Result};
|
use anyhow::{Context, Ok, Result};
|
||||||
|
#[cfg(target_os = "android")]
|
||||||
use extattr::{setxattr, Flags as XattrFlags};
|
use extattr::{setxattr, Flags as XattrFlags};
|
||||||
use jwalk::{Parallelism::Serial, WalkDir};
|
use jwalk::{Parallelism::Serial, WalkDir};
|
||||||
|
|
||||||
@@ -6,6 +7,7 @@ const SYSTEM_CON: &str = "u:object_r:system_file:s0";
|
|||||||
const _ADB_CON: &str = "u:object_r:adb_data_file:s0";
|
const _ADB_CON: &str = "u:object_r:adb_data_file:s0";
|
||||||
|
|
||||||
pub fn setcon(path: &str, con: &str) -> Result<()> {
|
pub fn setcon(path: &str, con: &str) -> Result<()> {
|
||||||
|
#[cfg(target_os = "android")]
|
||||||
setxattr(path, "security.selinux", con, XattrFlags::empty())
|
setxattr(path, "security.selinux", con, XattrFlags::empty())
|
||||||
.with_context(|| format!("Failed to change SELinux context for {path}"))?;
|
.with_context(|| format!("Failed to change SELinux context for {path}"))?;
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -18,6 +20,7 @@ pub fn setsyscon(path: &str) -> Result<()> {
|
|||||||
pub fn restore_syscon(dir: &str) -> Result<()> {
|
pub fn restore_syscon(dir: &str) -> Result<()> {
|
||||||
for dir_entry in WalkDir::new(dir).parallelism(Serial) {
|
for dir_entry in WalkDir::new(dir).parallelism(Serial) {
|
||||||
if let Some(path) = dir_entry.ok().map(|dir_entry| dir_entry.path()) {
|
if let Some(path) = dir_entry.ok().map(|dir_entry| dir_entry.path()) {
|
||||||
|
#[cfg(target_os = "android")]
|
||||||
setxattr(&path, "security.selinux", SYSTEM_CON, XattrFlags::empty()).with_context(
|
setxattr(&path, "security.selinux", SYSTEM_CON, XattrFlags::empty()).with_context(
|
||||||
|| {
|
|| {
|
||||||
format!(
|
format!(
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ use nom::{
|
|||||||
sequence::Tuple,
|
sequence::Tuple,
|
||||||
IResult, Parser,
|
IResult, Parser,
|
||||||
};
|
};
|
||||||
use std::{vec, path::Path};
|
use std::{path::Path, vec};
|
||||||
|
|
||||||
type SeObject<'a> = Vec<&'a str>;
|
type SeObject<'a> = Vec<&'a str>;
|
||||||
|
|
||||||
@@ -692,6 +692,7 @@ impl From<AtomicStatement> for FfiPolicy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "android")]
|
||||||
fn apply_one_rule<'a>(statement: &'a PolicyStatement<'a>) -> Result<()> {
|
fn apply_one_rule<'a>(statement: &'a PolicyStatement<'a>) -> Result<()> {
|
||||||
let policies: Vec<AtomicStatement> = statement.try_into()?;
|
let policies: Vec<AtomicStatement> = statement.try_into()?;
|
||||||
|
|
||||||
@@ -716,6 +717,11 @@ fn apply_one_rule<'a>(statement: &'a PolicyStatement<'a>) -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_os = "android"))]
|
||||||
|
fn apply_one_rule<'a>(statement: &'a PolicyStatement<'a>) -> Result<()> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn live_patch(policy: &str) -> Result<()> {
|
pub fn live_patch(policy: &str) -> Result<()> {
|
||||||
let result = parse_sepolicy(policy.trim())?;
|
let result = parse_sepolicy(policy.trim())?;
|
||||||
for statement in result {
|
for statement in result {
|
||||||
|
|||||||
@@ -1,33 +1,10 @@
|
|||||||
use anyhow::{bail, ensure, Context, Error, Ok, Result};
|
use anyhow::{bail, Context, Error, Ok, Result};
|
||||||
use retry::delay::NoDelay;
|
|
||||||
use std::{
|
use std::{
|
||||||
fs::{create_dir_all, set_permissions, write, File, Permissions},
|
fs::{create_dir_all, set_permissions, write, File, Permissions},
|
||||||
io::ErrorKind::AlreadyExists,
|
io::ErrorKind::AlreadyExists,
|
||||||
os::unix::prelude::PermissionsExt,
|
os::unix::prelude::PermissionsExt,
|
||||||
path::Path,
|
path::Path,
|
||||||
};
|
};
|
||||||
use sys_mount::{unmount, FilesystemType, Mount, UnmountFlags};
|
|
||||||
|
|
||||||
fn do_mount_image(src: &str, target: &str) -> Result<()> {
|
|
||||||
Mount::builder()
|
|
||||||
.fstype(FilesystemType::from("ext4"))
|
|
||||||
.mount(src, target)
|
|
||||||
.with_context(|| format!("Failed to do mount: {src} -> {target}"))?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn mount_image(src: &str, target: &str) -> Result<()> {
|
|
||||||
// umount target first.
|
|
||||||
let _ = umount_dir(target);
|
|
||||||
let result = retry::retry(NoDelay.take(3), || do_mount_image(src, target));
|
|
||||||
ensure!(result.is_ok(), "Failed to mount {} -> {}", src, target);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn umount_dir(src: &str) -> Result<()> {
|
|
||||||
unmount(src, UnmountFlags::empty()).with_context(|| format!("Failed to umount {src}"))?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn ensure_clean_dir(dir: &str) -> Result<()> {
|
pub fn ensure_clean_dir(dir: &str) -> Result<()> {
|
||||||
let path = Path::new(dir);
|
let path = Path::new(dir);
|
||||||
@@ -83,10 +60,16 @@ pub fn ensure_binary<T: AsRef<Path>>(path: T, contents: &[u8]) -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "android")]
|
||||||
pub fn getprop(prop: &str) -> Option<String> {
|
pub fn getprop(prop: &str) -> Option<String> {
|
||||||
android_properties::getprop(prop).value()
|
android_properties::getprop(prop).value()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_os = "android"))]
|
||||||
|
pub fn getprop(prop: &str) -> Option<String> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn is_safe_mode() -> bool {
|
pub fn is_safe_mode() -> bool {
|
||||||
getprop("persist.sys.safemode")
|
getprop("persist.sys.safemode")
|
||||||
.filter(|prop| prop == "1")
|
.filter(|prop| prop == "1")
|
||||||
|
|||||||
Reference in New Issue
Block a user