Refactor sepolicy.rules resolve native

Co-authored-by: LoveSy <shana@zju.edu.cn>
This commit is contained in:
vvb2060
2023-03-08 14:42:54 +08:00
committed by John Wu
parent 4de93cfd4b
commit 362eea741f
12 changed files with 163 additions and 122 deletions
-3
View File
@@ -83,9 +83,6 @@ int main(int argc, char *argv[]) {
if (name == "magisk"sv)
return magisk_proxy_main(argc, argv);
if (name == "magiskinit"sv && argc == 2 && argv[1] == "--rules-device"sv)
return rust::print_rules_device();
if (getpid() != 1)
return 1;
+6 -4
View File
@@ -57,7 +57,12 @@ public:
class MagiskInit : public BaseInit {
private:
void mount_rules_dir();
dev_t rules_dev = 0;
void parse_config_file();
void patch_sepolicy(const char *in, const char *out);
bool hijack_sepolicy();
void setup_tmp(const char *path);
protected:
#if ENABLE_AVD_HACK
@@ -66,9 +71,6 @@ protected:
bool avd_hack = false;
#endif
void patch_sepolicy(const char *in, const char *out);
bool hijack_sepolicy();
void setup_tmp(const char *path);
void patch_rw_root();
void patch_ro_root();
public:
-75
View File
@@ -1,9 +1,3 @@
use std::env;
use std::path::Path;
pub use base;
use base::libc::{dev_t, makedev};
use base::read_lines;
pub use logging::*;
mod logging;
@@ -12,74 +6,5 @@ mod logging;
pub mod ffi2 {
extern "Rust" {
fn setup_klog();
fn print_rules_device() -> i32;
}
}
pub fn print_rules_device() -> i32 {
const UNKNOWN: i32 = 0;
const PERSIST: i32 = UNKNOWN + 1;
const METADATA: i32 = PERSIST + 1;
const CACHE: i32 = METADATA + 1;
const UNENCRYPTED: i32 = CACHE + 1;
const DATA: i32 = UNENCRYPTED + 1;
const EXISTING: i32 = DATA + 1;
let encrypted = env::var("ISENCRYPTED").map_or(false, |var| var == "true");
let mut matched = UNKNOWN;
let mut rules_dev: dev_t = 0;
if let Ok(lines) = read_lines("/proc/self/mountinfo") {
for line in lines {
if let Ok(line) = line {
let new_matched;
if line.contains("/.magisk/sepolicy.rules ") {
new_matched = EXISTING;
} else if line.contains(" - ext4 ") && !line.contains("/dm-") {
if line.contains(" / /cache ") && matched < CACHE {
new_matched = CACHE;
} else if line.contains(" / /data ") && matched < DATA {
if !encrypted {
new_matched = UNENCRYPTED;
} else if Path::new("/data/unencrypted").is_dir() {
new_matched = DATA;
} else {
continue;
}
} else if line.contains(" / /metadata ") && matched < METADATA {
new_matched = METADATA;
} else if (line.contains(" / /persist ")
|| line.contains(" / /mnt/vendor/persist "))
&& matched < PERSIST
{
new_matched = PERSIST;
} else {
continue;
}
} else {
continue;
}
if let Some(device) = line.splitn(4, ' ').nth(2) {
device.split_once(':').map(|(a, b)| {
a.parse::<i32>().ok().map(|a| {
b.parse::<i32>().ok().map(|b| {
rules_dev = unsafe { makedev(a, b) };
matched = new_matched;
})
})
});
}
}
}
if matched > UNKNOWN {
println!("{rules_dev}");
return 0;
} else {
eprintln!("Failed to find sepolicy rules partition");
}
} else {
eprintln!("Error reading /proc/self/mountinfo");
}
return 1;
}
+26 -22
View File
@@ -2,7 +2,6 @@
#include <sys/mount.h>
#include <sys/sysmacros.h>
#include <libgen.h>
#include <inttypes.h>
#include <base.hpp>
#include <selinux.hpp>
@@ -112,33 +111,38 @@ static void switch_root(const string &path) {
frm_rf(root);
}
void MagiskInit::mount_rules_dir() {
dev_t rules_dev = 0;
parse_prop_file(".backup/.magisk", [&rules_dev](auto key, auto value) -> bool {
if (key == "RULESDEVICE") {
sscanf(value.data(), "%" PRIuPTR, &rules_dev);
return false;
}
return true;
});
static void mount_rules_dir(string path, dev_t rules_dev) {
if (!rules_dev) return;
xmknod(BLOCKDIR "/rules", S_IFBLK | 0600, rules_dev);
xmkdir(MIRRDIR "/rules", 0);
if (xmount(BLOCKDIR "/rules", MIRRDIR "/rules", "ext4", 0, nullptr) == 0) {
string custom_rules_dir = MIRRDIR "/rules";
if (access((custom_rules_dir + "/unencrypted").data(), F_OK) == 0) {
custom_rules_dir += "/unencrypted/magisk";
} else if (access((custom_rules_dir + "/adb").data(), F_OK) == 0) {
custom_rules_dir += "/adb/modules";
} else {
custom_rules_dir += "/magisk";
bool mounted = false;
// first of all, find if rules dev is already mounted
for (auto &info : parse_mount_info("self")) {
if (info.root == "/" && info.device == rules_dev) {
// Already mounted, just bind mount
xmount(info.target.data(), MIRRDIR "/rules", nullptr, MS_BIND, nullptr);
mounted = true;
break;
}
}
if (mounted || mount(BLOCKDIR "/rules", MIRRDIR "/rules", "ext4", MS_RDONLY, nullptr) == 0 ||
mount(BLOCKDIR "/rules", MIRRDIR "/rules", "f2fs", MS_RDONLY, nullptr) == 0) {
string custom_rules_dir = find_rules_dir(MIRRDIR "/rules");
// Create bind mount
xmkdirs(RULESDIR, 0);
xmkdirs(custom_rules_dir.data(), 0700);
LOGD("sepolicy.rules: %s -> %s\n", custom_rules_dir.data(), RULESDIR);
xmount(custom_rules_dir.data(), RULESDIR, nullptr, MS_BIND, nullptr);
if (access(custom_rules_dir.data(), F_OK)) {
LOGW("empty sepolicy.rules: %s\n", custom_rules_dir.data());
} else {
LOGD("sepolicy.rules: %s\n", custom_rules_dir.data());
xmount(custom_rules_dir.data(), RULESDIR, nullptr, MS_BIND, nullptr);
mount_list.emplace_back(path += "/" RULESDIR);
}
xumount2(MIRRDIR "/rules", MNT_DETACH);
} else {
PLOGE("Failed to mount sepolicy.rules %u:%u", major(rules_dev), minor(rules_dev));
unlink(BLOCKDIR "/rules");
}
}
@@ -242,7 +246,7 @@ void MagiskInit::setup_tmp(const char *path) {
xmkdir(BLOCKDIR, 0);
xmkdir(WORKERDIR, 0);
mount_rules_dir();
mount_rules_dir(path, rules_dev);
cp_afc(".backup/.magisk", INTLROOT "/config");
rm_rf(".backup");
+19
View File
@@ -1,5 +1,6 @@
#include <sys/mount.h>
#include <libgen.h>
#include <sys/sysmacros.h>
#include <magisk.hpp>
#include <base.hpp>
@@ -181,11 +182,27 @@ static void extract_files(bool sbin) {
}
}
void MagiskInit::parse_config_file() {
dev_t dev = 0;
parse_prop_file("/data/.backup/.magisk", [&dev](auto key, auto value) -> bool {
if (key == "RULESDEVICE") {
unsigned int dev_major = 0;
unsigned int dev_minor = 0;
sscanf(value.data(), "%u:%u", &dev_major, &dev_minor);
dev = makedev(dev_major, dev_minor);
return false;
}
return true;
});
rules_dev = dev;
}
#define ROOTMIR MIRRDIR "/system_root"
#define NEW_INITRC "/system/etc/init/hw/init.rc"
void MagiskInit::patch_ro_root() {
mount_list.emplace_back("/data");
parse_config_file();
string tmp_dir;
@@ -272,6 +289,8 @@ void RootFSInit::prepare() {
void MagiskInit::patch_rw_root() {
mount_list.emplace_back("/data");
parse_config_file();
// Create hardlink mirror of /sbin to /root
mkdir("/root", 0777);
clone_attr("/sbin", "/root");