From bc2cac90fe8d2a95d57b6d9b9b59883279c002be Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Fri, 2 Feb 2018 03:22:38 +0800 Subject: [PATCH] Hardlink files recursively --- native/jni/core/daemon.c | 9 ++------- native/jni/core/magiskinit.c | 14 +++++++------- native/jni/include/utils.h | 1 + native/jni/utils/file.c | 27 +++++++++++++++++++++++++++ 4 files changed, 37 insertions(+), 14 deletions(-) diff --git a/native/jni/core/daemon.c b/native/jni/core/daemon.c index d0ccfa533..d1046e610 100644 --- a/native/jni/core/daemon.c +++ b/native/jni/core/daemon.c @@ -141,13 +141,8 @@ void daemon_init() { chmod("/root", 0755); root = xopen("/root", O_RDONLY | O_CLOEXEC); sbin = xopen("/sbin", O_RDONLY | O_CLOEXEC); - dir = xfdopendir(sbin); - while((entry = xreaddir(dir))) { - if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue; - linkat(sbin, entry->d_name, root, entry->d_name, 0); - if (strcmp(entry->d_name, "magisk") == 0) - unlinkat(sbin, entry->d_name, 0); - } + link_dir(sbin, root); + unlink("/sbin/magisk"); close(sbin); xmount("tmpfs", "/sbin", "tmpfs", 0, NULL); diff --git a/native/jni/core/magiskinit.c b/native/jni/core/magiskinit.c index 17e004ad3..80240e003 100644 --- a/native/jni/core/magiskinit.c +++ b/native/jni/core/magiskinit.c @@ -152,7 +152,7 @@ static void fstab_patch_cb(int dirfd, struct dirent *entry) { size_t _size; uint32_t size; full_read_at(dirfd, entry->d_name, &buf, &_size); - size = _size; /* Type conversion */ + size = (uint32_t) _size; /* Type conversion */ if (!keepverity) patch_verity(&buf, &size, 1); if (!keepencrypt) @@ -203,8 +203,8 @@ static void patch_ramdisk(int root) { } static int strend(const char *s1, const char *s2) { - int l1 = strlen(s1); - int l2 = strlen(s2); + size_t l1 = strlen(s1); + size_t l2 = strlen(s2); return strcmp(s1 + l1 - l2, s2); } @@ -327,7 +327,7 @@ static int unxz(const void *buf, size_t size, int fd) { lzma_stream strm = LZMA_STREAM_INIT; if (lzma_auto_decoder(&strm, UINT64_MAX, 0) != LZMA_OK) return 1; - lzma_ret ret = 0; + lzma_ret ret; void *out = malloc(BUFSIZE); strm.next_in = buf; strm.avail_in = size; @@ -505,10 +505,10 @@ int main(int argc, char *argv[]) { } } - int overlay = open("/overlay", O_RDONLY | O_CLOEXEC); // Only patch rootfs if not intended to run in recovery if (access("/etc/recovery.fstab", F_OK) != 0) { + int overlay = open("/overlay", O_RDONLY | O_CLOEXEC); mv_dir(overlay, root); patch_ramdisk(root); @@ -528,16 +528,16 @@ int main(int argc, char *argv[]) { umount("/system"); } + close(overlay); + if (fork_dont_care() == 0) { strcpy(argv[0], "magiskinit"); - close(overlay); close(root); magisk_init_daemon(); } } // Clean up - close(overlay); close(root); umount("/vendor"); rmdir("/overlay"); diff --git a/native/jni/include/utils.h b/native/jni/include/utils.h index 22e2166b0..926a661f6 100644 --- a/native/jni/include/utils.h +++ b/native/jni/include/utils.h @@ -111,6 +111,7 @@ void frm_rf(int dirfd); void mv_f(const char *source, const char *destination); void mv_dir(int src, int dest); void cp_afc(const char *source, const char *destination); +void link_dir(int src, int dest); void clone_dir(int src, int dest); int getattr(const char *path, struct file_attr *a); int getattrat(int dirfd, const char *pathname, struct file_attr *a); diff --git a/native/jni/utils/file.c b/native/jni/utils/file.c index 021c142b5..4e4e81410 100644 --- a/native/jni/utils/file.c +++ b/native/jni/utils/file.c @@ -228,6 +228,33 @@ void clone_dir(int src, int dest) { } } +void link_dir(int src, int dest) { + struct dirent *entry; + DIR *dir; + int newsrc, newdest; + struct file_attr a; + + dir = xfdopendir(src); + while ((entry = xreaddir(dir))) { + if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) + continue; + if (is_excl(entry->d_name)) + continue; + if (entry->d_type == DT_DIR) { + getattrat(src, entry->d_name, &a); + xmkdirat(dest, entry->d_name, a.st.st_mode & 0777); + setattrat(dest, entry->d_name, &a); + newsrc = xopenat(src, entry->d_name, O_RDONLY | O_CLOEXEC); + newdest = xopenat(dest, entry->d_name, O_RDONLY | O_CLOEXEC); + link_dir(newsrc, newdest); + close(newsrc); + close(newdest); + } else { + linkat(src, entry->d_name, dest, entry->d_name, 0); + } + } +} + int getattr(const char *path, struct file_attr *a) { if (xlstat(path, &a->st) == -1) return -1;