Support cases when /sbin does not exist

This commit is contained in:
topjohnwu 2020-04-18 23:19:19 -07:00
parent d959c35723
commit 4c959cd983
4 changed files with 36 additions and 28 deletions

View File

@ -7,18 +7,18 @@ constexpr char magiskrc[] =
"on post-fs-data\n" "on post-fs-data\n"
" start logd\n" " start logd\n"
" rm " UNBLOCKFILE "\n" " rm " UNBLOCKFILE "\n"
" start %s\n" " start %2$s\n"
" wait " UNBLOCKFILE " 10\n" " wait " UNBLOCKFILE " 10\n"
" rm " UNBLOCKFILE "\n" " rm " UNBLOCKFILE "\n"
"\n" "\n"
"service %s /sbin/magisk --post-fs-data\n" "service %2$s %1$s/magisk --post-fs-data\n"
" user root\n" " user root\n"
" seclabel u:r:" SEPOL_PROC_DOMAIN ":s0\n" " seclabel u:r:" SEPOL_PROC_DOMAIN ":s0\n"
" oneshot\n" " oneshot\n"
"\n" "\n"
"service %s /sbin/magisk --service\n" "service %3$s %1$s/magisk --service\n"
" class late_start\n" " class late_start\n"
" user root\n" " user root\n"
" seclabel u:r:" SEPOL_PROC_DOMAIN ":s0\n" " seclabel u:r:" SEPOL_PROC_DOMAIN ":s0\n"
@ -26,10 +26,10 @@ constexpr char magiskrc[] =
"\n" "\n"
"on property:sys.boot_completed=1\n" "on property:sys.boot_completed=1\n"
" start %s\n" " start %4$s\n"
"\n" "\n"
"service %s /sbin/magisk --boot-complete\n" "service %4$s %1$s/magisk --boot-complete\n"
" user root\n" " user root\n"
" seclabel u:r:" SEPOL_PROC_DOMAIN ":s0\n" " seclabel u:r:" SEPOL_PROC_DOMAIN ":s0\n"
" oneshot\n" " oneshot\n"

View File

@ -21,7 +21,7 @@ using namespace std;
static vector<raw_data> rc_list; static vector<raw_data> rc_list;
static void patch_init_rc(FILE *rc) { static void patch_init_rc(FILE *rc, const char *tmp_dir) {
file_readline("/init.rc", [=](string_view line) -> bool { file_readline("/init.rc", [=](string_view line) -> bool {
// Do not start vaultkeeper // Do not start vaultkeeper
if (str_contains(line, "start vaultkeeper")) { if (str_contains(line, "start vaultkeeper")) {
@ -52,7 +52,7 @@ static void patch_init_rc(FILE *rc) {
gen_rand_str(ls_svc, sizeof(ls_svc)); gen_rand_str(ls_svc, sizeof(ls_svc));
gen_rand_str(bc_svc, sizeof(bc_svc)); gen_rand_str(bc_svc, sizeof(bc_svc));
LOGD("Inject magisk services: [%s] [%s] [%s]\n", pfd_svc, ls_svc, bc_svc); LOGD("Inject magisk services: [%s] [%s] [%s]\n", pfd_svc, ls_svc, bc_svc);
fprintf(rc, magiskrc, pfd_svc, pfd_svc, ls_svc, bc_svc, bc_svc); fprintf(rc, magiskrc, tmp_dir, pfd_svc, ls_svc, bc_svc);
} }
static void load_overlay_rc(const char *overlay) { static void load_overlay_rc(const char *overlay) {
@ -100,7 +100,7 @@ void RootFSInit::setup_rootfs() {
// Patch init.rc // Patch init.rc
FILE *rc = xfopen("/init.p.rc", "we"); FILE *rc = xfopen("/init.p.rc", "we");
patch_init_rc(rc); patch_init_rc(rc, "/sbin");
fclose(rc); fclose(rc);
clone_attr("/init.rc", "/init.p.rc"); clone_attr("/init.rc", "/init.p.rc");
rename("/init.p.rc", "/init.rc"); rename("/init.p.rc", "/init.rc");
@ -218,14 +218,23 @@ static void magic_mount(const string &sdir, const string &ddir = "") {
#define ROOTMIR MIRRDIR "/system_root" #define ROOTMIR MIRRDIR "/system_root"
#define ROOTBLK BLOCKDIR "/system_root" #define ROOTBLK BLOCKDIR "/system_root"
#define MONOPOLICY "/sepolicy" #define MONOPOLICY "/sepolicy"
#define PATCHPOLICY "/sbin/.se"
#define LIBSELINUX "/system/" LIBNAME "/libselinux.so" #define LIBSELINUX "/system/" LIBNAME "/libselinux.so"
void SARBase::patch_rootdir() { void SARBase::patch_rootdir() {
char tmp_dir[128]; char tmp_dir[16];
const char *sepol;
// TODO: dynamic paths char *p;
char *p = tmp_dir + sprintf(tmp_dir, "%s", "/sbin"); if (access("/sbin", F_OK) == 0) {
p = tmp_dir + sprintf(tmp_dir, "%s", "/sbin");
sepol = "/sbin/.se";
} else {
strcpy(tmp_dir, "/dev/");
p = tmp_dir + 5;
p += gen_rand_str(p, 10);
xmkdir(tmp_dir, 0);
sepol = "/dev/.se";
}
setup_tmp(tmp_dir, self, config); setup_tmp(tmp_dir, self, config);
persist_dir = string(tmp_dir) + "/" MIRRDIR "/persist"; persist_dir = string(tmp_dir) + "/" MIRRDIR "/persist";
@ -255,18 +264,18 @@ void SARBase::patch_rootdir() {
fgetattr(src, &attr); fgetattr(src, &attr);
close(src); close(src);
uint8_t *eof = init.buf + init.sz; uint8_t *eof = init.buf + init.sz;
for (uint8_t *p = init.buf; p < eof; ++p) { for (uint8_t *p = init.buf; p < eof;) {
if (memcmp(p, SPLIT_PLAT_CIL, sizeof(SPLIT_PLAT_CIL)) == 0) { if (memcmp(p, SPLIT_PLAT_CIL, sizeof(SPLIT_PLAT_CIL)) == 0) {
// Force init to load monolithic policy
LOGD("Remove from init: " SPLIT_PLAT_CIL "\n"); LOGD("Remove from init: " SPLIT_PLAT_CIL "\n");
memset(p, 'x', sizeof(SPLIT_PLAT_CIL) - 1); memset(p, 'x', sizeof(SPLIT_PLAT_CIL) - 1);
p += sizeof(SPLIT_PLAT_CIL) - 1; p += sizeof(SPLIT_PLAT_CIL);
} else if (memcmp(p, MONOPOLICY, sizeof(MONOPOLICY)) == 0) { } else if (memcmp(p, MONOPOLICY, sizeof(MONOPOLICY)) == 0) {
// Redirect /sepolicy to tmpfs LOGD("Patch init [" MONOPOLICY "] -> [%s]\n", sepol);
LOGD("Patch init [" MONOPOLICY "] -> [" PATCHPOLICY "]\n"); strcpy(reinterpret_cast<char *>(p), sepol);
memcpy(p, PATCHPOLICY, sizeof(PATCHPOLICY));
redirect = true; redirect = true;
p += sizeof(MONOPOLICY) - 1; p += sizeof(MONOPOLICY);
} else {
++p;
} }
} }
xmkdir(ROOTOVL, 0); xmkdir(ROOTOVL, 0);
@ -275,18 +284,16 @@ void SARBase::patch_rootdir() {
fsetattr(dest, &attr); fsetattr(dest, &attr);
close(dest); close(dest);
// Patch libselinux
if (!redirect) { if (!redirect) {
raw_data lib;
// init is dynamically linked, need to patch libselinux // init is dynamically linked, need to patch libselinux
raw_data lib;
full_read(LIBSELINUX, lib.buf, lib.sz); full_read(LIBSELINUX, lib.buf, lib.sz);
getattr(LIBSELINUX, &attr); getattr(LIBSELINUX, &attr);
eof = lib.buf + lib.sz; eof = lib.buf + lib.sz;
for (uint8_t *p = lib.buf; p < eof; ++p) { for (uint8_t *p = lib.buf; p < eof; ++p) {
if (memcmp(p, MONOPOLICY, sizeof(MONOPOLICY)) == 0) { if (memcmp(p, MONOPOLICY, sizeof(MONOPOLICY)) == 0) {
// Redirect /sepolicy to tmpfs LOGD("Patch libselinux.so [" MONOPOLICY "] -> [%s]\n", sepol);
LOGD("Patch libselinux.so [" MONOPOLICY "] -> [" PATCHPOLICY "]\n"); strcpy(reinterpret_cast<char *>(p), sepol);
memcpy(p, PATCHPOLICY, sizeof(PATCHPOLICY));
break; break;
} }
} }
@ -299,7 +306,7 @@ void SARBase::patch_rootdir() {
} }
// sepolicy // sepolicy
patch_sepolicy(PATCHPOLICY); patch_sepolicy(sepol);
// Handle overlay // Handle overlay
struct sockaddr_un sun; struct sockaddr_un sun;
@ -327,7 +334,7 @@ void SARBase::patch_rootdir() {
// Patch init.rc // Patch init.rc
FILE *rc = xfopen(ROOTOVL "/init.rc", "we"); FILE *rc = xfopen(ROOTOVL "/init.rc", "we");
patch_init_rc(rc); patch_init_rc(rc, tmp_dir);
fclose(rc); fclose(rc);
clone_attr("/init.rc", ROOTOVL "/init.rc"); clone_attr("/init.rc", ROOTOVL "/init.rc");

View File

@ -46,7 +46,7 @@ constexpr char ALPHANUM[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY
static bool seeded = false; static bool seeded = false;
static std::mt19937 gen; static std::mt19937 gen;
static std::uniform_int_distribution<int> dist(0, sizeof(ALPHANUM) - 2); static std::uniform_int_distribution<int> dist(0, sizeof(ALPHANUM) - 2);
void gen_rand_str(char *buf, int len, bool varlen) { int gen_rand_str(char *buf, int len, bool varlen) {
if (!seeded) { if (!seeded) {
if (access("/dev/urandom", F_OK) != 0) if (access("/dev/urandom", F_OK) != 0)
mknod("/dev/urandom", 0600 | S_IFCHR, makedev(1, 9)); mknod("/dev/urandom", 0600 | S_IFCHR, makedev(1, 9));
@ -64,6 +64,7 @@ void gen_rand_str(char *buf, int len, bool varlen) {
for (int i = 0; i < len - 1; ++i) for (int i = 0; i < len - 1; ++i)
buf[i] = ALPHANUM[dist(gen)]; buf[i] = ALPHANUM[dist(gen)];
buf[len - 1] = '\0'; buf[len - 1] = '\0';
return len - 1;
} }
int strend(const char *s1, const char *s2) { int strend(const char *s1, const char *s2) {

View File

@ -105,4 +105,4 @@ void init_argv0(int argc, char **argv);
void set_nice_name(const char *name); void set_nice_name(const char *name);
uint32_t binary_gcd(uint32_t u, uint32_t v); uint32_t binary_gcd(uint32_t u, uint32_t v);
int switch_mnt_ns(int pid); int switch_mnt_ns(int pid);
void gen_rand_str(char *buf, int len, bool varlen = true); int gen_rand_str(char *buf, int len, bool varlen = true);