From 568ca9e1774846aa4592801054d24989f3f4fd9d Mon Sep 17 00:00:00 2001 From: AXON Date: Sun, 13 Dec 2020 02:48:31 +0600 Subject: [PATCH] Rewriteen most of the stuff. --- Cargo.lock | 73 +++++++++++++++++++- Cargo.toml | 3 +- src/asset/mount | Bin 94732 -> 0 bytes src/main.rs | 172 +++++++++++++++++++++++++++++++----------------- src/utils.rs | 168 ++++++++++++++++++++++++++++++++++------------ 5 files changed, 311 insertions(+), 105 deletions(-) delete mode 100755 src/asset/mount diff --git a/Cargo.lock b/Cargo.lock index 977d198..c09cad6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -18,12 +18,49 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "errno" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa68f2fb9cae9d37c9b2b3584aba698a2e97f72d7aef7b9f7aa71d8b54ce46fe" +dependencies = [ + "errno-dragonfly", + "libc", + "winapi", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14ca354e36190500e1e1fb267c647932382b54053c50b14970856c0b00a35067" +dependencies = [ + "gcc", + "libc", +] + +[[package]] +name = "gcc" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" + [[package]] name = "libc" version = "0.2.81" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb" +[[package]] +name = "loopdev" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac9e35cfb6646d67059f2ca8913a90e6c60633053c103df423975297f33d6fcc" +dependencies = [ + "errno", + "libc", +] + [[package]] name = "nix" version = "0.19.1" @@ -38,7 +75,41 @@ dependencies = [ [[package]] name = "rusty-magisk" -version = "0.1.1" +version = "0.1.2" dependencies = [ "nix", + "sys-mount", ] + +[[package]] +name = "sys-mount" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62f5703caf67c45ad3450104001b4620a605e9def0cef13dde3c9add23f73cee" +dependencies = [ + "bitflags", + "libc", + "loopdev", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/Cargo.toml b/Cargo.toml index cb04f83..071f702 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rusty-magisk" -version = "0.1.1" +version = "0.1.2" authors = ["AXON "] edition = "2018" @@ -8,3 +8,4 @@ edition = "2018" [dependencies] nix = "0.19.1" +sys-mount = "1.2.1" \ No newline at end of file diff --git a/src/asset/mount b/src/asset/mount deleted file mode 100755 index 10166f75f2f97b6111fc1e6d113cf6e1cccff980..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 94732 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 IWw7_Z0V9H~AOHXW diff --git a/src/main.rs b/src/main.rs index 5c0381f..b50af8f 100755 --- a/src/main.rs +++ b/src/main.rs @@ -1,10 +1,10 @@ use std::env::set_var; use std::fs; use std::os::unix::fs::symlink; -use std::path::Path; // For working with files -use std::process::Command; +use std::path::{Path, PathBuf}; +use sys_mount::{unmount, Mount, MountFlags, UnmountFlags}; mod utils; -use utils::{executev, extract_file, mount}; +use utils::{extract_file, remount_root, switch_init}; pub fn job() { // Export some possibly required env vars for magisk @@ -12,12 +12,7 @@ pub fn job() { set_var("ASH_STANDALONE", "1"); // Initialize vars - let init_real = "/init.real"; - let bin_dir = if Path::new("/sbin").exists() { - "/sbin" - } else { - "/system/bin" - }; + let bin_dir = "/sbin"; let superuser_config = "/init.superuser.rc"; let magisk_config = &format!("{}{}", bin_dir, "/.magisk/config"); @@ -34,49 +29,112 @@ pub fn job() { }; //// Initialize bin_dir - if bin_dir != "/sbin" { - for dir in ["/dev/magisk/upper", "/dev/magisk/work"].iter() { - fs::create_dir_all(dir).expect("Error: Failed to setup bin_dir at /dev"); - extract_file("/dev/magisk_bin", magisk_bin_data, 0o755); - Command::new("/dev/magisk_bin") - .args(&["--clone-attr", "/system/bin", "/dev/magisk/upper"]) - .spawn() - .expect("Error: Failed to clone attrs at /dev/magisk/upper"); + if Path::new(bin_dir).exists() { + // When empty + if PathBuf::from(bin_dir) + .read_dir() + .map(|mut i| i.next().is_none()) + .unwrap_or(false) + { + match Mount::new(bin_dir, bin_dir, "tmpfs", MountFlags::empty(), None) { + Ok(_) => {} + Err(why) => { + println!( + "rusty-magisk: Failed to setup tmpfs at {}: {}", + bin_dir, why + ); + switch_init(); + } + } + } else { + // When not empty + remount_root(); + match fs::write(format!("{}/{}", bin_dir, ".rwfs"), "") { + Ok(_) => match fs::remove_file(format!("{}/{}", bin_dir, ".rwfs")) { + Ok(_) => {} + Err(_) => {} + }, + Err(why) => { + println!("rusty-magisk: {} is not writable: {}", bin_dir, why); + switch_init(); + } + } } } else { - // Remount required mountpoints as rw - mount(&[&"-o", "remount,rw", "/"]); - if Path::new(bin_dir).exists() { - mount(&[&"-o", "remount,rw", bin_dir]); + match fs::create_dir(bin_dir) { + Ok(_) => match Mount::new(bin_dir, bin_dir, "tmpfs", MountFlags::empty(), None) { + Ok(_) => {} + Err(why) => { + println!( + "rusty-magisk: Failed to setup tmpfs at {}: {}", + bin_dir, why + ); + switch_init(); + } + }, + Err(why) => { + println!( + "rusty-magisk: Root(/) is not writable, failed to initialize {}: {}", + bin_dir, why + ); + switch_init(); + } + } + } + + // Initialize procfs + if !Path::new("/proc/cpuinfo").exists() { + match Mount::new("/proc", "/proc", "proc", MountFlags::empty(), None) { + Ok(_) => {} + Err(_) => { + println!("rusty-magisk: Failed to initialize procfs"); + switch_init(); + } } } // Create required dirs in bin_dir let mirror_dir = [ + format!("{}{}", bin_dir, "/.magisk/modules"), format!("{}{}", bin_dir, "/.magisk/mirror/data"), format!("{}{}", bin_dir, "/.magisk/mirror/system"), - format!("{}{}", bin_dir, "/.magisk/modules"), - // format!("{}{}", bin_dir, "/.magisk/block"), ]; for dir in mirror_dir.iter() { - fs::create_dir_all(dir).expect(&format!("Failed to create {} dir", dir)); + match fs::create_dir_all(dir) { + Ok(_) => {} + Err(why) => { + println!("rusty-magisk: Failed to create {} dir: {}", dir, why); + } + } } //// Bind data and system mirrors in bin_dir - let mut mirror_count = 1; - for mirror_source in ["/data", "/system"].iter() { - mount(&[&"-o", "bind", mirror_source, &mirror_dir[mirror_count]]); - mirror_count += 1; + let mut mirror_count = 2; + + for mirror_source in ["/system", "/data"].iter() { + match Mount::new( + mirror_source, + &mirror_dir[mirror_count], + "", + MountFlags::BIND, + None, + ) { + Ok(_) => {} + Err(why) => { + eprintln!( + "rusty-magisk: Failed to bind mount {} into {}: {}", + mirror_source, &mirror_dir[mirror_count], why + ); + } + } + mirror_count -= 1; } - // Double remount bin_dir - mount(&[&"-o", "remount,rw", bin_dir]); - /////////////////////////// //// Initialize magisk //// // Extract magisk and set it up - + remount_root(); extract_file(superuser_config, include_bytes!("config/su"), 0o755); extract_file(magisk_config, include_bytes!("config/magisk"), 0o755); extract_file(magisk_bin, magisk_bin_data, 0o755); @@ -87,7 +145,11 @@ pub fn job() { match symlink(magisk_bin, format!("{}/{}", bin_dir, file)) { Ok(_) => {} Err(why) => { - eprintln!("Error: Failed to symlink for {}: {}", file, why); + println!( + "rusty-magisk: Failed to create symlink for {}: {}", + file, why + ); + switch_init(); } } } @@ -103,7 +165,7 @@ pub fn job() { match fs::create_dir_all(dir) { Ok(_) => {} Err(why) => { - eprintln!("Error: Failed to create {} dir: {}", dir, why); + println!("rusty-magisk: Failed to create {} dir: {}", dir, why); } } } @@ -117,39 +179,25 @@ pub fn job() { 0o644, ), Err(why) => { - eprintln!("Error: Failed to create MagiskApkDir dir: {}", why); + println!("rusty-magisk: Failed to create MagiskApkDir dir: {}", why); } } } - for su_bin in ["/system/bin/su", "/system/xbin/su"].iter() { - if Path::new(su_bin).exists() { - match fs::remove_file(su_bin) { - Ok(_) => {} - - Err(why) => { - eprintln!( - "Error: Failed to remove existing {} binary: {}", - su_bin, why - ); - } - } - } - - /* - match symlink("/sbin/su", su_bin) { - Ok(_) => {} - Err(why) => { - eprintln!("Error: Failed to symlink for {}: {}", su_bin, why); - } - } - */ - } - //// Swtitch process to OS init. - if Path::new(init_real).exists() { - executev(&[init_real]); + // Unmount our /proc to ensure real android init doesn't panic + match unmount("/proc", UnmountFlags::DETACH) { + Ok(_) => {} + Err(why) => { + println!( + "rusty-magisk: Failed to detach /proc, trying to switch init anyway: {}", + why + ); + } } + switch_init(); } -fn main() {} +fn main() { + job(); +} diff --git a/src/utils.rs b/src/utils.rs index 4e9646d..ef7be9c 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -3,11 +3,134 @@ use std::ffi::CString; use std::fs; use std::os::unix::fs::PermissionsExt; use std::path::Path; -use std::process::{exit, Command}; // For working with files +use sys_mount::{Mount, MountFlags}; + +pub fn executev(args: &[&str]) { + let args: Vec = args + .iter() + .map(|t| CString::new(*t).expect("rusty-magisk: Not a proper CString")) + .collect(); + unistd::execv(&args[0], &args).expect("rusty-magisk: Failed to complete executev() call"); +} + +pub fn chmod(file: &str, mode: u32) { + match fs::set_permissions(file, fs::Permissions::from_mode(mode)) { + Ok(_) => {} + Err(why) => { + println!( + "rusty-magisk: Failed to chnage file mode to {} for {}: {}", + file, mode, why + ); + switch_init(); + } + } +} + +pub fn extract_file(extern_file: &str, intern_file: &'static [u8], extern_mode: u32) { + match fs::write(extern_file, intern_file) { + Ok(_) => { + chmod(extern_file, extern_mode); + } + Err(why) => { + println!( + "rusty-magisk: Failed to write {} file: {}", + extern_file, why + ); + switch_init(); + } + } +} + +pub fn switch_init() { + let init_real = "/init.real"; + if Path::new(init_real).exists() { + executev(&[init_real]); + } +} + +pub fn remount_root() { + match Mount::new("/", "/", "", MountFlags::REMOUNT, None) { + Ok(_) => {} + Err(_) => {} + } +} + +////// Some unused functions below + +/* +pub fn clone_perms(source: &str, target: &str) -> std::io::Result<()> { + let perms = fs::metadata(source)?.permissions(); + fs::set_permissions(target, perms)?; + Ok(()) +} + +// OverlayFS really cant be mounted once first initrd does either chroot/switch_root into `/android` +// I've wasted many hours over this and had to finally ditch the idea :( +pub fn create_overlay() { + // Transform /system/bin into overlayFS mountpoint + for dir in ["/dev/upper", "/dev/work"].iter() { + fs::create_dir_all(dir).expect("rusty-magisk: Failed to setup bin_dir at /dev"); + } + + clone_perms("/system/bin", "/dev/upper").expect("Failed to clone /android perms"); + + libmount::Overlay::writable( + ["/system/bin"].iter().map(|x| x.as_ref()), + "/dev/upper", + "/dev/work", + "/system/bin", + ) + .mount() + .expect("rusty-magisk: Failed to setup overlayFS at /system/bin"); +} +*/ + +/* +pub fn wipe_old_su() { + for su_bin in ["/system/bin/su", "/system/xbin/su"].iter() { + if Path::new(su_bin).exists() { + match fs::remove_file(su_bin) { + Ok(_) => {} + + Err(why) => { + println!( + "rusty-magisk: Failed to remove existing {} binary: {}", + su_bin, why + ); + } + } + } + + /* + match symlink("/sbin/su", su_bin) { + Ok(_) => {} + Err(why) => { + println!("rusty-magisk: Failed to symlink for {}: {}", su_bin, why); + } + } + */ + } +} +*/ + +/* My noobish deprecieated mount function +pub fn mount(my_args: &[&str]) { + let mount_prog = "/dev/mount_bin"; + + if !Path::new(mount_prog).exists() { + extract_file(mount_prog, include_bytes!("asset/mount"), 0o777) + } + + Command::new(mount_prog) + .args(my_args) + .spawn() + .expect("rusty-magisk: "); +} + +*/ /* use sys_mount::{Mount, MountFlags, SupportedFilesystems}; -use execute::Execute; // For simplifying external command execution. pub fn mount(source_file: &str, target_file: &str) { // Fetch a list of supported file systems. // When mounting, a file system will be selected from this. @@ -22,7 +145,7 @@ pub fn mount(source_file: &str, target_file: &str) { // let mount = _mount.into_unmount_drop(UnmountFlags::DETACH); } Err(why) => { - eprintln!("Error: Failed to mount device: {}", why); + println!("rusty-magisk: Failed to mount device: {}", why); exit(1); } } @@ -46,46 +169,9 @@ pub fn run_externc( if let Some(exit_code) = command.execute().unwrap() { if exit_code != 0 { - eprintln!("{}", err_msg); + println!("{}", err_msg); exit(exit_code); } } } */ - -pub fn executev(args: &[&str]) { - let args: Vec = args - .iter() - .map(|t| CString::new(*t).expect("not a proper CString")) - .collect(); - unistd::execv(&args[0], &args).expect("failed"); -} - -pub fn chmod(file: &str, mode: u32) { - fs::set_permissions(file, fs::Permissions::from_mode(mode)).unwrap(); -} - -pub fn extract_file(extern_file: &str, intern_file: &'static [u8], extern_mode: u32) { - match fs::write(extern_file, intern_file) { - Ok(_) => { - chmod(extern_file, extern_mode); - } - Err(why) => { - eprintln!("Error: Failed to write {} file: {}", extern_file, why); - exit(1); - } - } -} - -pub fn mount(my_args: &[&str]) { - let mount_prog = "/dev/mount"; - - if !Path::new(mount_prog).exists() { - extract_file(mount_prog, include_bytes!("asset/mount"), 0o777) - } - - Command::new(mount_prog) - .args(my_args) - .spawn() - .expect("Error: "); -}