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