mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-12-26 20:17:38 +00:00
Always clone attribute from existing files to module files
This makes sure no weird permission/SELinux issues shall happen
This commit is contained in:
parent
c9fa8118d1
commit
0c227f2917
@ -48,7 +48,7 @@ extern void auto_start_magiskhide();
|
||||
// Precedence: MODULE > SKEL > INTER > DUMMY
|
||||
#define IS_DUMMY 0x01 /* mount from mirror */
|
||||
#define IS_INTER 0x02 /* intermediate node */
|
||||
#define IS_SKEL 0x04 /* mount from skeleton */
|
||||
#define IS_SKEL 0x04 /* replace with tmpfs */
|
||||
#define IS_MODULE 0x08 /* mount from module */
|
||||
|
||||
#define IS_DIR(n) ((n)->type == DT_DIR)
|
||||
@ -57,7 +57,8 @@ extern void auto_start_magiskhide();
|
||||
|
||||
class node_entry {
|
||||
public:
|
||||
explicit node_entry(const char *, uint8_t status = 0, uint8_t type = 0);
|
||||
explicit node_entry(const char *name, uint8_t status = 0, uint8_t type = 0)
|
||||
: name(name), type(type), status(status), parent(nullptr) {}
|
||||
~node_entry();
|
||||
void create_module_tree(const char *module);
|
||||
void magic_mount();
|
||||
@ -71,29 +72,25 @@ private:
|
||||
node_entry *parent;
|
||||
vector<node_entry *> children;
|
||||
|
||||
node_entry(const char *, const char *, uint8_t type);
|
||||
bool is_root();
|
||||
node_entry(node_entry *parent, const char *module, const char *name, uint8_t type)
|
||||
: node_entry(name, 0, type) {
|
||||
this->parent = parent;
|
||||
this->module = module;
|
||||
}
|
||||
bool is_vendor();
|
||||
string get_path();
|
||||
node_entry *insert(node_entry *);
|
||||
void insert(node_entry *&);
|
||||
void clone_skeleton();
|
||||
int get_path(char *path);
|
||||
};
|
||||
|
||||
node_entry::node_entry(const char *name, uint8_t status, uint8_t type)
|
||||
: name(name), type(type), status(status), parent(nullptr) {}
|
||||
|
||||
node_entry::node_entry(const char *module, const char *name, uint8_t type)
|
||||
: node_entry(name, (uint8_t) 0, type) {
|
||||
this->module = module;
|
||||
}
|
||||
|
||||
node_entry::~node_entry() {
|
||||
for (auto &node : children)
|
||||
delete node;
|
||||
}
|
||||
|
||||
bool node_entry::is_root() {
|
||||
return parent == nullptr;
|
||||
bool node_entry::is_vendor() {
|
||||
return parent ? (parent->parent ? false : name == "vendor") : false;
|
||||
}
|
||||
|
||||
string node_entry::get_path() {
|
||||
@ -109,7 +106,7 @@ int node_entry::get_path(char *path) {
|
||||
return len;
|
||||
}
|
||||
|
||||
node_entry *node_entry::insert(node_entry *node) {
|
||||
void node_entry::insert(node_entry *&node) {
|
||||
node->parent = this;
|
||||
for (auto &child : children) {
|
||||
if (child->name == node->name) {
|
||||
@ -117,15 +114,14 @@ node_entry *node_entry::insert(node_entry *node) {
|
||||
// The new node has higher precedence
|
||||
delete child;
|
||||
child = node;
|
||||
return node;
|
||||
} else {
|
||||
delete node;
|
||||
return child;
|
||||
node = child;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
children.push_back(node);
|
||||
return node;
|
||||
}
|
||||
|
||||
void node_entry::create_module_tree(const char *module) {
|
||||
@ -134,7 +130,6 @@ void node_entry::create_module_tree(const char *module) {
|
||||
|
||||
auto full_path = get_path();
|
||||
snprintf(buf, PATH_MAX, "%s/%s%s", MODULEROOT, module, full_path.c_str());
|
||||
|
||||
if (!(dir = xopendir(buf)))
|
||||
return;
|
||||
|
||||
@ -142,8 +137,12 @@ void node_entry::create_module_tree(const char *module) {
|
||||
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
|
||||
continue;
|
||||
// Create new node
|
||||
auto node = new node_entry(module, entry->d_name, entry->d_type);
|
||||
auto node = new node_entry(this, module, entry->d_name, entry->d_type);
|
||||
|
||||
// buf = real path, buf2 = module path
|
||||
snprintf(buf, PATH_MAX, "%s/%s", full_path.c_str(), entry->d_name);
|
||||
int eo2 = snprintf(buf2, PATH_MAX, MODULEROOT "/%s%s/%s",
|
||||
module, full_path.c_str(), entry->d_name);
|
||||
|
||||
/*
|
||||
* Clone the parent in the following condition:
|
||||
@ -154,7 +153,7 @@ void node_entry::create_module_tree(const char *module) {
|
||||
bool clone = false;
|
||||
if (IS_LNK(node) || access(buf, F_OK) == -1) {
|
||||
clone = true;
|
||||
} else if (!is_root() || node->name != "vendor") {
|
||||
} else if (!node->is_vendor()) {
|
||||
struct stat s;
|
||||
xstat(buf, &s);
|
||||
if (S_ISLNK(s.st_mode))
|
||||
@ -165,23 +164,27 @@ void node_entry::create_module_tree(const char *module) {
|
||||
// Mark self as a skeleton
|
||||
status |= IS_SKEL; /* This will not overwrite if parent is module */
|
||||
node->status = IS_MODULE;
|
||||
} else if (IS_DIR(node)) {
|
||||
// Check if marked as replace
|
||||
snprintf(buf2, PATH_MAX, "%s/%s%s/.replace", MODULEROOT, module, buf);
|
||||
if (access(buf2, F_OK) == 0) {
|
||||
// Replace everything, mark as leaf
|
||||
} else {
|
||||
// Clone attributes from real path
|
||||
clone_attr(buf, buf2);
|
||||
if (IS_DIR(node)) {
|
||||
// Check if marked as replace
|
||||
strcpy(buf2 + eo2, "/.replace");
|
||||
if (access(buf2, F_OK) == 0) {
|
||||
// Replace everything, mark as leaf
|
||||
node->status = IS_MODULE;
|
||||
} else {
|
||||
// This will be an intermediate node
|
||||
node->status = IS_INTER;
|
||||
}
|
||||
} else if (IS_REG(node)) {
|
||||
// This is a file, mark as leaf
|
||||
node->status = IS_MODULE;
|
||||
} else {
|
||||
// This will be an intermediate node
|
||||
node->status = IS_INTER;
|
||||
}
|
||||
} else if (IS_REG(node)) {
|
||||
// This is a file, mark as leaf
|
||||
node->status = IS_MODULE;
|
||||
}
|
||||
node = insert(node);
|
||||
if (node->status & (IS_SKEL | IS_INTER)) {
|
||||
// Intermediate folder, travel deeper
|
||||
insert(node);
|
||||
if (IS_DIR(node)) {
|
||||
// Recursive traverse through everything
|
||||
node->create_module_tree(module);
|
||||
}
|
||||
}
|
||||
@ -225,7 +228,7 @@ void node_entry::clone_skeleton() {
|
||||
close(creat(buf, 0644));
|
||||
// Links will be handled later
|
||||
|
||||
if (is_root() && child->name == "vendor") {
|
||||
if (child->is_vendor()) {
|
||||
if (seperate_vendor) {
|
||||
cp_afc(MIRRDIR "/system/vendor", "/system/vendor");
|
||||
VLOGI("copy_link ", "/system/vendor", MIRRDIR "/system/vendor");
|
||||
@ -270,13 +273,13 @@ void node_entry::magic_mount() {
|
||||
for (auto &child : children)
|
||||
child->magic_mount();
|
||||
}
|
||||
// The only thing goes here should be vendor placeholder
|
||||
// The only thing goes here should be placeholder nodes
|
||||
// There should be no dummies, so don't need to handle it here
|
||||
}
|
||||
|
||||
node_entry *node_entry::extract(const char *name) {
|
||||
node_entry *node = nullptr;
|
||||
// Extract the vendor node out of system tree and swap with placeholder
|
||||
// Extract the node out and swap with placeholder
|
||||
for (auto &child : children) {
|
||||
if (child->name == name) {
|
||||
node = child;
|
||||
|
Loading…
x
Reference in New Issue
Block a user