mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-12-25 21:47:37 +00:00
More complete support for fstab in dt
This commit is contained in:
parent
8ab045331b
commit
0c99c4d93f
@ -12,11 +12,9 @@
|
|||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
#define DEFAULT_DT_DIR "/proc/device-tree/firmware/android"
|
|
||||||
|
|
||||||
static void parse_cmdline(const std::function<void (std::string_view, const char *)> &fn) {
|
static void parse_cmdline(const std::function<void (std::string_view, const char *)> &fn) {
|
||||||
char cmdline[4096];
|
char cmdline[4096];
|
||||||
int fd = open("/proc/cmdline", O_RDONLY | O_CLOEXEC);
|
int fd = xopen("/proc/cmdline", O_RDONLY | O_CLOEXEC);
|
||||||
cmdline[read(fd, cmdline, sizeof(cmdline))] = '\0';
|
cmdline[read(fd, cmdline, sizeof(cmdline))] = '\0';
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
@ -125,7 +123,10 @@ void load_kernel_info(cmdline *cmd) {
|
|||||||
} else if (key == "enter_recovery") {
|
} else if (key == "enter_recovery") {
|
||||||
enter_recovery = value[0] == '1';
|
enter_recovery = value[0] == '1';
|
||||||
} else if (key == "androidboot.hardware") {
|
} else if (key == "androidboot.hardware") {
|
||||||
|
strcpy(cmd->hardware, value);
|
||||||
kirin = strstr(value, "kirin") || strstr(value, "hi3660") || strstr(value, "hi6250");
|
kirin = strstr(value, "kirin") || strstr(value, "hi3660") || strstr(value, "hi6250");
|
||||||
|
} else if (key == "androidboot.hardware.platform") {
|
||||||
|
strcpy(cmd->hardware_plat, value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -154,8 +155,11 @@ void load_kernel_info(cmdline *cmd) {
|
|||||||
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("Device info:\n");
|
||||||
LOGD("skip_initramfs=[%d]\n", cmd->skip_initramfs);
|
LOGD("skip_initramfs=[%d]\n", cmd->skip_initramfs);
|
||||||
LOGD("force_normal_boot=[%d]\n", cmd->force_normal_boot);
|
LOGD("force_normal_boot=[%d]\n", cmd->force_normal_boot);
|
||||||
LOGD("slot=[%s]\n", cmd->slot);
|
LOGD("slot=[%s]\n", cmd->slot);
|
||||||
LOGD("dt_dir=[%s]\n", cmd->dt_dir);
|
LOGD("dt_dir=[%s]\n", cmd->dt_dir);
|
||||||
|
LOGD("hardware=[%s]\n", cmd->hardware);
|
||||||
|
LOGD("hardware.platform=[%s]\n", cmd->hardware_plat);
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#include <logging.hpp>
|
#include <logging.hpp>
|
||||||
|
|
||||||
@ -11,7 +12,9 @@ struct cmdline {
|
|||||||
bool skip_initramfs;
|
bool skip_initramfs;
|
||||||
bool force_normal_boot;
|
bool force_normal_boot;
|
||||||
char slot[3];
|
char slot[3];
|
||||||
char dt_dir[128];
|
char dt_dir[64];
|
||||||
|
char hardware[32];
|
||||||
|
char hardware_plat[32];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct raw_data {
|
struct raw_data {
|
||||||
@ -31,6 +34,30 @@ struct raw_data {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct fstab_entry {
|
||||||
|
std::string dev;
|
||||||
|
std::string mnt_point;
|
||||||
|
std::string type;
|
||||||
|
std::string mnt_flags;
|
||||||
|
std::string fsmgr_flags;
|
||||||
|
|
||||||
|
fstab_entry() = default;
|
||||||
|
fstab_entry(const fstab_entry &o) = delete;
|
||||||
|
fstab_entry(fstab_entry &&o) = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define INIT_SOCKET "MAGISKINIT"
|
||||||
|
#define DEFAULT_DT_DIR "/proc/device-tree/firmware/android"
|
||||||
|
|
||||||
|
void load_kernel_info(cmdline *cmd);
|
||||||
|
int dump_magisk(const char *path, mode_t mode);
|
||||||
|
int magisk_proxy_main(int argc, char *argv[]);
|
||||||
|
void setup_klog();
|
||||||
|
void setup_tmp(const char *path, const raw_data &self, const raw_data &config);
|
||||||
|
|
||||||
|
using str_pairs = std::initializer_list<std::pair<std::string_view, std::string_view>>;
|
||||||
|
int raw_data_patch(void *addr, size_t sz, str_pairs list);
|
||||||
|
|
||||||
/***************
|
/***************
|
||||||
* Base classes
|
* Base classes
|
||||||
***************/
|
***************/
|
||||||
@ -52,6 +79,8 @@ public:
|
|||||||
cmd(cmd), argv(argv), mount_list{"/sys", "/proc"} {}
|
cmd(cmd), argv(argv), mount_list{"/sys", "/proc"} {}
|
||||||
virtual ~BaseInit() = default;
|
virtual ~BaseInit() = default;
|
||||||
virtual void start() = 0;
|
virtual void start() = 0;
|
||||||
|
void read_dt_fstab(std::map<std::string_view, fstab_entry> &fstab);
|
||||||
|
void dt_early_mount();
|
||||||
};
|
};
|
||||||
|
|
||||||
class MagiskInit : public BaseInit {
|
class MagiskInit : public BaseInit {
|
||||||
@ -158,11 +187,3 @@ public:
|
|||||||
exec_init();
|
exec_init();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#define INIT_SOCKET "MAGISKINIT"
|
|
||||||
|
|
||||||
void load_kernel_info(cmdline *cmd);
|
|
||||||
int dump_magisk(const char *path, mode_t mode);
|
|
||||||
int magisk_proxy_main(int argc, char *argv[]);
|
|
||||||
void setup_klog();
|
|
||||||
void setup_tmp(const char *path, const raw_data &self, const raw_data &config);
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include <sys/sysmacros.h>
|
#include <sys/sysmacros.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <libgen.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <utils.hpp>
|
#include <utils.hpp>
|
||||||
@ -21,10 +22,6 @@ struct devinfo {
|
|||||||
|
|
||||||
static vector<devinfo> dev_list;
|
static vector<devinfo> dev_list;
|
||||||
|
|
||||||
static char partname[32];
|
|
||||||
static char fstype[32];
|
|
||||||
static char block_dev[64];
|
|
||||||
|
|
||||||
static void parse_device(devinfo *dev, const char *uevent) {
|
static void parse_device(devinfo *dev, const char *uevent) {
|
||||||
dev->partname[0] = '\0';
|
dev->partname[0] = '\0';
|
||||||
parse_prop_file(uevent, [=](string_view key, string_view value) -> bool {
|
parse_prop_file(uevent, [=](string_view key, string_view value) -> bool {
|
||||||
@ -55,6 +52,11 @@ static void collect_devices() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
char partname[32];
|
||||||
|
char block_dev[64];
|
||||||
|
} blk_info;
|
||||||
|
|
||||||
static int64_t setup_block(bool write_block = true) {
|
static int64_t setup_block(bool write_block = true) {
|
||||||
if (dev_list.empty())
|
if (dev_list.empty())
|
||||||
collect_devices();
|
collect_devices();
|
||||||
@ -63,13 +65,13 @@ static int64_t setup_block(bool write_block = true) {
|
|||||||
|
|
||||||
for (int tries = 0; tries < 3; ++tries) {
|
for (int tries = 0; tries < 3; ++tries) {
|
||||||
for (auto &dev : dev_list) {
|
for (auto &dev : dev_list) {
|
||||||
if (strcasecmp(dev.partname, partname) == 0) {
|
if (strcasecmp(dev.partname, blk_info.partname) == 0) {
|
||||||
if (write_block) {
|
if (write_block) {
|
||||||
sprintf(block_dev, "/dev/block/%s", dev.devname);
|
sprintf(blk_info.block_dev, "/dev/block/%s", dev.devname);
|
||||||
}
|
}
|
||||||
LOGD("Found %s: [%s] (%d, %d)\n", dev.partname, dev.devname, dev.major, dev.minor);
|
LOGD("Setup %s: [%s] (%d, %d)\n", dev.partname, dev.devname, dev.major, dev.minor);
|
||||||
dev_t rdev = makedev(dev.major, dev.minor);
|
dev_t rdev = makedev(dev.major, dev.minor);
|
||||||
mknod(block_dev, S_IFBLK | 0600, rdev);
|
mknod(blk_info.block_dev, S_IFBLK | 0600, rdev);
|
||||||
return rdev;
|
return rdev;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -90,35 +92,69 @@ static bool is_lnk(const char *name) {
|
|||||||
return S_ISLNK(st.st_mode);
|
return S_ISLNK(st.st_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool read_dt_fstab(cmdline *cmd, const char *name) {
|
static string rtrim(string &&str) {
|
||||||
char path[128];
|
// Trim space, newline, and null byte from end of string
|
||||||
int fd;
|
while (memchr(" \n\r", str[str.length() - 1], 4))
|
||||||
sprintf(path, "%s/fstab/%s/dev", cmd->dt_dir, name);
|
str.pop_back();
|
||||||
if ((fd = open(path, O_RDONLY | O_CLOEXEC)) >= 0) {
|
return std::move(str);
|
||||||
read(fd, path, sizeof(path));
|
|
||||||
close(fd);
|
|
||||||
path[strcspn(path, "\r\n")] = '\0';
|
|
||||||
// Some custom treble use different names, so use what we read
|
|
||||||
char *part = rtrim(strrchr(path, '/') + 1);
|
|
||||||
sprintf(partname, "%s%s", part, strend(part, cmd->slot) ? cmd->slot : "");
|
|
||||||
sprintf(path, "%s/fstab/%s/type", cmd->dt_dir, name);
|
|
||||||
if ((fd = xopen(path, O_RDONLY | O_CLOEXEC)) >= 0) {
|
|
||||||
read(fd, fstype, 32);
|
|
||||||
close(fd);
|
|
||||||
fstype[strcspn(fstype, "\r\n")] = '\0';
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define mount_root(name) \
|
#define read_info(val) \
|
||||||
if (!is_lnk("/" #name) && read_dt_fstab(cmd, #name)) { \
|
if (access(#val, F_OK) == 0) {\
|
||||||
LOGD("Early mount " #name "\n"); \
|
entry.val = rtrim(full_read(#val)); \
|
||||||
setup_block(); \
|
}
|
||||||
xmkdir("/" #name, 0755); \
|
|
||||||
xmount(block_dev, "/" #name, fstype, MS_RDONLY, nullptr); \
|
void BaseInit::read_dt_fstab(map<string_view, fstab_entry> &fstab) {
|
||||||
mount_list.emplace_back("/" #name); \
|
if (access(cmd->dt_dir, F_OK) != 0)
|
||||||
|
return;
|
||||||
|
chdir(cmd->dt_dir);
|
||||||
|
run_finally cr([]{ chdir("/"); });
|
||||||
|
|
||||||
|
if (access("fstab", F_OK) != 0)
|
||||||
|
return;
|
||||||
|
chdir("fstab");
|
||||||
|
|
||||||
|
auto dir = xopen_dir(".");
|
||||||
|
for (dirent *dp; (dp = xreaddir(dir.get()));) {
|
||||||
|
if (dp->d_type != DT_DIR)
|
||||||
|
continue;
|
||||||
|
chdir(dp->d_name);
|
||||||
|
run_finally f([]{ chdir(".."); });
|
||||||
|
|
||||||
|
if (access("status", F_OK) == 0) {
|
||||||
|
auto status = rtrim(full_read("status"));
|
||||||
|
if (status != "okay" && status != "ok")
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
fstab_entry entry;
|
||||||
|
|
||||||
|
read_info(dev);
|
||||||
|
read_info(mnt_point) else {
|
||||||
|
entry.mnt_point = "/";
|
||||||
|
entry.mnt_point += dp->d_name;
|
||||||
|
}
|
||||||
|
read_info(type);
|
||||||
|
read_info(mnt_flags);
|
||||||
|
read_info(fsmgr_flags);
|
||||||
|
|
||||||
|
fstab.emplace(entry.mnt_point, std::move(entry));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseInit::dt_early_mount() {
|
||||||
|
map<string_view, fstab_entry> fstab;
|
||||||
|
read_dt_fstab(fstab);
|
||||||
|
for (const auto &[_, entry] : fstab) {
|
||||||
|
if (is_lnk(entry.mnt_point.data()))
|
||||||
|
continue;
|
||||||
|
// Derive partname from dev
|
||||||
|
sprintf(blk_info.partname, "%s%s", basename(entry.dev.data()), cmd->slot);
|
||||||
|
setup_block();
|
||||||
|
xmkdir(entry.mnt_point.data(), 0755);
|
||||||
|
xmount(blk_info.block_dev, entry.mnt_point.data(), entry.type.data(), MS_RDONLY, nullptr);
|
||||||
|
mount_list.push_back(entry.mnt_point);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void switch_root(const string &path) {
|
static void switch_root(const string &path) {
|
||||||
@ -152,17 +188,17 @@ static void switch_root(const string &path) {
|
|||||||
|
|
||||||
static void mount_persist(const char *dev_base, const char *mnt_base) {
|
static void mount_persist(const char *dev_base, const char *mnt_base) {
|
||||||
string mnt_point = mnt_base + "/persist"s;
|
string mnt_point = mnt_base + "/persist"s;
|
||||||
strcpy(partname, "persist");
|
strcpy(blk_info.partname, "persist");
|
||||||
xrealpath(dev_base, block_dev);
|
xrealpath(dev_base, blk_info.block_dev);
|
||||||
char *s = block_dev + strlen(block_dev);
|
char *s = blk_info.block_dev + strlen(blk_info.block_dev);
|
||||||
strcpy(s, "/persist");
|
strcpy(s, "/persist");
|
||||||
if (setup_block(false) < 0) {
|
if (setup_block(false) < 0) {
|
||||||
// Fallback to cache
|
// Fallback to cache
|
||||||
strcpy(partname, "cache");
|
strcpy(blk_info.partname, "cache");
|
||||||
strcpy(s, "/cache");
|
strcpy(s, "/cache");
|
||||||
if (setup_block(false) < 0) {
|
if (setup_block(false) < 0) {
|
||||||
// Try NVIDIA's BS
|
// Try NVIDIA's BS
|
||||||
strcpy(partname, "CAC");
|
strcpy(blk_info.partname, "CAC");
|
||||||
if (setup_block(false) < 0)
|
if (setup_block(false) < 0)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -170,19 +206,16 @@ static void mount_persist(const char *dev_base, const char *mnt_base) {
|
|||||||
mnt_point = mnt_base + "/cache"s;
|
mnt_point = mnt_base + "/cache"s;
|
||||||
}
|
}
|
||||||
xmkdir(mnt_point.data(), 0755);
|
xmkdir(mnt_point.data(), 0755);
|
||||||
xmount(block_dev, mnt_point.data(), "ext4", 0, nullptr);
|
xmount(blk_info.block_dev, mnt_point.data(), "ext4", 0, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RootFSInit::early_mount() {
|
void RootFSInit::early_mount() {
|
||||||
full_read("/init", self.buf, self.sz);
|
full_read("/init", self.buf, self.sz);
|
||||||
|
|
||||||
LOGD("Reverting /init\n");
|
LOGD("Restoring /init\n");
|
||||||
rename("/.backup/init", "/init");
|
rename("/.backup/init", "/init");
|
||||||
|
|
||||||
mount_root(system);
|
dt_early_mount();
|
||||||
mount_root(vendor);
|
|
||||||
mount_root(product);
|
|
||||||
mount_root(odm);
|
|
||||||
|
|
||||||
xmkdir("/dev/mnt", 0755);
|
xmkdir("/dev/mnt", 0755);
|
||||||
mount_persist("/dev/block", "/dev/mnt");
|
mount_persist("/dev/block", "/dev/mnt");
|
||||||
@ -201,12 +234,12 @@ void SARBase::backup_files() {
|
|||||||
|
|
||||||
void SARBase::mount_system_root() {
|
void SARBase::mount_system_root() {
|
||||||
LOGD("Early mount system_root\n");
|
LOGD("Early mount system_root\n");
|
||||||
sprintf(partname, "system%s", cmd->slot);
|
sprintf(blk_info.partname, "system%s", cmd->slot);
|
||||||
strcpy(block_dev, "/dev/root");
|
strcpy(blk_info.block_dev, "/dev/root");
|
||||||
auto dev = setup_block(false);
|
auto dev = setup_block(false);
|
||||||
if (dev < 0) {
|
if (dev < 0) {
|
||||||
// Try NVIDIA naming scheme
|
// Try NVIDIA naming scheme
|
||||||
strcpy(partname, "APP");
|
strcpy(blk_info.partname, "APP");
|
||||||
dev = setup_block(false);
|
dev = setup_block(false);
|
||||||
if (dev < 0) {
|
if (dev < 0) {
|
||||||
// We don't really know what to do at this point...
|
// We don't really know what to do at this point...
|
||||||
@ -230,9 +263,7 @@ void SARInit::early_mount() {
|
|||||||
mount_system_root();
|
mount_system_root();
|
||||||
switch_root("/system_root");
|
switch_root("/system_root");
|
||||||
|
|
||||||
mount_root(vendor);
|
dt_early_mount();
|
||||||
mount_root(product);
|
|
||||||
mount_root(odm);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SARFirstStageInit::early_mount() {
|
void SARFirstStageInit::early_mount() {
|
||||||
@ -262,15 +293,12 @@ void BaseInit::cleanup() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void patch_socket_name(const char *path) {
|
static void patch_socket_name(const char *path) {
|
||||||
|
char rstr[16];
|
||||||
|
gen_rand_str(rstr, sizeof(rstr));
|
||||||
char *buf;
|
char *buf;
|
||||||
size_t size;
|
size_t size;
|
||||||
mmap_rw(path, buf, size);
|
mmap_rw(path, buf, size);
|
||||||
for (int i = 0; i < size; ++i) {
|
raw_data_patch(buf, size, { make_pair(MAIN_SOCKET, rstr) });
|
||||||
if (memcmp(buf + i, MAIN_SOCKET, sizeof(MAIN_SOCKET)) == 0) {
|
|
||||||
gen_rand_str(buf + i, 16);
|
|
||||||
i += sizeof(MAIN_SOCKET);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
munmap(buf, size);
|
munmap(buf, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,19 +81,28 @@ static void load_overlay_rc(const char *overlay) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int raw_data_patch(void *addr, size_t sz, str_pairs list) {
|
||||||
|
int count = 0;
|
||||||
|
for (uint8_t *p = (uint8_t *)addr, *eof = (uint8_t *)addr + sz; p < eof; ++p) {
|
||||||
|
for (auto &[from, to] : list) {
|
||||||
|
if (memcmp(p, from.data(), from.length() + 1) == 0) {
|
||||||
|
LOGD("Replace [%s] -> [%s]\n", from.data(), to.data());
|
||||||
|
memset(p, 0, from.length());
|
||||||
|
memcpy(p, to.data(), to.length());
|
||||||
|
++count;
|
||||||
|
p += from.length();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
void RootFSInit::setup_rootfs() {
|
void RootFSInit::setup_rootfs() {
|
||||||
if (patch_sepolicy("/sepolicy")) {
|
if (patch_sepolicy("/sepolicy")) {
|
||||||
char *addr;
|
char *addr;
|
||||||
size_t size;
|
size_t size;
|
||||||
mmap_rw("/init", addr, size);
|
mmap_rw("/init", addr, size);
|
||||||
for (char *p = addr; p < addr + size; ++p) {
|
raw_data_patch(addr, size, {make_pair(SPLIT_PLAT_CIL, "xxx")});
|
||||||
if (memcmp(p, SPLIT_PLAT_CIL, sizeof(SPLIT_PLAT_CIL)) == 0) {
|
|
||||||
// Force init to load /sepolicy
|
|
||||||
LOGD("Remove from init: " SPLIT_PLAT_CIL "\n");
|
|
||||||
memset(p, 'x', sizeof(SPLIT_PLAT_CIL) - 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
munmap(addr, size);
|
munmap(addr, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,43 +268,26 @@ void SARBase::patch_rootdir() {
|
|||||||
|
|
||||||
// Patch init
|
// Patch init
|
||||||
raw_data init;
|
raw_data init;
|
||||||
bool redirect = false;
|
|
||||||
int src = xopen("/init", O_RDONLY | O_CLOEXEC);
|
int src = xopen("/init", O_RDONLY | O_CLOEXEC);
|
||||||
fd_full_read(src, init.buf, init.sz);
|
fd_full_read(src, init.buf, init.sz);
|
||||||
for (uint8_t *p = init.buf, *eof = init.buf + init.sz; p < eof;) {
|
int patch_count = raw_data_patch(init.buf, init.sz, {
|
||||||
if (memcmp(p, SPLIT_PLAT_CIL, sizeof(SPLIT_PLAT_CIL)) == 0) {
|
make_pair(SPLIT_PLAT_CIL, "xxx"), /* Force loading monolithic sepolicy */
|
||||||
LOGD("Remove from init: " SPLIT_PLAT_CIL "\n");
|
make_pair(MONOPOLICY, sepol) /* Redirect /sepolicy to custom path */
|
||||||
memset(p, 'x', sizeof(SPLIT_PLAT_CIL) - 1);
|
});
|
||||||
p += sizeof(SPLIT_PLAT_CIL);
|
|
||||||
} else if (memcmp(p, MONOPOLICY, sizeof(MONOPOLICY)) == 0) {
|
|
||||||
LOGD("Patch init [" MONOPOLICY "] -> [%s]\n", sepol);
|
|
||||||
strcpy(reinterpret_cast<char *>(p), sepol);
|
|
||||||
redirect = true;
|
|
||||||
p += sizeof(MONOPOLICY);
|
|
||||||
} else {
|
|
||||||
++p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
xmkdir(ROOTOVL, 0);
|
xmkdir(ROOTOVL, 0);
|
||||||
int dest = xopen(ROOTOVL "/init", O_CREAT | O_WRONLY | O_CLOEXEC);
|
int dest = xopen(ROOTOVL "/init", O_CREAT | O_WRONLY | O_CLOEXEC, 0);
|
||||||
xwrite(dest, init.buf, init.sz);
|
xwrite(dest, init.buf, init.sz);
|
||||||
fclone_attr(src, dest);
|
fclone_attr(src, dest);
|
||||||
close(src);
|
close(src);
|
||||||
close(dest);
|
close(dest);
|
||||||
|
|
||||||
if (!redirect) {
|
if (patch_count != 2 && access(LIBSELINUX, F_OK) == 0) {
|
||||||
// init is dynamically linked, need to patch libselinux
|
// init is dynamically linked, need to patch libselinux
|
||||||
raw_data lib;
|
raw_data lib;
|
||||||
full_read(LIBSELINUX, lib.buf, lib.sz);
|
full_read(LIBSELINUX, lib.buf, lib.sz);
|
||||||
for (uint8_t *p = lib.buf, *eof = lib.buf + lib.sz; p < eof; ++p) {
|
raw_data_patch(lib.buf, lib.sz, {make_pair(MONOPOLICY, sepol)});
|
||||||
if (memcmp(p, MONOPOLICY, sizeof(MONOPOLICY)) == 0) {
|
|
||||||
LOGD("Patch libselinux.so [" MONOPOLICY "] -> [%s]\n", sepol);
|
|
||||||
strcpy(reinterpret_cast<char *>(p), sepol);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
xmkdirs(dirname(ROOTOVL LIBSELINUX), 0755);
|
xmkdirs(dirname(ROOTOVL LIBSELINUX), 0755);
|
||||||
dest = xopen(ROOTOVL LIBSELINUX, O_CREAT | O_WRONLY | O_CLOEXEC);
|
dest = xopen(ROOTOVL LIBSELINUX, O_CREAT | O_WRONLY | O_CLOEXEC, 0);
|
||||||
xwrite(dest, lib.buf, lib.sz);
|
xwrite(dest, lib.buf, lib.sz);
|
||||||
close(dest);
|
close(dest);
|
||||||
clone_attr(LIBSELINUX, ROOTOVL LIBSELINUX);
|
clone_attr(LIBSELINUX, ROOTOVL LIBSELINUX);
|
||||||
|
@ -302,11 +302,10 @@ void full_read(const char *filename, void **buf, size_t *size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
string fd_full_read(int fd) {
|
string fd_full_read(int fd) {
|
||||||
|
char buf[4096];
|
||||||
string str;
|
string str;
|
||||||
auto len = lseek(fd, 0, SEEK_END);
|
for (ssize_t len; (len = xread(fd, buf, sizeof(buf))) > 0;)
|
||||||
str.resize(len);
|
str.insert(str.end(), buf, buf + len);
|
||||||
lseek(fd, 0, SEEK_SET);
|
|
||||||
xxread(fd, str.data(), len);
|
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,14 +164,6 @@ bool ends_with(const std::string_view &s1, const std::string_view &s2) {
|
|||||||
return l1 < l2 ? false : s1.compare(l1 - l2, l2, s2) == 0;
|
return l1 < l2 ? false : s1.compare(l1 - l2, l2, s2) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *rtrim(char *str) {
|
|
||||||
int len = strlen(str);
|
|
||||||
while (len > 0 && str[len - 1] == ' ')
|
|
||||||
--len;
|
|
||||||
str[len] = '\0';
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Bionic's atoi runs through strtol().
|
* Bionic's atoi runs through strtol().
|
||||||
* Use our own implementation for faster conversion.
|
* Use our own implementation for faster conversion.
|
||||||
|
@ -97,7 +97,6 @@ bool ends_with(const std::string_view &s1, const std::string_view &s2);
|
|||||||
int fork_dont_care();
|
int fork_dont_care();
|
||||||
int fork_no_zombie();
|
int fork_no_zombie();
|
||||||
int strend(const char *s1, const char *s2);
|
int strend(const char *s1, const char *s2);
|
||||||
char *rtrim(char *str);
|
|
||||||
void init_argv0(int argc, char **argv);
|
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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user