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

View File

@ -21,7 +21,7 @@ using namespace std;
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 {
// Do not 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(bc_svc, sizeof(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) {
@ -100,7 +100,7 @@ void RootFSInit::setup_rootfs() {
// Patch init.rc
FILE *rc = xfopen("/init.p.rc", "we");
patch_init_rc(rc);
patch_init_rc(rc, "/sbin");
fclose(rc);
clone_attr("/init.rc", "/init.p.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 ROOTBLK BLOCKDIR "/system_root"
#define MONOPOLICY "/sepolicy"
#define PATCHPOLICY "/sbin/.se"
#define LIBSELINUX "/system/" LIBNAME "/libselinux.so"
void SARBase::patch_rootdir() {
char tmp_dir[128];
char tmp_dir[16];
const char *sepol;
// TODO: dynamic paths
char *p = tmp_dir + sprintf(tmp_dir, "%s", "/sbin");
char *p;
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);
persist_dir = string(tmp_dir) + "/" MIRRDIR "/persist";
@ -255,18 +264,18 @@ void SARBase::patch_rootdir() {
fgetattr(src, &attr);
close(src);
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) {
// Force init to load monolithic policy
LOGD("Remove from init: " SPLIT_PLAT_CIL "\n");
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) {
// Redirect /sepolicy to tmpfs
LOGD("Patch init [" MONOPOLICY "] -> [" PATCHPOLICY "]\n");
memcpy(p, PATCHPOLICY, sizeof(PATCHPOLICY));
LOGD("Patch init [" MONOPOLICY "] -> [%s]\n", sepol);
strcpy(reinterpret_cast<char *>(p), sepol);
redirect = true;
p += sizeof(MONOPOLICY) - 1;
p += sizeof(MONOPOLICY);
} else {
++p;
}
}
xmkdir(ROOTOVL, 0);
@ -275,18 +284,16 @@ void SARBase::patch_rootdir() {
fsetattr(dest, &attr);
close(dest);
// Patch libselinux
if (!redirect) {
raw_data lib;
// init is dynamically linked, need to patch libselinux
raw_data lib;
full_read(LIBSELINUX, lib.buf, lib.sz);
getattr(LIBSELINUX, &attr);
eof = lib.buf + lib.sz;
for (uint8_t *p = lib.buf; p < eof; ++p) {
if (memcmp(p, MONOPOLICY, sizeof(MONOPOLICY)) == 0) {
// Redirect /sepolicy to tmpfs
LOGD("Patch libselinux.so [" MONOPOLICY "] -> [" PATCHPOLICY "]\n");
memcpy(p, PATCHPOLICY, sizeof(PATCHPOLICY));
LOGD("Patch libselinux.so [" MONOPOLICY "] -> [%s]\n", sepol);
strcpy(reinterpret_cast<char *>(p), sepol);
break;
}
}
@ -299,7 +306,7 @@ void SARBase::patch_rootdir() {
}
// sepolicy
patch_sepolicy(PATCHPOLICY);
patch_sepolicy(sepol);
// Handle overlay
struct sockaddr_un sun;
@ -327,7 +334,7 @@ void SARBase::patch_rootdir() {
// Patch init.rc
FILE *rc = xfopen(ROOTOVL "/init.rc", "we");
patch_init_rc(rc);
patch_init_rc(rc, tmp_dir);
fclose(rc);
clone_attr("/init.rc", ROOTOVL "/init.rc");

View File

@ -46,7 +46,7 @@ constexpr char ALPHANUM[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY
static bool seeded = false;
static std::mt19937 gen;
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 (access("/dev/urandom", F_OK) != 0)
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)
buf[i] = ALPHANUM[dist(gen)];
buf[len - 1] = '\0';
return len - 1;
}
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);
uint32_t binary_gcd(uint32_t u, uint32_t v);
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);