diff --git a/native/src/core/module.cpp b/native/src/core/module.cpp index 97373797d..b5b6a0dca 100644 --- a/native/src/core/module.cpp +++ b/native/src/core/module.cpp @@ -37,7 +37,7 @@ tmpfs_node::tmpfs_node(node_entry *node) : dir_node(node, this) { for (dirent *entry; (entry = xreaddir(dir.get()));) { if (entry->d_type == DT_DIR) { // create a dummy inter_node to upgrade later - emplace(entry->d_name, entry->d_name, ""); + emplace(entry->d_name, entry->d_name); } else { // Insert mirror nodes emplace(entry->d_name, entry); @@ -61,7 +61,18 @@ bool dir_node::prepare() { set_exist(true); } for (auto it = children.begin(); it != children.end();) { - if (require_tmpfs_upgrade(it->second)) { + // We need to upgrade to tmpfs node if any child: + // - Target does not exist + // - Source or target is a symlink (since we cannot bind mount symlink) + bool cannot_mnt; + if (struct stat st{}; lstat(it->second->node_path().data(), &st) != 0) { + cannot_mnt = true; + } else { + it->second->set_exist(true); + cannot_mnt = it->second->is_lnk() || S_ISLNK(st.st_mode); + } + + if (cannot_mnt) { if (_node_type > type_id()) { // Upgrade will fail, remove the unsupported child node LOGW("Unable to add: %s, skipped\n", it->second->node_path().data()); @@ -71,15 +82,6 @@ bool dir_node::prepare() { } // Tell parent to upgrade self to tmpfs to_tmpfs = true; - // If child is inter_node and it does not exist, upgrade to module - if (auto dn = dyn_cast(it->second)) { - if (!dn->exist()) { - if (auto nit = upgrade(it); nit != children.end()) { - it = nit; - goto next_node; - } - } - } } if (auto dn = dyn_cast(it->second)) { if (skip_mirror) { @@ -90,7 +92,6 @@ bool dir_node::prepare() { it = upgrade(it); } } -next_node: ++it; } return to_tmpfs; @@ -110,7 +111,7 @@ void dir_node::collect_module_files(const char *module, int dfd) { if (entry->d_type == DT_DIR) { if (auto it = children.find(entry->d_name); it == children.end()) { - dn = emplace(entry->d_name, entry->d_name, module); + dn = emplace(entry->d_name, entry->d_name); } else { dn = dyn_cast(it->second); } @@ -143,6 +144,10 @@ void node_entry::create_and_mount(const char *reason, const string &src) { } } +void mirror_node::mount() { + create_and_mount("mirror", mirror_path()); +} + void module_node::mount() { string src = module_mnt + module + parent()->root()->prefix + node_path(); if (exist()) @@ -205,7 +210,7 @@ public: static void inject_magisk_bins(root_node *system) { auto bin = system->get_child("bin"); if (!bin) { - bin = new inter_node("bin", ""); + bin = new inter_node("bin"); system->insert(bin); } diff --git a/native/src/core/node.hpp b/native/src/core/node.hpp index 7921d4fb9..46339f65d 100644 --- a/native/src/core/node.hpp +++ b/native/src/core/node.hpp @@ -175,9 +175,9 @@ protected: return static_cast(it == children.end() ? nullptr : it->second); } - template - iterator insert(string_view name, uint8_t type, const Func &fn) { - return insert_at(children.find(name), type, fn); + template + iterator insert(string_view name, uint8_t type, const Builder &builder) { + return insert_at(children.find(name), type, builder); } // Emplace insert a new node, or upgrade if the requested type has a higher rank. @@ -216,17 +216,11 @@ protected: return it; } - template + template iterator upgrade(iterator it, Args &&...args) { - return insert_at(it, type_id(), [&](node_entry *&ex) -> node_entry * { - if (!ex) - return nullptr; - if constexpr (!std::is_same_v) { - // Type check if type is specified - if (!isa(ex)) - return nullptr; - } - auto node = new To(static_cast(ex), std::forward(args)...); + return insert_at(it, type_id(), [&](node_entry *&ex) -> node_entry * { + if (!ex) return nullptr; + auto node = new T(ex, std::forward(args)...); ex = nullptr; return node; }); @@ -241,21 +235,6 @@ protected: private: // Root node lookup cache root_node *_root = nullptr; - - // We need to upgrade to tmpfs node if any child: - // - Target does not exist - // - Source or target is a symlink (since we cannot bind mount link) - bool require_tmpfs_upgrade(node_entry *child) { - struct stat st{}; - if (lstat(child->node_path().data(), &st) != 0) { - return true; - } else { - child->set_exist(true); - if (child->is_lnk() || S_ISLNK(st.st_mode)) - return true; - } - return false; - } }; class root_node : public dir_node { @@ -271,10 +250,7 @@ public: class inter_node : public dir_node { public: - inter_node(const char *name, const char *module) : dir_node(name, this), module(module) {} -private: - const char *module; - friend class module_node; + inter_node(const char *name) : dir_node(name, this) {} }; class module_node : public node_entry { @@ -286,8 +262,6 @@ public: consume(node); } - explicit module_node(inter_node *node) : module_node(node, node->module) {} - void mount() override; private: const char *module; @@ -297,9 +271,7 @@ private: class mirror_node : public node_entry { public: explicit mirror_node(dirent *entry) : node_entry(entry->d_name, entry->d_type, this) {} - void mount() override { - create_and_mount("mirror", mirror_path()); - } + void mount() override; }; class tmpfs_node : public dir_node {