mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-11-27 20:15:29 +00:00
Update mmap implementation
Always map memory as writable, but private when read-only
This commit is contained in:
parent
9a28dd4f6e
commit
f2cb3c38fe
@ -213,6 +213,6 @@ bool check_two_stage() {
|
||||
if (access("/system/bin/init", F_OK) == 0)
|
||||
return true;
|
||||
// If we still have no indication, parse the original init and see what's up
|
||||
auto init = raw_data::mmap_ro("/.backup/init");
|
||||
auto init = mmap_data::ro("/.backup/init");
|
||||
return init.contains("selinux_setup");
|
||||
}
|
||||
|
@ -54,8 +54,8 @@ public:
|
||||
|
||||
class MagiskInit : public BaseInit {
|
||||
protected:
|
||||
auto_data<HEAP> self;
|
||||
auto_data<HEAP> config;
|
||||
mmap_data self;
|
||||
mmap_data config;
|
||||
std::string custom_rules_dir;
|
||||
|
||||
void mount_with_dt();
|
||||
|
@ -289,7 +289,7 @@ success:
|
||||
}
|
||||
|
||||
void RootFSInit::early_mount() {
|
||||
self = raw_data::read("/init");
|
||||
self = mmap_data::ro("/init");
|
||||
|
||||
LOGD("Restoring /init\n");
|
||||
rename("/.backup/init", "/init");
|
||||
@ -301,9 +301,9 @@ void SARBase::backup_files() {
|
||||
if (access("/overlay.d", F_OK) == 0)
|
||||
backup_folder("/overlay.d", overlays);
|
||||
|
||||
self = raw_data::read("/proc/self/exe");
|
||||
self = mmap_data::ro("/proc/self/exe");
|
||||
if (access("/.backup/.magisk", R_OK) == 0)
|
||||
config = raw_data::read("/.backup/.magisk");
|
||||
config = mmap_data::ro("/.backup/.magisk");
|
||||
}
|
||||
|
||||
void SARBase::mount_system_root() {
|
||||
@ -346,7 +346,7 @@ void SARInit::early_mount() {
|
||||
switch_root("/system_root");
|
||||
|
||||
{
|
||||
auto init = raw_data::mmap_ro("/init");
|
||||
auto init = mmap_data::ro("/init");
|
||||
is_two_stage = init.contains("selinux_setup");
|
||||
}
|
||||
LOGD("is_two_stage: [%d]\n", is_two_stage);
|
||||
@ -383,7 +383,7 @@ void BaseInit::exec_init() {
|
||||
static void patch_socket_name(const char *path) {
|
||||
char rstr[16];
|
||||
gen_rand_str(rstr, sizeof(rstr));
|
||||
auto bin = raw_data::mmap_rw(path);
|
||||
auto bin = mmap_data::rw(path);
|
||||
bin.patch({ make_pair(MAIN_SOCKET, rstr) });
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
int data_holder::patch(str_pairs list) {
|
||||
int mmap_data::patch(str_pairs list) {
|
||||
if (buf == nullptr)
|
||||
return 0;
|
||||
int count = 0;
|
||||
@ -20,7 +20,7 @@ int data_holder::patch(str_pairs list) {
|
||||
return count;
|
||||
}
|
||||
|
||||
bool data_holder::contains(string_view pattern) {
|
||||
bool mmap_data::contains(string_view pattern) {
|
||||
if (buf == nullptr)
|
||||
return false;
|
||||
for (uint8_t *p = buf, *eof = buf + sz; p < eof; ++p) {
|
||||
@ -32,33 +32,21 @@ bool data_holder::contains(string_view pattern) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void data_holder::consume(data_holder &other) {
|
||||
void mmap_data::consume(mmap_data &other) {
|
||||
buf = other.buf;
|
||||
sz = other.sz;
|
||||
other.buf = nullptr;
|
||||
other.sz = 0;
|
||||
}
|
||||
|
||||
auto_data<HEAP> raw_data::read(int fd) {
|
||||
auto_data<HEAP> data;
|
||||
fd_full_read(fd, data.buf, data.sz);
|
||||
mmap_data mmap_data::rw(const char *name) {
|
||||
mmap_data data;
|
||||
mmap_rw(name, data.buf, data.sz);
|
||||
return data;
|
||||
}
|
||||
|
||||
auto_data<HEAP> raw_data::read(const char *name) {
|
||||
auto_data<HEAP> data;
|
||||
full_read(name, data.buf, data.sz);
|
||||
return data;
|
||||
}
|
||||
|
||||
auto_data<MMAP> raw_data::mmap_rw(const char *name) {
|
||||
auto_data<MMAP> data;
|
||||
::mmap_rw(name, data.buf, data.sz);
|
||||
return data;
|
||||
}
|
||||
|
||||
auto_data<MMAP> raw_data::mmap_ro(const char *name) {
|
||||
auto_data<MMAP> data;
|
||||
::mmap_ro(name, data.buf, data.sz);
|
||||
mmap_data mmap_data::ro(const char *name) {
|
||||
mmap_data data;
|
||||
mmap_ro(name, data.buf, data.sz);
|
||||
return data;
|
||||
}
|
||||
|
@ -2,31 +2,23 @@
|
||||
|
||||
#include <utils.hpp>
|
||||
|
||||
struct data_holder {
|
||||
struct mmap_data {
|
||||
uint8_t *buf = nullptr;
|
||||
size_t sz = 0;
|
||||
|
||||
mmap_data() = default;
|
||||
mmap_data(const mmap_data&) = delete;
|
||||
mmap_data(mmap_data &&other) { consume(other); }
|
||||
~mmap_data() { if (buf) munmap(buf, sz); }
|
||||
mmap_data& operator=(mmap_data &&other) { consume(other); return *this; }
|
||||
|
||||
using str_pairs = std::initializer_list<std::pair<std::string_view, std::string_view>>;
|
||||
int patch(str_pairs list);
|
||||
bool contains(std::string_view pattern);
|
||||
protected:
|
||||
void consume(data_holder &other);
|
||||
};
|
||||
|
||||
enum data_type { HEAP, MMAP };
|
||||
template <data_type T>
|
||||
struct auto_data : public data_holder {
|
||||
auto_data<T>() = default;
|
||||
auto_data<T>(const auto_data&) = delete;
|
||||
auto_data<T>(auto_data<T> &&other) { consume(other); }
|
||||
~auto_data<T>() {}
|
||||
auto_data<T>& operator=(auto_data<T> &&other) { consume(other); return *this; }
|
||||
};
|
||||
template <> inline auto_data<MMAP>::~auto_data<MMAP>() { if (buf) munmap(buf, sz); }
|
||||
template <> inline auto_data<HEAP>::~auto_data<HEAP>() { free(buf); }
|
||||
static mmap_data rw(const char *name);
|
||||
static mmap_data ro(const char *name);
|
||||
|
||||
namespace raw_data {
|
||||
auto_data<HEAP> read(const char *name);
|
||||
auto_data<HEAP> read(int fd);
|
||||
auto_data<MMAP> mmap_rw(const char *name);
|
||||
auto_data<MMAP> mmap_ro(const char *name);
|
||||
}
|
||||
private:
|
||||
void consume(mmap_data &other);
|
||||
};
|
||||
|
@ -218,7 +218,7 @@ void SARBase::patch_rootdir() {
|
||||
int patch_count;
|
||||
{
|
||||
int src = xopen("/init", O_RDONLY | O_CLOEXEC);
|
||||
auto init = raw_data::read(src);
|
||||
auto init = mmap_data::ro("/init");
|
||||
patch_count = init.patch({
|
||||
make_pair(SPLIT_PLAT_CIL, "xxx"), /* Force loading monolithic sepolicy */
|
||||
make_pair(MONOPOLICY, sepol) /* Redirect /sepolicy to custom path */
|
||||
@ -233,7 +233,7 @@ void SARBase::patch_rootdir() {
|
||||
|
||||
if (patch_count != 2 && access(LIBSELINUX, F_OK) == 0) {
|
||||
// init is dynamically linked, need to patch libselinux
|
||||
auto lib = raw_data::read(LIBSELINUX);
|
||||
auto lib = mmap_data::ro(LIBSELINUX);
|
||||
lib.patch({make_pair(MONOPOLICY, sepol)});
|
||||
xmkdirs(dirname(ROOTOVL LIBSELINUX), 0755);
|
||||
int dest = xopen(ROOTOVL LIBSELINUX, O_CREAT | O_WRONLY | O_CLOEXEC, 0);
|
||||
@ -301,7 +301,7 @@ void RootFSInit::patch_rootfs() {
|
||||
}
|
||||
|
||||
if (patch_sepolicy("/sepolicy")) {
|
||||
auto init = raw_data::mmap_rw("/init");
|
||||
auto init = mmap_data::rw("/init");
|
||||
init.patch({ make_pair(SPLIT_PLAT_CIL, "xxx") });
|
||||
}
|
||||
|
||||
@ -331,8 +331,8 @@ void MagiskProxy::start() {
|
||||
xmount(nullptr, "/", nullptr, MS_REMOUNT, nullptr);
|
||||
|
||||
// Backup stuffs before removing them
|
||||
self = raw_data::read("/sbin/magisk");
|
||||
config = raw_data::read("/.backup/.magisk");
|
||||
self = mmap_data::ro("/sbin/magisk");
|
||||
config = mmap_data::ro("/.backup/.magisk");
|
||||
char custom_rules_dir[64];
|
||||
custom_rules_dir[0] = '\0';
|
||||
xreadlink(TMP_RULESDIR, custom_rules_dir, sizeof(custom_rules_dir));
|
||||
|
@ -114,7 +114,7 @@ void FirstStageInit::prepare() {
|
||||
}
|
||||
|
||||
// Patch init to force IsDtFstabCompatible() return false
|
||||
auto init = raw_data::mmap_rw("/init");
|
||||
auto init = mmap_data::rw("/init");
|
||||
init.patch({ make_pair("android,fstab", "xxx") });
|
||||
}
|
||||
|
||||
@ -150,7 +150,7 @@ void SARInit::first_stage_prep() {
|
||||
int src = xopen("/init", O_RDONLY);
|
||||
int dest = xopen("/dev/init", O_CREAT | O_WRONLY, 0);
|
||||
{
|
||||
auto init = raw_data::read(src);
|
||||
auto init = mmap_data::ro("/init");
|
||||
init.patch({ make_pair(INIT_PATH, REDIR_PATH) });
|
||||
write(dest, init.buf, init.sz);
|
||||
fclone_attr(src, dest);
|
||||
|
@ -279,7 +279,6 @@ void *__mmap(const char *filename, size_t *size, bool rw) {
|
||||
return nullptr;
|
||||
}
|
||||
struct stat st;
|
||||
void *buf;
|
||||
if (fstat(fd, &st)) {
|
||||
*size = 0;
|
||||
return nullptr;
|
||||
@ -288,7 +287,9 @@ void *__mmap(const char *filename, size_t *size, bool rw) {
|
||||
ioctl(fd, BLKGETSIZE64, size);
|
||||
else
|
||||
*size = st.st_size;
|
||||
buf = *size > 0 ? xmmap(nullptr, *size, PROT_READ | (rw ? PROT_WRITE : 0), MAP_SHARED, fd, 0) : nullptr;
|
||||
void *buf = *size > 0 ?
|
||||
xmmap(nullptr, *size, PROT_READ | PROT_WRITE, rw ? MAP_SHARED : MAP_PRIVATE, fd, 0) :
|
||||
nullptr;
|
||||
close(fd);
|
||||
return buf;
|
||||
}
|
||||
@ -437,3 +438,16 @@ sDIR make_dir(DIR *dp) {
|
||||
sFILE make_file(FILE *fp) {
|
||||
return sFILE(fp, [](FILE *fp){ return fp ? fclose(fp) : 1; });
|
||||
}
|
||||
|
||||
raw_file::raw_file(raw_file &&o) {
|
||||
path.swap(o.path);
|
||||
attr = o.attr;
|
||||
buf = o.buf;
|
||||
sz = o.sz;
|
||||
o.buf = nullptr;
|
||||
o.sz = 0;
|
||||
}
|
||||
|
||||
raw_file::~raw_file() {
|
||||
free(buf);
|
||||
}
|
||||
|
@ -21,22 +21,13 @@ struct file_attr {
|
||||
struct raw_file {
|
||||
std::string path;
|
||||
file_attr attr;
|
||||
uint8_t *buf = nullptr;
|
||||
size_t sz = 0;
|
||||
uint8_t *buf;
|
||||
size_t sz;
|
||||
|
||||
raw_file() = default;
|
||||
raw_file() : attr({}), buf(nullptr), sz(0) {}
|
||||
raw_file(const raw_file&) = delete;
|
||||
raw_file(raw_file &&d) {
|
||||
path = std::move(d.path);
|
||||
attr = d.attr;
|
||||
buf = d.buf;
|
||||
sz = d.sz;
|
||||
d.buf = nullptr;
|
||||
d.sz = 0;
|
||||
}
|
||||
~raw_file() {
|
||||
free(buf);
|
||||
}
|
||||
raw_file(raw_file &&o);
|
||||
~raw_file();
|
||||
};
|
||||
|
||||
ssize_t fd_path(int fd, char *path, size_t size);
|
||||
|
Loading…
Reference in New Issue
Block a user