Several improvements

This commit is contained in:
topjohnwu 2019-03-31 06:32:33 -04:00
parent cd6bcb97ef
commit 0149b1368d
3 changed files with 30 additions and 47 deletions

View File

@ -245,7 +245,7 @@ void MagiskInit::load_kernel_info() {
if (cmd.dt_dir[0] == '\0') if (cmd.dt_dir[0] == '\0')
strcpy(cmd.dt_dir, DEFAULT_DT_DIR); strcpy(cmd.dt_dir, DEFAULT_DT_DIR);
LOGD("system_as_root[%d] slot[%s] dt_dir[%s]\n", cmd.system_as_root, cmd.slot, cmd.dt_dir); LOGD("system_as_root[%d]\nslot[%s]\ndt_dir[%s]\n", cmd.system_as_root, cmd.slot, cmd.dt_dir);
} }
void MagiskInit::preset() { void MagiskInit::preset() {
@ -253,10 +253,7 @@ void MagiskInit::preset() {
if (cmd.system_as_root) { if (cmd.system_as_root) {
// Clear rootfs // Clear rootfs
const char *excl[] = { "overlay", "proc", "sys", nullptr }; frm_rf(root, { "overlay", "proc", "sys" });
excl_list = excl;
frm_rf(root);
excl_list = nullptr;
} else { } else {
decompress_ramdisk(); decompress_ramdisk();
@ -375,24 +372,16 @@ void MagiskInit::setup_rootfs() {
bool patch_init = patch_sepolicy(); bool patch_init = patch_sepolicy();
if (cmd.system_as_root) { if (cmd.system_as_root) {
// Clone rootfs except /system // Clone rootfs
int system_root = open("/system_root", O_RDONLY | O_CLOEXEC); int system_root = open("/system_root", O_RDONLY | O_CLOEXEC);
const char *excl[] = { "system", nullptr }; clone_dir(system_root, root, false);
excl_list = excl;
clone_dir(system_root, root);
close(system_root); close(system_root);
excl_list = nullptr;
} }
// Override /sepolicy if exist
rename("/magisk_sepolicy", "/sepolicy");
if (patch_init) { if (patch_init) {
constexpr char SYSTEM_INIT[] = "/system/bin/init"; constexpr char SYSTEM_INIT[] = "/system/bin/init";
// If init is symlink, copy it to rootfs so we can patch // If init is symlink, copy it to rootfs so we can patch
struct stat st; if (is_lnk("/init"))
lstat("/init", &st);
if (S_ISLNK(st.st_mode))
cp_afc(SYSTEM_INIT, "/init"); cp_afc(SYSTEM_INIT, "/init");
char *addr; char *addr;
@ -474,7 +463,7 @@ bool MagiskInit::patch_sepolicy() {
sepol_magisk_rules(); sepol_magisk_rules();
sepol_allow(SEPOL_PROC_DOMAIN, ALL, ALL, ALL); sepol_allow(SEPOL_PROC_DOMAIN, ALL, ALL, ALL);
dump_policydb("/magisk_sepolicy"); dump_policydb("/sepolicy");
// Load policy to kernel so we can label rootfs // Load policy to kernel so we can label rootfs
if (load_sepol) if (load_sepol)
@ -483,7 +472,7 @@ bool MagiskInit::patch_sepolicy() {
// Remove OnePlus stupid debug sepolicy and use our own // Remove OnePlus stupid debug sepolicy and use our own
if (access("/sepolicy_debug", F_OK) == 0) { if (access("/sepolicy_debug", F_OK) == 0) {
unlink("/sepolicy_debug"); unlink("/sepolicy_debug");
link("/magisk_sepolicy", "/sepolicy_debug"); link("/sepolicy", "/sepolicy_debug");
} }
// Enable selinux functions // Enable selinux functions

View File

@ -17,16 +17,6 @@
using namespace std; using namespace std;
const char **excl_list = nullptr;
static int is_excl(const char *name) {
if (excl_list)
for (int i = 0; excl_list[i]; ++i)
if (strcmp(name, excl_list[i]) == 0)
return 1;
return 0;
}
ssize_t fd_path(int fd, char *path, size_t size) { ssize_t fd_path(int fd, char *path, size_t size) {
snprintf(path, size, "/proc/self/fd/%d", fd); snprintf(path, size, "/proc/self/fd/%d", fd);
return xreadlink(path, path, size); return xreadlink(path, path, size);
@ -62,7 +52,15 @@ int mkdirs(const char *pathname, mode_t mode) {
return 0; return 0;
} }
void post_order_walk(int dirfd, void (*fn)(int, struct dirent *)) { static bool is_excl(initializer_list<const char *> excl, const char *name) {
for (auto item : excl)
if (strcmp(item, name) == 0)
return true;
return false;
}
static void post_order_walk(int dirfd, initializer_list<const char *> excl,
int (*fn)(int, struct dirent *)) {
struct dirent *entry; struct dirent *entry;
int newfd; int newfd;
DIR *dir = fdopendir(dirfd); DIR *dir = fdopendir(dirfd);
@ -71,17 +69,21 @@ void post_order_walk(int dirfd, void (*fn)(int, struct dirent *)) {
while ((entry = xreaddir(dir))) { while ((entry = xreaddir(dir))) {
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
continue; continue;
if (is_excl(entry->d_name)) if (is_excl(excl, entry->d_name))
continue; continue;
if (entry->d_type == DT_DIR) { if (entry->d_type == DT_DIR) {
newfd = xopenat(dirfd, entry->d_name, O_RDONLY | O_CLOEXEC); newfd = xopenat(dirfd, entry->d_name, O_RDONLY | O_CLOEXEC);
post_order_walk(newfd, fn); post_order_walk(newfd, excl, fn);
close(newfd); close(newfd);
} }
fn(dirfd, entry); fn(dirfd, entry);
} }
} }
static int remove_at(int dirfd, struct dirent *entry) {
return unlinkat(dirfd, entry->d_name, entry->d_type == DT_DIR ? AT_REMOVEDIR : 0);
}
void rm_rf(const char *path) { void rm_rf(const char *path) {
struct stat st; struct stat st;
if (lstat(path, &st) < 0) if (lstat(path, &st) < 0)
@ -94,10 +96,8 @@ void rm_rf(const char *path) {
remove(path); remove(path);
} }
void frm_rf(int dirfd) { void frm_rf(int dirfd, initializer_list<const char *> excl) {
post_order_walk(dirfd, [](auto dirfd, auto entry) -> void { post_order_walk(dirfd, excl, remove_at);
unlinkat(dirfd, entry->d_name, entry->d_type == DT_DIR ? AT_REMOVEDIR : 0);
});
} }
/* This will only on the same file system */ /* This will only on the same file system */
@ -134,8 +134,6 @@ void mv_dir(int src, int dest) {
while ((entry = xreaddir(dir))) { while ((entry = xreaddir(dir))) {
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
continue; continue;
if (is_excl(entry->d_name))
continue;
getattrat(src, entry->d_name, &a); getattrat(src, entry->d_name, &a);
switch (entry->d_type) { switch (entry->d_type) {
case DT_DIR: case DT_DIR:
@ -186,7 +184,7 @@ void cp_afc(const char *source, const char *destination) {
setattr(destination, &a); setattr(destination, &a);
} }
void clone_dir(int src, int dest) { void clone_dir(int src, int dest, bool overwrite) {
struct dirent *entry; struct dirent *entry;
DIR *dir; DIR *dir;
int srcfd, destfd, newsrc, newdest; int srcfd, destfd, newsrc, newdest;
@ -197,7 +195,8 @@ void clone_dir(int src, int dest) {
while ((entry = xreaddir(dir))) { while ((entry = xreaddir(dir))) {
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
continue; continue;
if (is_excl(entry->d_name)) if (struct stat st; !overwrite &&
fstatat(dest, entry->d_name, &st, AT_SYMLINK_NOFOLLOW) == 0)
continue; continue;
getattrat(src, entry->d_name, &a); getattrat(src, entry->d_name, &a);
switch (entry->d_type) { switch (entry->d_type) {
@ -206,7 +205,7 @@ void clone_dir(int src, int dest) {
setattrat(dest, entry->d_name, &a); setattrat(dest, entry->d_name, &a);
newsrc = xopenat(src, entry->d_name, O_RDONLY | O_CLOEXEC); newsrc = xopenat(src, entry->d_name, O_RDONLY | O_CLOEXEC);
newdest = xopenat(dest, entry->d_name, O_RDONLY | O_CLOEXEC); newdest = xopenat(dest, entry->d_name, O_RDONLY | O_CLOEXEC);
clone_dir(newsrc, newdest); clone_dir(newsrc, newdest, overwrite);
close(newsrc); close(newsrc);
close(newdest); close(newdest);
break; break;
@ -237,8 +236,6 @@ void link_dir(int src, int dest) {
while ((entry = xreaddir(dir))) { while ((entry = xreaddir(dir))) {
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
continue; continue;
if (is_excl(entry->d_name))
continue;
if (entry->d_type == DT_DIR) { if (entry->d_type == DT_DIR) {
getattrat(src, entry->d_name, &a); getattrat(src, entry->d_name, &a);
xmkdirat(dest, entry->d_name, a.st.st_mode & 0777); xmkdirat(dest, entry->d_name, a.st.st_mode & 0777);

View File

@ -97,8 +97,6 @@ ssize_t __getdelim(char **lineptr, size_t *n, int delim, FILE *stream);
#define do_align(p, a) (((p) + (a) - 1) / (a) * (a)) #define do_align(p, a) (((p) + (a) - 1) / (a) * (a))
#define align_off(p, a) (do_align(p, a) - (p)) #define align_off(p, a) (do_align(p, a) - (p))
extern const char **excl_list;
struct file_attr { struct file_attr {
struct stat st; struct stat st;
char con[128]; char con[128];
@ -107,14 +105,11 @@ struct file_attr {
ssize_t fd_path(int fd, char *path, size_t size); ssize_t fd_path(int fd, char *path, size_t size);
int fd_pathat(int dirfd, const char *name, char *path, size_t size); int fd_pathat(int dirfd, const char *name, char *path, size_t size);
int mkdirs(const char *pathname, mode_t mode); int mkdirs(const char *pathname, mode_t mode);
void post_order_walk(int dirfd, void (*fn)(int, struct dirent *));
void rm_rf(const char *path); void rm_rf(const char *path);
void frm_rf(int dirfd);
void mv_f(const char *source, const char *destination); void mv_f(const char *source, const char *destination);
void mv_dir(int src, int dest); void mv_dir(int src, int dest);
void cp_afc(const char *source, const char *destination); void cp_afc(const char *source, const char *destination);
void link_dir(int src, int dest); void link_dir(int src, int dest);
void clone_dir(int src, int dest);
int getattr(const char *path, struct file_attr *a); int getattr(const char *path, struct file_attr *a);
int getattrat(int dirfd, const char *name, struct file_attr *a); int getattrat(int dirfd, const char *name, struct file_attr *a);
int fgetattr(int fd, struct file_attr *a); int fgetattr(int fd, struct file_attr *a);
@ -177,6 +172,8 @@ void file_readline(const char *file, const std::function<bool (std::string_view)
void parse_prop_file(const char *file, const std::function void parse_prop_file(const char *file, const std::function
<bool(std::string_view, std::string_view)> &fn); <bool(std::string_view, std::string_view)> &fn);
void *__mmap(const char *filename, size_t *size, bool rw); void *__mmap(const char *filename, size_t *size, bool rw);
void frm_rf(int dirfd, std::initializer_list<const char *> excl = std::initializer_list<const char *>());
void clone_dir(int src, int dest, bool overwrite = true);
template <typename B> template <typename B>
void mmap_ro(const char *filename, B &buf, size_t &sz) { void mmap_ro(const char *filename, B &buf, size_t &sz) {