mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-11-27 20:15:29 +00:00
Don't let inter_node upgrade to module_node
This commit is contained in:
parent
92077ebe53
commit
744ebca206
@ -37,7 +37,7 @@ tmpfs_node::tmpfs_node(node_entry *node) : dir_node(node, this) {
|
|||||||
for (dirent *entry; (entry = xreaddir(dir.get()));) {
|
for (dirent *entry; (entry = xreaddir(dir.get()));) {
|
||||||
if (entry->d_type == DT_DIR) {
|
if (entry->d_type == DT_DIR) {
|
||||||
// create a dummy inter_node to upgrade later
|
// create a dummy inter_node to upgrade later
|
||||||
emplace<inter_node>(entry->d_name, entry->d_name, "");
|
emplace<inter_node>(entry->d_name, entry->d_name);
|
||||||
} else {
|
} else {
|
||||||
// Insert mirror nodes
|
// Insert mirror nodes
|
||||||
emplace<mirror_node>(entry->d_name, entry);
|
emplace<mirror_node>(entry->d_name, entry);
|
||||||
@ -61,7 +61,18 @@ bool dir_node::prepare() {
|
|||||||
set_exist(true);
|
set_exist(true);
|
||||||
}
|
}
|
||||||
for (auto it = children.begin(); it != children.end();) {
|
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<tmpfs_node>()) {
|
if (_node_type > type_id<tmpfs_node>()) {
|
||||||
// Upgrade will fail, remove the unsupported child node
|
// Upgrade will fail, remove the unsupported child node
|
||||||
LOGW("Unable to add: %s, skipped\n", it->second->node_path().data());
|
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
|
// Tell parent to upgrade self to tmpfs
|
||||||
to_tmpfs = true;
|
to_tmpfs = true;
|
||||||
// If child is inter_node and it does not exist, upgrade to module
|
|
||||||
if (auto dn = dyn_cast<inter_node>(it->second)) {
|
|
||||||
if (!dn->exist()) {
|
|
||||||
if (auto nit = upgrade<module_node, inter_node>(it); nit != children.end()) {
|
|
||||||
it = nit;
|
|
||||||
goto next_node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (auto dn = dyn_cast<dir_node>(it->second)) {
|
if (auto dn = dyn_cast<dir_node>(it->second)) {
|
||||||
if (skip_mirror) {
|
if (skip_mirror) {
|
||||||
@ -90,7 +92,6 @@ bool dir_node::prepare() {
|
|||||||
it = upgrade<tmpfs_node>(it);
|
it = upgrade<tmpfs_node>(it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
next_node:
|
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
return to_tmpfs;
|
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 (entry->d_type == DT_DIR) {
|
||||||
if (auto it = children.find(entry->d_name); it == children.end()) {
|
if (auto it = children.find(entry->d_name); it == children.end()) {
|
||||||
dn = emplace<inter_node>(entry->d_name, entry->d_name, module);
|
dn = emplace<inter_node>(entry->d_name, entry->d_name);
|
||||||
} else {
|
} else {
|
||||||
dn = dyn_cast<inter_node>(it->second);
|
dn = dyn_cast<inter_node>(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() {
|
void module_node::mount() {
|
||||||
string src = module_mnt + module + parent()->root()->prefix + node_path();
|
string src = module_mnt + module + parent()->root()->prefix + node_path();
|
||||||
if (exist())
|
if (exist())
|
||||||
@ -205,7 +210,7 @@ public:
|
|||||||
static void inject_magisk_bins(root_node *system) {
|
static void inject_magisk_bins(root_node *system) {
|
||||||
auto bin = system->get_child<inter_node>("bin");
|
auto bin = system->get_child<inter_node>("bin");
|
||||||
if (!bin) {
|
if (!bin) {
|
||||||
bin = new inter_node("bin", "");
|
bin = new inter_node("bin");
|
||||||
system->insert(bin);
|
system->insert(bin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,9 +175,9 @@ protected:
|
|||||||
return static_cast<T*>(it == children.end() ? nullptr : it->second);
|
return static_cast<T*>(it == children.end() ? nullptr : it->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Func>
|
template<typename Builder>
|
||||||
iterator insert(string_view name, uint8_t type, const Func &fn) {
|
iterator insert(string_view name, uint8_t type, const Builder &builder) {
|
||||||
return insert_at(children.find(name), type, fn);
|
return insert_at(children.find(name), type, builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Emplace insert a new node, or upgrade if the requested type has a higher rank.
|
// Emplace insert a new node, or upgrade if the requested type has a higher rank.
|
||||||
@ -216,17 +216,11 @@ protected:
|
|||||||
return it;
|
return it;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class To, class From = node_entry, class ...Args>
|
template<class T, class ...Args>
|
||||||
iterator upgrade(iterator it, Args &&...args) {
|
iterator upgrade(iterator it, Args &&...args) {
|
||||||
return insert_at(it, type_id<To>(), [&](node_entry *&ex) -> node_entry * {
|
return insert_at(it, type_id<T>(), [&](node_entry *&ex) -> node_entry * {
|
||||||
if (!ex)
|
if (!ex) return nullptr;
|
||||||
return nullptr;
|
auto node = new T(ex, std::forward<Args>(args)...);
|
||||||
if constexpr (!std::is_same_v<From, node_entry>) {
|
|
||||||
// Type check if type is specified
|
|
||||||
if (!isa<From>(ex))
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
auto node = new To(static_cast<From *>(ex), std::forward<Args>(args)...);
|
|
||||||
ex = nullptr;
|
ex = nullptr;
|
||||||
return node;
|
return node;
|
||||||
});
|
});
|
||||||
@ -241,21 +235,6 @@ protected:
|
|||||||
private:
|
private:
|
||||||
// Root node lookup cache
|
// Root node lookup cache
|
||||||
root_node *_root = nullptr;
|
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 {
|
class root_node : public dir_node {
|
||||||
@ -271,10 +250,7 @@ public:
|
|||||||
|
|
||||||
class inter_node : public dir_node {
|
class inter_node : public dir_node {
|
||||||
public:
|
public:
|
||||||
inter_node(const char *name, const char *module) : dir_node(name, this), module(module) {}
|
inter_node(const char *name) : dir_node(name, this) {}
|
||||||
private:
|
|
||||||
const char *module;
|
|
||||||
friend class module_node;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class module_node : public node_entry {
|
class module_node : public node_entry {
|
||||||
@ -286,8 +262,6 @@ public:
|
|||||||
consume(node);
|
consume(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit module_node(inter_node *node) : module_node(node, node->module) {}
|
|
||||||
|
|
||||||
void mount() override;
|
void mount() override;
|
||||||
private:
|
private:
|
||||||
const char *module;
|
const char *module;
|
||||||
@ -297,9 +271,7 @@ private:
|
|||||||
class mirror_node : public node_entry {
|
class mirror_node : public node_entry {
|
||||||
public:
|
public:
|
||||||
explicit mirror_node(dirent *entry) : node_entry(entry->d_name, entry->d_type, this) {}
|
explicit mirror_node(dirent *entry) : node_entry(entry->d_name, entry->d_type, this) {}
|
||||||
void mount() override {
|
void mount() override;
|
||||||
create_and_mount("mirror", mirror_path());
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class tmpfs_node : public dir_node {
|
class tmpfs_node : public dir_node {
|
||||||
|
Loading…
Reference in New Issue
Block a user