Rename rules to preinit

It is possible that we will allow more preinit files for modules.
Rename the partition and folders from rules to preinit.
This commit is contained in:
topjohnwu
2023-03-16 04:07:00 -07:00
committed by John Wu
parent 7048aa1014
commit 4e2b88b3d0
18 changed files with 110 additions and 118 deletions

View File

@ -506,14 +506,14 @@ string find_apk_path(const char *pkg) {
return path.append("/base.apk");
}
string find_rules_dir(const char *base_dir) {
string rules_dir = base_dir;
if (access((rules_dir + "/unencrypted").data(), F_OK) == 0) {
rules_dir += "/unencrypted/magisk";
} else if (access((rules_dir + "/adb").data(), F_OK) == 0) {
rules_dir += "/adb/modules";
string resolve_preinit_dir(const char *base_dir) {
string dir = base_dir;
if (access((dir + "/unencrypted").data(), F_OK) == 0) {
dir += "/unencrypted/magisk";
} else if (access((dir + "/adb").data(), F_OK) == 0) {
dir += "/adb/modules";
} else {
rules_dir += "/magisk";
dir += "/magisk";
}
return rules_dir;
return dir;
}

View File

@ -107,7 +107,7 @@ void frm_rf(int dirfd);
void clone_dir(int src, int dest);
std::vector<mount_info> parse_mount_info(const char *pid);
std::string find_apk_path(const char *pkg);
std::string find_rules_dir(const char *base_dir);
std::string resolve_preinit_dir(const char *base_dir);
using sFILE = std::unique_ptr<FILE, decltype(&fclose)>;
using sDIR = std::unique_ptr<DIR, decltype(&closedir)>;

View File

@ -60,20 +60,20 @@ static void mount_mirrors() {
restorecon();
}
// check and mount rules
if (struct stat st{}; stat((MAGISKTMP + "/" BLOCKDIR "/rules").data(), &st) == 0 && (st.st_mode & S_IFBLK)) {
dev_t rules_dev = st.st_rdev;
// Check and mount preinit mirror
if (struct stat st{}; stat((MAGISKTMP + "/" PREINITDEV).data(), &st) == 0 && (st.st_mode & S_IFBLK)) {
dev_t preinit_dev = st.st_rdev;
for (const auto &info: self_mount_info) {
if (info.root == "/" && info.device == rules_dev) {
if (info.root == "/" && info.device == preinit_dev) {
auto flags = split_ro(info.fs_option, ",");
auto rw = std::any_of(flags.begin(), flags.end(), [](const auto &flag) {
return flag == "rw"sv;
});
if (!rw) continue;
string custom_rules_dir = find_rules_dir(info.target.data());
xmkdir(custom_rules_dir.data(), 0700);
auto rules_dir = MAGISKTMP + "/" RULESDIR;
mount_mirror(custom_rules_dir, rules_dir);
string preinit_dir = resolve_preinit_dir(info.target.data());
xmkdir(preinit_dir.data(), 0700);
auto mirror_dir = MAGISKTMP + "/" PREINITMIRR;
mount_mirror(preinit_dir, mirror_dir);
break;
}
}
@ -104,7 +104,7 @@ static void mount_mirrors() {
}
}
dev_t find_rules_device() {
dev_t find_preinit_device() {
const int UNKNOWN = 0;
const int PERSIST = 1;
const int METADATA = 2;
@ -113,12 +113,12 @@ dev_t find_rules_device() {
int matched = UNKNOWN;
dev_t rules_dev = 0;
bool encrypted = getprop("ro.crypto.state") == "encrypted";
string custom_rules_dir;
string preinit_dir;
bool mount = getuid() == 0 && getenv("MAGISKTMP");
for (const auto &info: parse_mount_info("self")) {
if (info.target.ends_with(RULESDIR))
if (info.target.ends_with(PREINITMIRR))
return info.device;
if (info.root != "/" || info.source.find("/dm-") != string::npos)
continue;
@ -146,17 +146,17 @@ dev_t find_rules_device() {
} else continue;
if (mount) {
custom_rules_dir = find_rules_dir(info.target.data());
preinit_dir = resolve_preinit_dir(info.target.data());
}
rules_dev = info.device;
matched = new_matched;
}
if (!custom_rules_dir.empty()) {
auto rules_dir = getenv("MAGISKTMP") + "/rules"s;
mkdirs(custom_rules_dir.data(), 0700);
mkdirs(rules_dir.data(), 0700);
xmount(custom_rules_dir.data(), rules_dir.data(), nullptr, MS_BIND, nullptr);
if (!preinit_dir.empty()) {
auto mirror_dir = string(getenv("MAGISKTMP")) + "/" PREINITMIRR;
mkdirs(preinit_dir.data(), 0700);
mkdirs(mirror_dir.data(), 0700);
xmount(preinit_dir.data(), mirror_dir.data(), nullptr, MS_BIND, nullptr);
}
return rules_dev;

View File

@ -6,7 +6,7 @@
extern bool RECOVERY_MODE;
extern std::atomic<ino_t> pkg_xml_ino;
dev_t find_rules_device();
dev_t find_preinit_device();
void unlock_blocks();
void reboot();
void start_log_daemon();

View File

@ -122,7 +122,6 @@ int magisk_main(int argc, char *argv[]) {
do_reboot = 1;
} else {
usage();
exit(1);
}
int fd = connect_daemon(MainRequest::REMOVE_MODULES);
write_int(fd, do_reboot);
@ -134,8 +133,8 @@ int magisk_main(int argc, char *argv[]) {
return 0;
} else if (argc >= 3 && argv[1] == "--install-module"sv) {
install_module(argv[2]);
} else if (argv[1] == "--rules-device"sv) {
auto dev = find_rules_device();
} else if (argv[1] == "--preinit-device"sv) {
auto dev = find_preinit_device();
if (dev) printf("%u:%u\n", major(dev), minor(dev));
return dev ? 0 : 1;
}

View File

@ -437,7 +437,7 @@ void handle_modules() {
}
static int check_rules_dir(char *buf, size_t sz) {
int off = ssprintf(buf, sz, "%s/%s", MAGISKTMP.data(), RULESDIR);
int off = ssprintf(buf, sz, "%s/%s", MAGISKTMP.data(), PREINITMIRR);
struct stat st1{};
struct stat st2{};
if (xstat(buf, &st1) < 0 || xstat(MODULEROOT, &st2) < 0)

View File

@ -15,19 +15,20 @@
#define MAGISKDB SECURE_DIR "/magisk.db"
// tmpfs paths
extern std::string MAGISKTMP;
#define INTLROOT ".magisk"
#define MIRRDIR INTLROOT "/mirror"
#define RULESDIR INTLROOT "/rules"
#define BLOCKDIR INTLROOT "/block"
#define WORKERDIR INTLROOT "/worker"
#define MODULEMNT INTLROOT "/modules"
#define BBPATH INTLROOT "/busybox"
#define ROOTOVL INTLROOT "/rootdir"
#define SHELLPTS INTLROOT "/pts"
#define ROOTMNT ROOTOVL "/.mount_list"
#define ZYGISKBIN INTLROOT "/zygisk"
#define SELINUXMOCK INTLROOT "/selinux"
extern std::string MAGISKTMP;
#define INTLROOT ".magisk"
#define MIRRDIR INTLROOT "/mirror"
#define PREINITMIRR INTLROOT "/preinit"
#define BLOCKDIR INTLROOT "/block"
#define PREINITDEV BLOCKDIR "/preinit"
#define WORKERDIR INTLROOT "/worker"
#define MODULEMNT INTLROOT "/modules"
#define BBPATH INTLROOT "/busybox"
#define ROOTOVL INTLROOT "/rootdir"
#define SHELLPTS INTLROOT "/pts"
#define ROOTMNT ROOTOVL "/.mount_list"
#define ZYGISKBIN INTLROOT "/zygisk"
#define SELINUXMOCK INTLROOT "/selinux"
constexpr const char *applet_names[] = { "su", "resetprop", nullptr };

View File

@ -57,7 +57,7 @@ public:
class MagiskInit : public BaseInit {
private:
dev_t rules_dev = 0;
dev_t preinit_dev = 0;
void parse_config_file();
void patch_sepolicy(const char *in, const char *out);

View File

@ -111,38 +111,40 @@ static void switch_root(const string &path) {
frm_rf(root);
}
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);
#define PREINITMNT MIRRDIR "/preinit"
static void mount_preinit_dir(string path, dev_t preinit_dev) {
if (!preinit_dev) return;
xmknod(PREINITDEV, S_IFBLK | 0600, preinit_dev);
xmkdir(PREINITMNT, 0);
bool mounted = false;
// first of all, find if rules dev is already mounted
// First, find if it is already mounted
for (auto &info : parse_mount_info("self")) {
if (info.root == "/" && info.device == rules_dev) {
if (info.root == "/" && info.device == preinit_dev) {
// Already mounted, just bind mount
xmount(info.target.data(), MIRRDIR "/rules", nullptr, MS_BIND, nullptr);
xmount(info.target.data(), PREINITMNT, 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");
if (mounted || mount(PREINITDEV, PREINITMNT, "ext4", MS_RDONLY, nullptr) == 0 ||
mount(PREINITDEV, PREINITMNT, "f2fs", MS_RDONLY, nullptr) == 0) {
string preinit_dir = resolve_preinit_dir(PREINITMNT);
// Create bind mount
xmkdirs(RULESDIR, 0);
if (access(custom_rules_dir.data(), F_OK)) {
LOGW("empty rules: %s\n", custom_rules_dir.data());
xmkdirs(PREINITMIRR, 0);
if (access(preinit_dir.data(), F_OK)) {
LOGW("empty preinit: %s\n", preinit_dir.data());
} else {
LOGD("rules: %s\n", custom_rules_dir.data());
xmount(custom_rules_dir.data(), RULESDIR, nullptr, MS_BIND, nullptr);
mount_list.emplace_back(path += "/" RULESDIR);
LOGD("preinit: %s\n", preinit_dir.data());
xmount(preinit_dir.data(), PREINITMIRR, nullptr, MS_BIND, nullptr);
mount_list.emplace_back(path += "/" PREINITMIRR);
}
xumount2(MIRRDIR "/rules", MNT_DETACH);
xumount2(PREINITMNT, MNT_DETACH);
} else {
PLOGE("Failed to mount rules %u:%u", major(rules_dev), minor(rules_dev));
unlink(BLOCKDIR "/rules");
PLOGE("Failed to mount rules %u:%u", major(preinit_dev), minor(preinit_dev));
unlink(PREINITDEV);
}
}
@ -246,7 +248,7 @@ void MagiskInit::setup_tmp(const char *path) {
xmkdir(BLOCKDIR, 0);
xmkdir(WORKERDIR, 0);
mount_rules_dir(path, rules_dev);
mount_preinit_dir(path, preinit_dev);
cp_afc(".backup/.magisk", INTLROOT "/config");
rm_rf(".backup");

View File

@ -185,7 +185,7 @@ 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") {
if (key == "PREINITDEVICE") {
unsigned int dev_major = 0;
unsigned int dev_minor = 0;
sscanf(value.data(), "%u:%u", &dev_major, &dev_minor);
@ -194,7 +194,7 @@ void MagiskInit::parse_config_file() {
}
return true;
});
rules_dev = dev;
preinit_dev = dev;
}
#define ROOTMIR MIRRDIR "/system_root"

View File

@ -15,12 +15,12 @@ void MagiskInit::patch_sepolicy(const char *in, const char *out) {
sepol->magisk_rules();
// Custom rules
if (auto dir = xopen_dir(RULESDIR)) {
if (auto dir = xopen_dir(PREINITMIRR)) {
for (dirent *entry; (entry = xreaddir(dir.get()));) {
auto rule = RULESDIR "/"s + entry->d_name + "/sepolicy.rule";
auto rule = PREINITMIRR "/"s + entry->d_name + "/sepolicy.rule";
if (xaccess(rule.data(), R_OK) == 0 &&
access((RULESDIR "/"s + entry->d_name + "/disable").data(), F_OK) != 0 &&
access((RULESDIR "/"s + entry->d_name + "/remove").data(), F_OK) != 0) {
access((PREINITMIRR "/"s + entry->d_name + "/disable").data(), F_OK) != 0 &&
access((PREINITMIRR "/"s + entry->d_name + "/remove").data(), F_OK) != 0) {
LOGD("Loading custom sepolicy patch: [%s]\n", rule.data());
sepol->load_rule_file(rule.data());
}
@ -96,12 +96,12 @@ bool MagiskInit::hijack_sepolicy() {
// Read all custom rules into memory
string rules;
if (auto dir = xopen_dir(RULESDIR)) {
if (auto dir = xopen_dir(PREINITMIRR)) {
for (dirent *entry; (entry = xreaddir(dir.get()));) {
auto rule_file = RULESDIR "/"s + entry->d_name + "/sepolicy.rule";
auto rule_file = PREINITMIRR "/"s + entry->d_name + "/sepolicy.rule";
if (xaccess(rule_file.data(), R_OK) == 0 &&
access((RULESDIR "/"s + entry->d_name + "/disable").data(), F_OK) != 0 &&
access((RULESDIR "/"s + entry->d_name + "/remove").data(), F_OK) != 0) {
access((PREINITMIRR "/"s + entry->d_name + "/disable").data(), F_OK) != 0 &&
access((PREINITMIRR "/"s + entry->d_name + "/remove").data(), F_OK) != 0) {
LOGD("Load custom sepolicy patch: [%s]\n", rule_file.data());
full_read(rule_file.data(), rules);
rules += '\n';