From 36e86ff2335bb720774e995bfca3d0bc432ade44 Mon Sep 17 00:00:00 2001 From: AXON Date: Fri, 18 Dec 2020 15:14:47 +0600 Subject: [PATCH] Many many improvements. --- Cargo.lock | 75 +++++++++- Cargo.toml | 8 +- src/asset/chmod | Bin 0 -> 36780 bytes src/config/su | 8 +- src/config/su_minimal | 10 ++ src/main.rs | 316 +++++++++++++++++++++++++++++------------- src/utils.rs | 135 ++++++++++++------ 7 files changed, 399 insertions(+), 153 deletions(-) create mode 100644 src/asset/chmod create mode 100644 src/config/su_minimal diff --git a/Cargo.lock b/Cargo.lock index c09cad6..d2a596a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,9 +14,9 @@ checksum = "4c0496836a84f8d0495758516b8621a622beb77c0fed418570e50764093ced48" [[package]] name = "cfg-if" -version = "1.0.0" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" [[package]] name = "errno" @@ -39,6 +39,26 @@ dependencies = [ "libc", ] +[[package]] +name = "error-chain" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d2f06b9cac1506ece98fe3231e3cc9c4410ec3d5b1f24ae1c8946f0742cdefc" +dependencies = [ + "version_check", +] + +[[package]] +name = "faccess" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e039175679baf763ddddf4f76900b92d4dae9411ee88cf42d2f11b976b09e07c" +dependencies = [ + "bitflags", + "libc", + "winapi", +] + [[package]] name = "gcc" version = "0.3.55" @@ -51,6 +71,28 @@ version = "0.2.81" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb" +[[package]] +name = "libmount" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23c4c2ad2d5cbd2f5a05620c3daf45930add53ec207fa99ce5eec971089dc35f" +dependencies = [ + "libc", + "nix", + "quick-error", +] + +[[package]] +name = "likemod" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a62b4c3a11f9aeb844f94662d1a61ba99ce8d37d8fc4dbb3352be29d7094158" +dependencies = [ + "errno", + "error-chain", + "libc", +] + [[package]] name = "loopdev" version = "0.2.1" @@ -63,21 +105,30 @@ dependencies = [ [[package]] name = "nix" -version = "0.19.1" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ccba0cfe4fdf15982d1674c69b1fd80bad427d293849982668dfe454bd61f2" +checksum = "6c722bee1037d430d0f8e687bbdbf222f27cc6e4e68d5caf630857bb2b6dbdce" dependencies = [ "bitflags", "cc", "cfg-if", "libc", + "void", ] +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + [[package]] name = "rusty-magisk" -version = "0.1.2" +version = "0.1.3" dependencies = [ - "nix", + "faccess", + "libmount", + "likemod", "sys-mount", ] @@ -92,6 +143,18 @@ dependencies = [ "loopdev", ] +[[package]] +name = "version_check" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + [[package]] name = "winapi" version = "0.3.9" diff --git a/Cargo.toml b/Cargo.toml index 071f702..31adffa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,11 +1,13 @@ [package] name = "rusty-magisk" -version = "0.1.2" +version = "0.1.3" authors = ["AXON "] edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -nix = "0.19.1" -sys-mount = "1.2.1" \ No newline at end of file +sys-mount = "1.2.1" +likemod = "0.2.0" +libmount = "0.1.15" +faccess = "0.2.3" diff --git a/src/asset/chmod b/src/asset/chmod new file mode 100644 index 0000000000000000000000000000000000000000..5e76548b5858eb3c79a4ca9e9817821d61cee75c GIT binary patch literal 36780 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 literal 0 HcmV?d00001 diff --git a/src/config/su b/src/config/su index dd34fd4..cb74cd2 100644 --- a/src/config/su +++ b/src/config/su @@ -1,14 +1,14 @@ on early-init export PATH /sbin:/bin:/system/bin:/system/xbin:/system/vendor/bin:/gearlock/bin:/apex/com.android.runtime/bin:/apex/com.android.art/bin -service su_daemon /sbin/magisk --daemon +service su_daemon magisk_bin_path --daemon seclabel u:r:su:s0 oneshot on boot start su_daemon - exec u:r:su:s0 -- /sbin/magisk --post-fs-data + exec u:r:su:s0 -- magisk_bin_path --post-fs-data on property:sys.boot_completed=1 - exec u:r:su:s0 -- /sbin/magisk --service - exec u:r:su:s0 -- /sbin/magisk --boot-complete + exec u:r:su:s0 -- magisk_bin_path --service + exec u:r:su:s0 -- magisk_bin_path --boot-complete diff --git a/src/config/su_minimal b/src/config/su_minimal new file mode 100644 index 0000000..44b9357 --- /dev/null +++ b/src/config/su_minimal @@ -0,0 +1,10 @@ +service su_daemon magisk_bin_path --daemon + seclabel u:r:su:s0 + oneshot + +on boot + start su_daemon + +on property:sys.boot_completed=1 + exec u:r:su:s0 -- magisk_bin_path --service + exec u:r:su:s0 -- magisk_bin_path --boot-complete diff --git a/src/main.rs b/src/main.rs index b50af8f..7a8f2ee 100755 --- a/src/main.rs +++ b/src/main.rs @@ -1,97 +1,180 @@ -use std::env::set_var; -use std::fs; -use std::os::unix::fs::symlink; -use std::path::{Path, PathBuf}; -use sys_mount::{unmount, Mount, MountFlags, UnmountFlags}; mod utils; -use utils::{extract_file, remount_root, switch_init}; +use faccess::PathExt; +use libmount; +use std::{env, fs, os::unix::fs::symlink, path::Path, process::Command}; +use sys_mount::{Mount, MountFlags}; +use utils::{ + chmod, clone_perms, dir_is_empty, extract_file, load_modfile, remount_root, switch_init, + wipe_old_su, KernelFsMount, +}; pub fn job() { - // Export some possibly required env vars for magisk - set_var("FIRST_STAGE", "1"); - set_var("ASH_STANDALONE", "1"); + // Initialize procfs + KernelFsMount::proc(); - // Initialize vars + // Check whether we need to setup overlayFS and define bin_dir var + remount_root(); let bin_dir = "/sbin"; + let bin_dir: &str = { + if Path::new("/").writable() || dir_is_empty(bin_dir) { + if !Path::new("/").writable() { + KernelFsMount::dev(); + } + //// Initialize bin_dir at /sbin + if Path::new(bin_dir).exists() { + // When empty + if dir_is_empty(bin_dir) { + 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 { + 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(); + } + } + } - let superuser_config = "/init.superuser.rc"; - let magisk_config = &format!("{}{}", bin_dir, "/.magisk/config"); + // Init variable value + "/sbin" + } else { + // Setup devfs + KernelFsMount::dev(); - let magisk_apk_dir = "/system/priv-app/MagiskSu"; - let magisk_bin = &format!("{}{}", bin_dir, "/magisk"); + // Load overlay kernel modules + let mut kernel_release = match fs::read_to_string("/proc/sys/kernel/osrelease") { + Ok(ok_result) => ok_result, + Err(_) => { + switch_init(); + String::from("") + } + }; - let _magisk_bin_data_x86 = include_bytes!("asset/magisk"); - let _magisk_bin_data_x64 = include_bytes!("asset/magisk64"); - let magisk_bin_data: &'static [u8] = if Path::new("/system/lib64").exists() { - _magisk_bin_data_x64 - } else { - _magisk_bin_data_x86 - }; + kernel_release.pop(); // Remove newline char - //// Initialize bin_dir - 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(); + for module in ["exportfs/exportfs.ko", "overlayfs/overlay.ko"].iter() { + let mod_path = format!( + "/system/lib/modules/{}/kernel/fs/{}", + kernel_release, module + ); + match load_modfile(&mod_path) { + Ok(_) => {} + Err(_) => { + println!("rusty-magisk: Failed to load overlay kernel modules"); + switch_init(); + } } } - } else { - // When not empty - remount_root(); - match fs::write(format!("{}/{}", bin_dir, ".rwfs"), "") { - Ok(_) => match fs::remove_file(format!("{}/{}", bin_dir, ".rwfs")) { + + // Create overlayfs runtime dirs + for dir in ["/dev/upper", "/dev/work"].iter() { + match fs::create_dir_all(dir) { Ok(_) => {} - Err(_) => {} - }, - Err(why) => { - println!("rusty-magisk: {} is not writable: {}", bin_dir, why); - switch_init(); + Err(_) => { + println!("rusty-magisk: Failed to setup devfs for overlay"); + switch_init(); + } } } - } - } else { - 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 - ); + + // Setup overlayfs + clone_perms("/system/bin", "/dev/upper").expect("FUck"); + match libmount::Overlay::writable( + ["/system/bin"].iter().map(|x| x.as_ref()), + "/dev/upper", + "/dev/work", + "/system/bin", + ) + .mount() + { + Ok(_) => { + wipe_old_su(); + extract_file("/dev/chmod", include_bytes!("asset/chmod"), 777); + for dir in ["/system/bin"].iter() { + match Command::new("/dev/chmod").args(&["755", dir]).spawn() { + Ok(_) => if let Ok(_) = fs::remove_file("/dev/chmod") {}, + Err(why) => { + println!( + "rusty-magisk: Failed to chnage modes on {}: {}", + dir, why + ); + } + } + } + } + Err(_) => { + println!("rusty-magisk: Failed to mount overlayfs at /system/bin"); switch_init(); } - }, - Err(why) => { - println!( - "rusty-magisk: Root(/) is not writable, failed to initialize {}: {}", - bin_dir, why - ); - switch_init(); } + + // Init variable value + "/system/bin" } - } + }; - // 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(); - } + // Export some possibly required env vars for magisk + env::set_var("FIRST_STAGE", "1"); + env::set_var("ASH_STANDALONE", "1"); + + // Initialize vars + let superuser_config = "/init.superuser.rc"; + let superuser_config_data: &'static [u8] = { + if Path::new("/").writable() { + include_bytes!("config/su") + } else { + include_bytes!("config/su_minimal") } - } + }; + + let magisk_config = format!("{}/{}", bin_dir, ".magisk/config"); + let magisk_apk_dir = "/system/priv-app/MagiskSu"; + + let magisk_bin = format!("{}/{}", bin_dir, "magisk"); + //let magisk_su_bin = format!("{}/{}", bin_dir, "su"); + let magisk_bin_data: &'static [u8] = { + if Path::new("/system/lib64").exists() { + include_bytes!("asset/magisk64") + } else { + include_bytes!("asset/magisk") + } + }; // Create required dirs in bin_dir let mirror_dir = [ @@ -135,14 +218,48 @@ pub fn job() { //// 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); + + if Path::new("/").writable() { + extract_file(superuser_config, superuser_config_data, 0o750); + } else { + extract_file("/dev/su.rc", superuser_config_data, 0o750); + match libmount::BindMount::new("/dev/su.rc", superuser_config).mount() { + Ok(_) => {} + Err(_) => { + println!("rusty-magisk: Failed to mount superuser_config"); + switch_init(); + } + } + } + + // Update magisk binary path + let new_superuser_config = match fs::read_to_string(superuser_config) { + Ok(ok_result) => ok_result, + Err(_) => { + println!("rusty-magisk: Failed to read new superuser_config"); + switch_init(); + String::from("") + } + }; + match fs::write( + superuser_config, + new_superuser_config.replace("magisk_bin_path", &magisk_bin), + ) { + Ok(_) => {} + Err(_) => { + println!("rusty-magisk: Failed to write new superuser_config"); + switch_init(); + } + } + + // Extract the remaining stuff + extract_file(&magisk_config, include_bytes!("config/magisk"), 0o755); + extract_file(&magisk_bin, magisk_bin_data, 0o755); // Link magisk applets - for file in ["su", "resetprop", "magiskhide"].iter() { + for file in ["su", "resetprop", "magiskhide", "magiskpolicy"].iter() { if !Path::new(&format!("{}/{}", bin_dir, file)).exists() { - match symlink(magisk_bin, format!("{}/{}", bin_dir, file)) { + match symlink(&magisk_bin, format!("{}/{}", bin_dir, file)) { Ok(_) => {} Err(why) => { println!( @@ -158,7 +275,7 @@ pub fn job() { for dir in [ "/data/adb/modules", "/data/adb/post-fs-data.d", - "/data/adb/services.d", + "/data/adb/service.d", ] .iter() { @@ -171,30 +288,31 @@ pub fn job() { } // Install magiskMan into system if missing - if !Path::new(magisk_apk_dir).exists() { - match fs::create_dir_all(magisk_apk_dir) { - Ok(_) => extract_file( - &format!("{}{}", magisk_apk_dir, "/MagiskSu.apk"), - include_bytes!("asset/magisk.apk"), - 0o644, - ), - Err(why) => { - println!("rusty-magisk: Failed to create MagiskApkDir dir: {}", why); + if Path::new("/").writable() { + if !Path::new(magisk_apk_dir).exists() { + match fs::create_dir_all(magisk_apk_dir) { + Ok(_) => { + chmod(magisk_apk_dir, 0o755); + extract_file( + &format!("{}{}", magisk_apk_dir, "/MagiskSu.apk"), + include_bytes!("asset/magisk.apk"), + 0o644, + ); + } + Err(why) => { + println!("rusty-magisk: Failed to create MagiskApkDir dir: {}", why); + } } } + } else { + extract_file( + "/data/magisk.apk", + include_bytes!("asset/magisk.apk"), + 0o755, + ); } //// Swtitch process to OS init. - // 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(); } diff --git a/src/utils.rs b/src/utils.rs index ef7be9c..ff73577 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,16 +1,38 @@ -use nix::unistd; -use std::ffi::CString; -use std::fs; -use std::os::unix::fs::PermissionsExt; -use std::path::Path; -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"); +use likemod::errors; +use std::{ + fs, + os::unix::{fs::PermissionsExt, process::CommandExt}, + path::{Path, PathBuf}, + process::Command, + thread, time, +}; +use sys_mount::{unmount, Mount, MountFlags, UnmountFlags}; + +pub struct KernelFsMount(); +impl KernelFsMount { + pub fn proc() { + 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(); + } + } + } + } + + pub fn dev() { + if dir_is_empty("/dev") { + match Mount::new("/dev", "/dev", "tmpfs", MountFlags::empty(), None) { + Ok(_) => {} + Err(_) => { + println!("rusty-magisk: Failed to setup devfs for overlay"); + switch_init(); + } + } + } + } } pub fn chmod(file: &str, mode: u32) { @@ -44,48 +66,65 @@ pub fn extract_file(extern_file: &str, intern_file: &'static [u8], extern_mode: pub fn switch_init() { let init_real = "/init.real"; if Path::new(init_real).exists() { - executev(&[init_real]); + // Unmount our /proc and /dev to ensure real android init doesn't panic + for fs in ["/dev", "/proc"].iter() { + // Verify fs in not empty before unmounting + if !dir_is_empty(fs) { + match unmount(fs, UnmountFlags::DETACH) { + Ok(_) => {} + Err(why) => { + println!( + "rusty-magisk: Failed to detach {}, trying to switch init anyway: {}", + fs, why + ); + } + } + } + } + Command::new(init_real).exec(); + } else { + println!("rusty-magisk: No init executable found to switch to ... im gonna panniccccc!!!"); + thread::sleep(time::Duration::from_secs(5)); + panic!("Once upon a time there lived ..."); } } pub fn remount_root() { - match Mount::new("/", "/", "", MountFlags::REMOUNT, None) { - Ok(_) => {} - Err(_) => {} + if let Ok(_) = Mount::new("/", "/", "", MountFlags::REMOUNT, None) {} +} + +pub fn dir_is_empty(dir: &str) -> bool { + if Path::new(dir).exists() + && PathBuf::from(dir) + .read_dir() + .map(|mut i| i.next().is_none()) + .unwrap_or(false) + { + true + } else { + false } } -////// Some unused functions below +pub fn load_modfile(modpath: &str) -> errors::Result<()> { + // Get a file descriptor to the kernel module object. + let fmod = std::fs::File::open(Path::new(modpath))?; + + // Assemble module parameters for loading. + let mut params = likemod::ModParams::new(); + params.insert("bus_delay".to_string(), likemod::ModParamValue::Int(5)); + + // Try to load the module. + let loader = likemod::ModLoader::default().set_parameters(params); + loader.load_module_file(&fmod) +} -/* 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() { @@ -111,6 +150,20 @@ pub fn wipe_old_su() { */ } } + +////// Some unused rusty functions below + +/* + +pub fn sbin_mode() -> bool { + if env::var("ANDROID_BOOTLOGO").is_err() { + true + } else { + false + } +} + + */ /* My noobish deprecieated mount function