mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-11-30 21:45:27 +00:00
Migrate to STL
This commit is contained in:
parent
03c39e692a
commit
3e4c12cf56
@ -13,6 +13,8 @@
|
|||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <sys/mount.h>
|
#include <sys/mount.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "magisk.h"
|
#include "magisk.h"
|
||||||
#include "db.h"
|
#include "db.h"
|
||||||
@ -23,8 +25,10 @@
|
|||||||
#include "selinux.h"
|
#include "selinux.h"
|
||||||
#include "flags.h"
|
#include "flags.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
static char buf[PATH_MAX], buf2[PATH_MAX];
|
static char buf[PATH_MAX], buf2[PATH_MAX];
|
||||||
static Vector<CharArray> module_list;
|
static vector<string> module_list;
|
||||||
static bool seperate_vendor;
|
static bool seperate_vendor;
|
||||||
|
|
||||||
char *system_block, *vendor_block, *magiskloop;
|
char *system_block, *vendor_block, *magiskloop;
|
||||||
@ -42,9 +46,9 @@ extern void auto_start_magiskhide();
|
|||||||
#define IS_SKEL 0x04 /* mount from skeleton */
|
#define IS_SKEL 0x04 /* mount from skeleton */
|
||||||
#define IS_MODULE 0x08 /* mount from module */
|
#define IS_MODULE 0x08 /* mount from module */
|
||||||
|
|
||||||
#define IS_DIR(n) (n->type == DT_DIR)
|
#define IS_DIR(n) ((n)->type == DT_DIR)
|
||||||
#define IS_LNK(n) (n->type == DT_LNK)
|
#define IS_LNK(n) ((n)->type == DT_LNK)
|
||||||
#define IS_REG(n) (n->type == DT_REG)
|
#define IS_REG(n) ((n)->type == DT_REG)
|
||||||
|
|
||||||
class node_entry {
|
class node_entry {
|
||||||
public:
|
public:
|
||||||
@ -56,15 +60,15 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
const char *module; /* Only used when status & IS_MODULE */
|
const char *module; /* Only used when status & IS_MODULE */
|
||||||
const CharArray name;
|
const string name;
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
uint8_t status;
|
uint8_t status;
|
||||||
node_entry *parent;
|
node_entry *parent;
|
||||||
Vector<node_entry *> children;
|
vector<node_entry *> children;
|
||||||
|
|
||||||
node_entry(const char *, const char *, uint8_t type);
|
node_entry(const char *, const char *, uint8_t type);
|
||||||
bool is_root();
|
bool is_root();
|
||||||
CharArray get_path();
|
string get_path();
|
||||||
node_entry *insert(node_entry *);
|
node_entry *insert(node_entry *);
|
||||||
void clone_skeleton();
|
void clone_skeleton();
|
||||||
int get_path(char *path);
|
int get_path(char *path);
|
||||||
@ -87,7 +91,7 @@ bool node_entry::is_root() {
|
|||||||
return parent == nullptr;
|
return parent == nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
CharArray node_entry::get_path() {
|
string node_entry::get_path() {
|
||||||
get_path(buf);
|
get_path(buf);
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
@ -123,7 +127,7 @@ void node_entry::create_module_tree(const char *module) {
|
|||||||
DIR *dir;
|
DIR *dir;
|
||||||
struct dirent *entry;
|
struct dirent *entry;
|
||||||
|
|
||||||
CharArray full_path = get_path();
|
auto full_path = get_path();
|
||||||
snprintf(buf, PATH_MAX, "%s/%s%s", MOUNTPOINT, module, full_path.c_str());
|
snprintf(buf, PATH_MAX, "%s/%s%s", MOUNTPOINT, module, full_path.c_str());
|
||||||
|
|
||||||
if (!(dir = xopendir(buf)))
|
if (!(dir = xopendir(buf)))
|
||||||
@ -133,7 +137,7 @@ void node_entry::create_module_tree(const char *module) {
|
|||||||
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
|
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
|
||||||
continue;
|
continue;
|
||||||
// Create new node
|
// Create new node
|
||||||
node_entry *node = new node_entry(module, entry->d_name, entry->d_type);
|
auto node = new node_entry(module, entry->d_name, entry->d_type);
|
||||||
snprintf(buf, PATH_MAX, "%s/%s", full_path.c_str(), entry->d_name);
|
snprintf(buf, PATH_MAX, "%s/%s", full_path.c_str(), entry->d_name);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -185,7 +189,7 @@ void node_entry::clone_skeleton() {
|
|||||||
struct node_entry *dummy;
|
struct node_entry *dummy;
|
||||||
|
|
||||||
// Clone the structure
|
// Clone the structure
|
||||||
CharArray full_path = get_path();
|
auto full_path = get_path();
|
||||||
snprintf(buf, PATH_MAX, "%s%s", MIRRDIR, full_path.c_str());
|
snprintf(buf, PATH_MAX, "%s%s", MIRRDIR, full_path.c_str());
|
||||||
if (!(dir = xopendir(buf)))
|
if (!(dir = xopendir(buf)))
|
||||||
return;
|
return;
|
||||||
@ -200,10 +204,10 @@ void node_entry::clone_skeleton() {
|
|||||||
|
|
||||||
if (status & IS_SKEL) {
|
if (status & IS_SKEL) {
|
||||||
file_attr attr;
|
file_attr attr;
|
||||||
getattr(full_path, &attr);
|
getattr(full_path.c_str(), &attr);
|
||||||
LOGI("mnt_tmpfs : %s\n", full_path.c_str());
|
LOGI("mnt_tmpfs : %s\n", full_path.c_str());
|
||||||
xmount("tmpfs", full_path, "tmpfs", 0, nullptr);
|
xmount("tmpfs", full_path.c_str(), "tmpfs", 0, nullptr);
|
||||||
setattr(full_path, &attr);
|
setattr(full_path.c_str(), &attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto &child : children) {
|
for (auto &child : children) {
|
||||||
@ -254,9 +258,9 @@ void node_entry::clone_skeleton() {
|
|||||||
void node_entry::magic_mount() {
|
void node_entry::magic_mount() {
|
||||||
if (status & IS_MODULE) {
|
if (status & IS_MODULE) {
|
||||||
// Mount module item
|
// Mount module item
|
||||||
CharArray real_path = get_path();
|
auto real_path = get_path();
|
||||||
snprintf(buf, PATH_MAX, "%s/%s%s", MOUNTPOINT, module, real_path.c_str());
|
snprintf(buf, PATH_MAX, "%s/%s%s", MOUNTPOINT, module, real_path.c_str());
|
||||||
bind_mount(buf, real_path);
|
bind_mount(buf, real_path.c_str());
|
||||||
} else if (status & IS_SKEL) {
|
} else if (status & IS_SKEL) {
|
||||||
// The node is labeled to be cloned with skeleton, lets do it
|
// The node is labeled to be cloned with skeleton, lets do it
|
||||||
clone_skeleton();
|
clone_skeleton();
|
||||||
@ -330,7 +334,8 @@ static void exec_common_script(const char* stage) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void exec_module_script(const char* stage) {
|
static void exec_module_script(const char* stage) {
|
||||||
for (const char *module : module_list) {
|
for (const auto &m : module_list) {
|
||||||
|
const auto module = m.c_str();
|
||||||
snprintf(buf2, PATH_MAX, "%s/%s/%s.sh", MOUNTPOINT, module, stage);
|
snprintf(buf2, PATH_MAX, "%s/%s/%s.sh", MOUNTPOINT, module, stage);
|
||||||
if (access(buf2, F_OK) == -1)
|
if (access(buf2, F_OK) == -1)
|
||||||
continue;
|
continue;
|
||||||
@ -364,7 +369,7 @@ static void simple_mount(const char *path) {
|
|||||||
if (access(buf2, F_OK) == -1)
|
if (access(buf2, F_OK) == -1)
|
||||||
continue;
|
continue;
|
||||||
if (entry->d_type == DT_DIR) {
|
if (entry->d_type == DT_DIR) {
|
||||||
simple_mount(CharArray(buf2));
|
simple_mount(string(buf2).c_str());
|
||||||
} else if (entry->d_type == DT_REG) {
|
} else if (entry->d_type == DT_REG) {
|
||||||
// Actual file path
|
// Actual file path
|
||||||
snprintf(buf, PATH_MAX, "%s%s", SIMPLEMOUNT, buf2);
|
snprintf(buf, PATH_MAX, "%s%s", SIMPLEMOUNT, buf2);
|
||||||
@ -431,21 +436,20 @@ static bool magisk_env() {
|
|||||||
xmkdir(SECURE_DIR "/post-fs-data.d", 0755);
|
xmkdir(SECURE_DIR "/post-fs-data.d", 0755);
|
||||||
xmkdir(SECURE_DIR "/service.d", 0755);
|
xmkdir(SECURE_DIR "/service.d", 0755);
|
||||||
|
|
||||||
CharArray sdk_prop = getprop("ro.build.version.sdk");
|
auto sdk_prop = getprop("ro.build.version.sdk");
|
||||||
int sdk = sdk_prop.empty() ? -1 : atoi(sdk_prop);
|
int sdk = sdk_prop.empty() ? -1 : atoi(sdk_prop.c_str());
|
||||||
|
|
||||||
LOGI("* Mounting mirrors");
|
LOGI("* Mounting mirrors");
|
||||||
Vector<CharArray> mounts;
|
auto mounts = file_to_vector("/proc/mounts");
|
||||||
file_to_vector("/proc/mounts", mounts);
|
|
||||||
bool system_as_root = false;
|
bool system_as_root = false;
|
||||||
for (auto &line : mounts) {
|
for (auto &line : mounts) {
|
||||||
if (line.contains(" /system_root ")) {
|
if (line.find(" /system_root ") != string::npos) {
|
||||||
bind_mount("/system_root/system", MIRRDIR "/system");
|
bind_mount("/system_root/system", MIRRDIR "/system");
|
||||||
sscanf(line, "%s", buf);
|
sscanf(line.c_str(), "%s", buf);
|
||||||
system_block = strdup2(buf);
|
system_block = strdup2(buf);
|
||||||
system_as_root = true;
|
system_as_root = true;
|
||||||
} else if (!system_as_root && line.contains(" /system ")) {
|
} else if (!system_as_root && line.find(" /system ") != string::npos) {
|
||||||
sscanf(line, "%s %*s %s", buf, buf2);
|
sscanf(line.c_str(), "%s %*s %s", buf, buf2);
|
||||||
system_block = strdup2(buf);
|
system_block = strdup2(buf);
|
||||||
xmount(system_block, MIRRDIR "/system", buf2, MS_RDONLY, nullptr);
|
xmount(system_block, MIRRDIR "/system", buf2, MS_RDONLY, nullptr);
|
||||||
#ifdef MAGISK_DEBUG
|
#ifdef MAGISK_DEBUG
|
||||||
@ -453,9 +457,9 @@ static bool magisk_env() {
|
|||||||
#else
|
#else
|
||||||
LOGI("mount: %s\n", MIRRDIR "/system");
|
LOGI("mount: %s\n", MIRRDIR "/system");
|
||||||
#endif
|
#endif
|
||||||
} else if (line.contains(" /vendor ")) {
|
} else if (line.find(" /vendor ") != string::npos) {
|
||||||
seperate_vendor = true;
|
seperate_vendor = true;
|
||||||
sscanf(line, "%s %*s %s", buf, buf2);
|
sscanf(line.c_str(), "%s %*s %s", buf, buf2);
|
||||||
vendor_block = strdup2(buf);
|
vendor_block = strdup2(buf);
|
||||||
xmkdir(MIRRDIR "/vendor", 0755);
|
xmkdir(MIRRDIR "/vendor", 0755);
|
||||||
xmount(buf, MIRRDIR "/vendor", buf2, MS_RDONLY, nullptr);
|
xmount(buf, MIRRDIR "/vendor", buf2, MS_RDONLY, nullptr);
|
||||||
@ -464,7 +468,9 @@ static bool magisk_env() {
|
|||||||
#else
|
#else
|
||||||
LOGI("mount: %s\n", MIRRDIR "/vendor");
|
LOGI("mount: %s\n", MIRRDIR "/vendor");
|
||||||
#endif
|
#endif
|
||||||
} else if (sdk >= 24 && line.contains(" /proc ") && !line.contains("hidepid=2")) {
|
} else if (sdk >= 24 &&
|
||||||
|
line.find(" /proc ") != string::npos &&
|
||||||
|
line.find("hidepid=2") == string::npos) {
|
||||||
// Enforce hidepid
|
// Enforce hidepid
|
||||||
xmount(nullptr, "/proc", nullptr, MS_REMOUNT, "hidepid=2,gid=3009");
|
xmount(nullptr, "/proc", nullptr, MS_REMOUNT, "hidepid=2,gid=3009");
|
||||||
}
|
}
|
||||||
@ -508,7 +514,7 @@ static void collect_modules() {
|
|||||||
}
|
}
|
||||||
unlink("update");
|
unlink("update");
|
||||||
if (access("disable", F_OK))
|
if (access("disable", F_OK))
|
||||||
module_list.push_back(entry->d_name);
|
module_list.emplace_back(entry->d_name);
|
||||||
chdir("..");
|
chdir("..");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -559,7 +565,7 @@ static bool prepare_img() {
|
|||||||
|
|
||||||
static void install_apk(const char *apk) {
|
static void install_apk(const char *apk) {
|
||||||
setfilecon(apk, "u:object_r:" SEPOL_FILE_DOMAIN ":s0");
|
setfilecon(apk, "u:object_r:" SEPOL_FILE_DOMAIN ":s0");
|
||||||
while (1) {
|
while (true) {
|
||||||
sleep(5);
|
sleep(5);
|
||||||
LOGD("apk_install: attempting to install APK\n");
|
LOGD("apk_install: attempting to install APK\n");
|
||||||
int fd = -1, pid;
|
int fd = -1, pid;
|
||||||
@ -586,14 +592,14 @@ static void install_apk(const char *apk) {
|
|||||||
static bool check_data() {
|
static bool check_data() {
|
||||||
bool mnt = false;
|
bool mnt = false;
|
||||||
bool data = false;
|
bool data = false;
|
||||||
Vector<CharArray> mounts;
|
auto mounts = file_to_vector("/proc/mounts");
|
||||||
file_to_vector("/proc/mounts", mounts);
|
|
||||||
for (auto &line : mounts) {
|
for (auto &line : mounts) {
|
||||||
if (line.contains(" /data ") && !line.contains("tmpfs"))
|
if (line.find(" /data ") != string::npos &&
|
||||||
|
line.find("tmpfs") == string::npos)
|
||||||
mnt = true;
|
mnt = true;
|
||||||
}
|
}
|
||||||
if (mnt) {
|
if (mnt) {
|
||||||
CharArray crypto = getprop("ro.crypto.state");
|
auto crypto = getprop("ro.crypto.state");
|
||||||
if (!crypto.empty()) {
|
if (!crypto.empty()) {
|
||||||
if (crypto == "unencrypted") {
|
if (crypto == "unencrypted") {
|
||||||
// Unencrypted, we can directly access data
|
// Unencrypted, we can directly access data
|
||||||
@ -811,11 +817,11 @@ void post_fs_data(int client) {
|
|||||||
exec_module_script("post-fs-data");
|
exec_module_script("post-fs-data");
|
||||||
|
|
||||||
// Recollect modules
|
// Recollect modules
|
||||||
module_list.clear(true);
|
module_list.clear();
|
||||||
collect_modules();
|
collect_modules();
|
||||||
|
|
||||||
// Create the system root entry
|
// Create the system root entry
|
||||||
node_entry *sys_root = new node_entry("system", IS_INTER);
|
auto sys_root = new node_entry("system", IS_INTER);
|
||||||
|
|
||||||
// Vendor root entry
|
// Vendor root entry
|
||||||
node_entry *ven_root = nullptr;
|
node_entry *ven_root = nullptr;
|
||||||
@ -823,7 +829,8 @@ void post_fs_data(int client) {
|
|||||||
bool has_modules = false;
|
bool has_modules = false;
|
||||||
|
|
||||||
LOGI("* Loading modules\n");
|
LOGI("* Loading modules\n");
|
||||||
for (const char *module : module_list) {
|
for (const auto &m : module_list) {
|
||||||
|
const auto module = m.c_str();
|
||||||
// Read props
|
// Read props
|
||||||
snprintf(buf, PATH_MAX, "%s/%s/system.prop", MOUNTPOINT, module);
|
snprintf(buf, PATH_MAX, "%s/%s/system.prop", MOUNTPOINT, module);
|
||||||
if (access(buf, F_OK) == 0) {
|
if (access(buf, F_OK) == 0) {
|
||||||
@ -911,7 +918,7 @@ core_only:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// All boot stage done, cleanup
|
// All boot stage done, cleanup
|
||||||
module_list.clear(true);
|
module_list.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void boot_complete(int client) {
|
void boot_complete(int client) {
|
||||||
|
@ -12,14 +12,17 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "magisk.h"
|
#include "magisk.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "daemon.h"
|
#include "daemon.h"
|
||||||
#include "flags.h"
|
#include "flags.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
bool log_daemon_started = false;
|
bool log_daemon_started = false;
|
||||||
static Vector<const char *> log_cmd, clear_cmd;
|
static vector<const char *> log_cmd, clear_cmd;
|
||||||
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
|
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@ -68,7 +71,7 @@ static void *monitor_thread(void *) {
|
|||||||
sleep(5);
|
sleep(5);
|
||||||
int fd;
|
int fd;
|
||||||
char b;
|
char b;
|
||||||
while (1) {
|
while (true) {
|
||||||
fd = connect_daemon();
|
fd = connect_daemon();
|
||||||
write_int(fd, HANDSHAKE);
|
write_int(fd, HANDSHAKE);
|
||||||
// This should hold unless the daemon is killed
|
// This should hold unless the daemon is killed
|
||||||
@ -136,11 +139,7 @@ static void log_daemon() {
|
|||||||
}
|
}
|
||||||
chmod("/dev/null", 0666);
|
chmod("/dev/null", 0666);
|
||||||
clear_cmd = log_cmd;
|
clear_cmd = log_cmd;
|
||||||
log_cmd.push_back("-v");
|
log_cmd.insert(log_cmd.end(), { "-v", "threadtime", "-s", "am_proc_start", "Magisk" });
|
||||||
log_cmd.push_back("threadtime");
|
|
||||||
log_cmd.push_back("-s");
|
|
||||||
log_cmd.push_back("am_proc_start");
|
|
||||||
log_cmd.push_back("Magisk");
|
|
||||||
#ifdef MAGISK_DEBUG
|
#ifdef MAGISK_DEBUG
|
||||||
log_cmd.push_back("*:F");
|
log_cmd.push_back("*:F");
|
||||||
#endif
|
#endif
|
||||||
@ -163,7 +162,7 @@ static void log_daemon() {
|
|||||||
if (xbind(sockfd, (struct sockaddr*) &sun, len))
|
if (xbind(sockfd, (struct sockaddr*) &sun, len))
|
||||||
exit(1);
|
exit(1);
|
||||||
xlisten(sockfd, 10);
|
xlisten(sockfd, 10);
|
||||||
while(1) {
|
while(true) {
|
||||||
int fd = xaccept4(sockfd, nullptr, nullptr, SOCK_CLOEXEC);
|
int fd = xaccept4(sockfd, nullptr, nullptr, SOCK_CLOEXEC);
|
||||||
switch(read_int(fd)) {
|
switch(read_int(fd)) {
|
||||||
case HIDE_CONNECT:
|
case HIDE_CONNECT:
|
||||||
|
@ -3,12 +3,11 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "CharArray.h"
|
#include <string>
|
||||||
|
|
||||||
int prop_exist(const char *name);
|
int prop_exist(const char *name);
|
||||||
int setprop(const char *name, const char *value, const bool trigger = true);
|
int setprop(const char *name, const char *value, bool trigger = true);
|
||||||
CharArray getprop(const char *name, bool persist = false);
|
std::string getprop(const char *name, bool persist = false);
|
||||||
void getprop(void (*callback)(const char *, const char *, void *), void *cookie, bool persist = false);
|
void getprop(void (*callback)(const char *, const char *, void *), void *cookie, bool persist = false);
|
||||||
int deleteprop(const char *name, bool persist = false);
|
int deleteprop(const char *name, bool persist = false);
|
||||||
int load_prop_file(const char *filename, const bool trigger = true);
|
int load_prop_file(const char *filename, bool trigger = true);
|
||||||
|
|
||||||
|
@ -2,11 +2,14 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#include "cpio.h"
|
#include "cpio.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "logging.h"
|
#include "logging.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
#define parse_align() lseek(fd, align(lseek(fd, 0, SEEK_CUR), 4), SEEK_SET)
|
#define parse_align() lseek(fd, align(lseek(fd, 0, SEEK_CUR), 4), SEEK_SET)
|
||||||
|
|
||||||
static uint32_t x8u(char *hex) {
|
static uint32_t x8u(char *hex) {
|
||||||
@ -40,8 +43,8 @@ cpio_entry::cpio_entry(int fd, cpio_newc_header &header) {
|
|||||||
// rdevminor = x8u(header.rdevminor);
|
// rdevminor = x8u(header.rdevminor);
|
||||||
uint32_t namesize = x8u(header.namesize);
|
uint32_t namesize = x8u(header.namesize);
|
||||||
// check = x8u(header.check);
|
// check = x8u(header.check);
|
||||||
filename = CharArray(namesize);
|
filename.resize(namesize - 1);
|
||||||
xxread(fd, filename, filename.size());
|
xxread(fd, &filename[0], namesize);
|
||||||
parse_align();
|
parse_align();
|
||||||
if (filesize) {
|
if (filesize) {
|
||||||
data = xmalloc(filesize);
|
data = xmalloc(filesize);
|
||||||
@ -54,22 +57,13 @@ cpio_entry::~cpio_entry() {
|
|||||||
free(data);
|
free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define the way to sort cpio_entry
|
|
||||||
template<>
|
|
||||||
int(*Vector<cpio_entry*>::_cmp)(cpio_entry*&, cpio_entry*&) = [](auto a, auto b) -> int {
|
|
||||||
if (a == b) return 0;
|
|
||||||
if (a == nullptr) return 1;
|
|
||||||
if (b == nullptr) return -1;
|
|
||||||
return a->filename.compare(b->filename);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
cpio::cpio(const char *filename) {
|
cpio::cpio(const char *filename) {
|
||||||
int fd = open(filename, O_RDONLY);
|
int fd = open(filename, O_RDONLY);
|
||||||
if (fd < 0) return;
|
if (fd < 0) return;
|
||||||
fprintf(stderr, "Loading cpio: [%s]\n", filename);
|
fprintf(stderr, "Loading cpio: [%s]\n", filename);
|
||||||
cpio_newc_header header;
|
cpio_newc_header header;
|
||||||
cpio_entry *entry;
|
cpio_entry *entry;
|
||||||
|
int i = 0;
|
||||||
while(xxread(fd, &header, sizeof(cpio_newc_header)) != -1) {
|
while(xxread(fd, &header, sizeof(cpio_newc_header)) != -1) {
|
||||||
entry = new cpio_entry(fd, header);
|
entry = new cpio_entry(fd, header);
|
||||||
if (entry->filename == "." || entry->filename == ".." || entry->filename == "TRAILER!!!") {
|
if (entry->filename == "." || entry->filename == ".." || entry->filename == "TRAILER!!!") {
|
||||||
@ -86,7 +80,7 @@ cpio::cpio(const char *filename) {
|
|||||||
|
|
||||||
cpio::~cpio() {
|
cpio::~cpio() {
|
||||||
for (auto &e : arr)
|
for (auto &e : arr)
|
||||||
if (e) delete e;
|
delete e;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define dump_align() write_zero(fd, align_off(lseek(fd, 0, SEEK_CUR), 4))
|
#define dump_align() write_zero(fd, align_off(lseek(fd, 0, SEEK_CUR), 4))
|
||||||
@ -109,11 +103,11 @@ void cpio::dump(const char *file) {
|
|||||||
0, // e->devminor
|
0, // e->devminor
|
||||||
0, // e->rdevmajor
|
0, // e->rdevmajor
|
||||||
0, // e->rdevminor
|
0, // e->rdevminor
|
||||||
(uint32_t) e->filename.size(),
|
(uint32_t) e->filename.size() + 1,
|
||||||
0 // e->check
|
0 // e->check
|
||||||
);
|
);
|
||||||
xwrite(fd, header, 110);
|
xwrite(fd, header, 110);
|
||||||
xwrite(fd, e->filename, e->filename.size());
|
xwrite(fd, e->filename.c_str(), e->filename.size() + 1);
|
||||||
dump_align();
|
dump_align();
|
||||||
if (e->filesize) {
|
if (e->filesize) {
|
||||||
xwrite(fd, e->data, e->filesize);
|
xwrite(fd, e->data, e->filesize);
|
||||||
@ -140,7 +134,7 @@ int cpio::find(const char *name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void cpio::insert(cpio_entry *e) {
|
void cpio::insert(cpio_entry *e) {
|
||||||
int i = find(e->filename);
|
int i = find(e->filename.c_str());
|
||||||
if (i >= 0) {
|
if (i >= 0) {
|
||||||
delete arr[i];
|
delete arr[i];
|
||||||
arr[i] = e;
|
arr[i] = e;
|
||||||
@ -149,17 +143,12 @@ void cpio::insert(cpio_entry *e) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cpio::insert(Vector<cpio_entry *> &arr) {
|
|
||||||
for (auto &e : arr)
|
|
||||||
insert(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cpio::rm(const char *name, bool r) {
|
void cpio::rm(const char *name, bool r) {
|
||||||
size_t len = strlen(name);
|
size_t len = strlen(name);
|
||||||
for (auto &e : arr) {
|
for (auto &e : arr) {
|
||||||
if (!e)
|
if (!e)
|
||||||
continue;
|
continue;
|
||||||
if (e->filename.compare(name, len) == 0 &&
|
if (e->filename.compare(0, len, name) == 0 &&
|
||||||
((r && e->filename[len] == '/') || e->filename[len] == '\0')) {
|
((r && e->filename[len] == '/') || e->filename[len] == '\0')) {
|
||||||
fprintf(stderr, "Remove [%s]\n", e->filename.c_str());
|
fprintf(stderr, "Remove [%s]\n", e->filename.c_str());
|
||||||
delete e;
|
delete e;
|
||||||
@ -171,17 +160,15 @@ void cpio::rm(const char *name, bool r) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void cpio::makedir(mode_t mode, const char *name) {
|
void cpio::makedir(mode_t mode, const char *name) {
|
||||||
auto e = new cpio_entry();
|
auto e = new cpio_entry(name);
|
||||||
e->mode = S_IFDIR | mode;
|
e->mode = S_IFDIR | mode;
|
||||||
e->filename = name;
|
|
||||||
insert(e);
|
insert(e);
|
||||||
fprintf(stderr, "Create directory [%s] (%04o)\n", name, mode);
|
fprintf(stderr, "Create directory [%s] (%04o)\n", name, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cpio::ln(const char *target, const char *name) {
|
void cpio::ln(const char *target, const char *name) {
|
||||||
auto e = new cpio_entry();
|
auto e = new cpio_entry(name);
|
||||||
e->mode = S_IFLNK;
|
e->mode = S_IFLNK;
|
||||||
e->filename = name;
|
|
||||||
e->filesize = strlen(target);
|
e->filesize = strlen(target);
|
||||||
e->data = strdup(target);
|
e->data = strdup(target);
|
||||||
insert(e);
|
insert(e);
|
||||||
@ -190,9 +177,8 @@ void cpio::ln(const char *target, const char *name) {
|
|||||||
|
|
||||||
void cpio::add(mode_t mode, const char *name, const char *file) {
|
void cpio::add(mode_t mode, const char *name, const char *file) {
|
||||||
int fd = xopen(file, O_RDONLY);
|
int fd = xopen(file, O_RDONLY);
|
||||||
auto e = new cpio_entry();
|
auto e = new cpio_entry(name);
|
||||||
e->mode = S_IFREG | mode;
|
e->mode = S_IFREG | mode;
|
||||||
e->filename = name;
|
|
||||||
e->filesize = lseek(fd, 0, SEEK_END);
|
e->filesize = lseek(fd, 0, SEEK_END);
|
||||||
lseek(fd, 0, SEEK_SET);
|
lseek(fd, 0, SEEK_SET);
|
||||||
e->data = xmalloc(e->filesize);
|
e->data = xmalloc(e->filesize);
|
||||||
@ -239,17 +225,15 @@ static void extract_entry(cpio_entry *e, const char *file) {
|
|||||||
|
|
||||||
void cpio::extract() {
|
void cpio::extract() {
|
||||||
for (auto &e : arr) {
|
for (auto &e : arr) {
|
||||||
if (!e)
|
if (!e) continue;
|
||||||
continue;
|
extract_entry(e, e->filename.c_str());
|
||||||
extract_entry(e, e->filename);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cpio::extract(const char *name, const char *file) {
|
bool cpio::extract(const char *name, const char *file) {
|
||||||
int i = find(name);
|
int i = find(name);
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
auto e = arr[i];
|
extract_entry(arr[i], file);
|
||||||
extract_entry(e, file);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
fprintf(stderr, "Cannot find the file entry [%s]\n", name);
|
fprintf(stderr, "Cannot find the file entry [%s]\n", name);
|
||||||
@ -257,7 +241,13 @@ bool cpio::extract(const char *name, const char *file) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void cpio::sort() {
|
void cpio::sort() {
|
||||||
arr.sort();
|
std::sort(arr.begin(), arr.end(), [] (auto a, auto b) -> bool {
|
||||||
|
if (a == b || a == nullptr)
|
||||||
|
return false;
|
||||||
|
if (b == nullptr)
|
||||||
|
return true;
|
||||||
|
return a->filename.compare(b->filename) < 0;
|
||||||
|
});
|
||||||
while (arr.back() == nullptr)
|
while (arr.back() == nullptr)
|
||||||
arr.pop_back();
|
arr.pop_back();
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,8 @@
|
|||||||
#define _CPIO_H_
|
#define _CPIO_H_
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <vector>
|
||||||
#include "Vector.h"
|
#include <string>
|
||||||
#include "CharArray.h"
|
|
||||||
|
|
||||||
struct cpio_newc_header {
|
struct cpio_newc_header {
|
||||||
char magic[6];
|
char magic[6];
|
||||||
@ -38,17 +37,18 @@ struct cpio_entry {
|
|||||||
// uint32_t namesize;
|
// uint32_t namesize;
|
||||||
// uint32_t check;
|
// uint32_t check;
|
||||||
// char *filename = nullptr;
|
// char *filename = nullptr;
|
||||||
CharArray filename;
|
std::string filename;
|
||||||
void *data = nullptr;
|
void *data = nullptr;
|
||||||
|
|
||||||
cpio_entry() {}
|
cpio_entry() = default;
|
||||||
|
explicit cpio_entry(const char *name) : filename(name) {}
|
||||||
cpio_entry(int fd, cpio_newc_header &header);
|
cpio_entry(int fd, cpio_newc_header &header);
|
||||||
~cpio_entry();
|
~cpio_entry();
|
||||||
};
|
};
|
||||||
|
|
||||||
class cpio {
|
class cpio {
|
||||||
public:
|
public:
|
||||||
cpio(const char *filename);
|
explicit cpio(const char *filename);
|
||||||
~cpio();
|
~cpio();
|
||||||
void dump(const char *file);
|
void dump(const char *file);
|
||||||
int find(const char *name);
|
int find(const char *name);
|
||||||
@ -57,14 +57,13 @@ public:
|
|||||||
void makedir(mode_t mode, const char *name);
|
void makedir(mode_t mode, const char *name);
|
||||||
void ln(const char *target, const char *name);
|
void ln(const char *target, const char *name);
|
||||||
void add(mode_t mode, const char *name, const char *file);
|
void add(mode_t mode, const char *name, const char *file);
|
||||||
void insert(Vector<cpio_entry *> &arr);
|
|
||||||
bool mv(const char *from, const char *to);
|
bool mv(const char *from, const char *to);
|
||||||
void extract();
|
void extract();
|
||||||
bool extract(const char *name, const char *file);
|
bool extract(const char *name, const char *file);
|
||||||
void sort();
|
void sort();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Vector<cpio_entry *> arr;
|
std::vector<cpio_entry *> arr;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -6,9 +6,11 @@
|
|||||||
#include "cpio.h"
|
#include "cpio.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
class magisk_cpio : public cpio {
|
class magisk_cpio : public cpio {
|
||||||
public:
|
public:
|
||||||
magisk_cpio(const char *filename) : cpio(filename) {}
|
explicit magisk_cpio(const char *filename) : cpio(filename) {}
|
||||||
void patch(bool keepverity, bool keepforceencrypt);
|
void patch(bool keepverity, bool keepforceencrypt);
|
||||||
int test();
|
int test();
|
||||||
char * sha1();
|
char * sha1();
|
||||||
@ -23,8 +25,8 @@ void magisk_cpio::patch(bool keepverity, bool keepforceencrypt) {
|
|||||||
if (!e)
|
if (!e)
|
||||||
continue;
|
continue;
|
||||||
bool fstab = (!keepverity || !keepforceencrypt) &&
|
bool fstab = (!keepverity || !keepforceencrypt) &&
|
||||||
!e->filename.starts_with(".backup") &&
|
!str_starts(e->filename, ".backup") &&
|
||||||
e->filename.contains("fstab") && S_ISREG(e->mode);
|
str_contains(e->filename, "fstab") && S_ISREG(e->mode);
|
||||||
if (!keepverity) {
|
if (!keepverity) {
|
||||||
if (fstab) {
|
if (fstab) {
|
||||||
patch_verity(&e->data, &e->filesize, 1);
|
patch_verity(&e->data, &e->filesize, 1);
|
||||||
@ -98,7 +100,7 @@ char *magisk_cpio::sha1() {
|
|||||||
void magisk_cpio::restore() {
|
void magisk_cpio::restore() {
|
||||||
for (auto &e : arr) {
|
for (auto &e : arr) {
|
||||||
if (!e) continue;
|
if (!e) continue;
|
||||||
if (e->filename.starts_with(".backup")) {
|
if (str_starts(e->filename, ".backup")) {
|
||||||
if (e->filename[7] == '\0') continue;
|
if (e->filename[7] == '\0') continue;
|
||||||
if (e->filename[8] == '.') {
|
if (e->filename[8] == '.') {
|
||||||
if (strcmp(&e->filename[8], ".rmlist") == 0) {
|
if (strcmp(&e->filename[8], ".rmlist") == 0) {
|
||||||
@ -106,7 +108,7 @@ void magisk_cpio::restore() {
|
|||||||
rm((char *) e->data + pos, false);
|
rm((char *) e->data + pos, false);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
mv(e->filename, e->filename + 8);
|
mv(e->filename.c_str(), &e->filename[8]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -120,17 +122,15 @@ void magisk_cpio::restore() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void magisk_cpio::backup(const char *orig) {
|
void magisk_cpio::backup(const char *orig) {
|
||||||
Vector<cpio_entry*> bak;
|
vector<cpio_entry*> bak;
|
||||||
cpio_entry *m, *n, *rem;
|
cpio_entry *m, *n, *rem;
|
||||||
char buf[PATH_MAX];
|
char buf[PATH_MAX];
|
||||||
|
|
||||||
m = new cpio_entry();
|
m = new cpio_entry(".backup");
|
||||||
m->filename = ".backup";
|
|
||||||
m->mode = S_IFDIR;
|
m->mode = S_IFDIR;
|
||||||
bak.push_back(m);
|
bak.push_back(m);
|
||||||
|
|
||||||
rem = new cpio_entry();
|
rem = new cpio_entry(".backup/.rmlist");
|
||||||
rem->filename = ".backup/.rmlist";
|
|
||||||
rem->mode = S_IFREG;
|
rem->mode = S_IFREG;
|
||||||
|
|
||||||
magisk_cpio o(orig);
|
magisk_cpio o(orig);
|
||||||
@ -176,7 +176,7 @@ void magisk_cpio::backup(const char *orig) {
|
|||||||
// Something new in ramdisk, record in rem
|
// Something new in ramdisk, record in rem
|
||||||
++j;
|
++j;
|
||||||
rem->data = xrealloc(rem->data, rem->filesize + n->filename.size());
|
rem->data = xrealloc(rem->data, rem->filesize + n->filename.size());
|
||||||
memcpy((char *) rem->data + rem->filesize, n->filename, n->filename.size());
|
memcpy((char *) rem->data + rem->filesize, n->filename.c_str(), n->filename.size());
|
||||||
rem->filesize += n->filename.size();
|
rem->filesize += n->filename.size();
|
||||||
fprintf(stderr, "Record new entry: [%s] -> [.backup/.rmlist]\n", n->filename.c_str());
|
fprintf(stderr, "Record new entry: [%s] -> [.backup/.rmlist]\n", n->filename.c_str());
|
||||||
}
|
}
|
||||||
@ -196,7 +196,8 @@ void magisk_cpio::backup(const char *orig) {
|
|||||||
delete rem;
|
delete rem;
|
||||||
|
|
||||||
if (bak.size() > 1)
|
if (bak.size() > 1)
|
||||||
insert(bak);
|
for (auto item : bak)
|
||||||
|
insert(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -249,11 +250,11 @@ int cpio_commands(int argc, char *argv[]) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} else if (cmdc == 3 && strcmp(cmdv[0], "mkdir") == 0) {
|
} else if (cmdc == 3 && strcmp(cmdv[0], "mkdir") == 0) {
|
||||||
cpio.makedir(strtoul(cmdv[1], NULL, 8), cmdv[2]);
|
cpio.makedir(strtoul(cmdv[1], nullptr, 8), cmdv[2]);
|
||||||
} else if (cmdc == 3 && strcmp(cmdv[0], "ln") == 0) {
|
} else if (cmdc == 3 && strcmp(cmdv[0], "ln") == 0) {
|
||||||
cpio.ln(cmdv[1], cmdv[2]);
|
cpio.ln(cmdv[1], cmdv[2]);
|
||||||
} else if (cmdc == 4 && strcmp(cmdv[0], "add") == 0) {
|
} else if (cmdc == 4 && strcmp(cmdv[0], "add") == 0) {
|
||||||
cpio.add(strtoul(cmdv[1], NULL, 8), cmdv[2], cmdv[3]);
|
cpio.add(strtoul(cmdv[1], nullptr, 8), cmdv[2], cmdv[3]);
|
||||||
} else {
|
} else {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -15,10 +15,12 @@
|
|||||||
#include "daemon.h"
|
#include "daemon.h"
|
||||||
#include "db.h"
|
#include "db.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
#define SAFETYNET_COMPONENT "com.google.android.gms/.droidguard.DroidGuardService"
|
#define SAFETYNET_COMPONENT "com.google.android.gms/.droidguard.DroidGuardService"
|
||||||
#define SAFETYNET_PROCESS "com.google.android.gms.unstable"
|
#define SAFETYNET_PROCESS "com.google.android.gms.unstable"
|
||||||
|
|
||||||
Vector<CharArray> hide_list;
|
vector<string> hide_list;
|
||||||
pthread_mutex_t list_lock;
|
pthread_mutex_t list_lock;
|
||||||
|
|
||||||
static pthread_t proc_monitor_thread;
|
static pthread_t proc_monitor_thread;
|
||||||
@ -55,7 +57,7 @@ void hide_sensitive_props() {
|
|||||||
|
|
||||||
// Hide all sensitive props
|
// Hide all sensitive props
|
||||||
for (int i = 0; prop_key[i]; ++i) {
|
for (int i = 0; prop_key[i]; ++i) {
|
||||||
CharArray value = getprop(prop_key[i]);
|
auto value = getprop(prop_key[i]);
|
||||||
if (!value.empty() && value != prop_value[i])
|
if (!value.empty() && value != prop_value[i])
|
||||||
setprop(prop_key[i], prop_value[i], false);
|
setprop(prop_key[i], prop_value[i], false);
|
||||||
}
|
}
|
||||||
@ -118,7 +120,7 @@ static bool proc_name_match(int pid, const char *name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void kill_proc_cb(int pid, void *v) {
|
static void kill_proc_cb(int pid, void *v) {
|
||||||
ps_arg *args = static_cast<ps_arg *>(v);
|
auto args = static_cast<ps_arg *>(v);
|
||||||
if (proc_name_match(pid, args->name))
|
if (proc_name_match(pid, args->name))
|
||||||
kill(pid, SIGTERM);
|
kill(pid, SIGTERM);
|
||||||
else if (args->uid > 0) {
|
else if (args->uid > 0) {
|
||||||
@ -183,7 +185,7 @@ int add_list(const char *proc) {
|
|||||||
|
|
||||||
// Critical region
|
// Critical region
|
||||||
pthread_mutex_lock(&list_lock);
|
pthread_mutex_lock(&list_lock);
|
||||||
hide_list.push_back(proc);
|
hide_list.emplace_back(proc);
|
||||||
kill_process(proc);
|
kill_process(proc);
|
||||||
pthread_mutex_unlock(&list_lock);
|
pthread_mutex_unlock(&list_lock);
|
||||||
|
|
||||||
@ -247,10 +249,9 @@ bool init_list() {
|
|||||||
|
|
||||||
// Migrate old hide list into database
|
// Migrate old hide list into database
|
||||||
if (access(LEGACY_LIST, R_OK) == 0) {
|
if (access(LEGACY_LIST, R_OK) == 0) {
|
||||||
Vector<CharArray> tmp;
|
auto tmp = file_to_vector(LEGACY_LIST);
|
||||||
file_to_vector(LEGACY_LIST, tmp);
|
|
||||||
for (auto &s : tmp)
|
for (auto &s : tmp)
|
||||||
add_list(s);
|
add_list(s.c_str());
|
||||||
unlink(LEGACY_LIST);
|
unlink(LEGACY_LIST);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -307,7 +308,7 @@ int launch_magiskhide(int client) {
|
|||||||
// Start monitoring
|
// Start monitoring
|
||||||
proc_monitor();
|
proc_monitor();
|
||||||
|
|
||||||
error:
|
error:
|
||||||
hide_enabled = false;
|
hide_enabled = false;
|
||||||
return DAEMON_ERROR;
|
return DAEMON_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -2,10 +2,10 @@
|
|||||||
#define MAGISK_HIDE_H
|
#define MAGISK_HIDE_H
|
||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "daemon.h"
|
#include "daemon.h"
|
||||||
#include "Vector.h"
|
|
||||||
#include "CharArray.h"
|
|
||||||
|
|
||||||
#define TERM_THREAD SIGUSR1
|
#define TERM_THREAD SIGUSR1
|
||||||
|
|
||||||
@ -30,7 +30,7 @@ bool init_list();
|
|||||||
|
|
||||||
extern bool hide_enabled;
|
extern bool hide_enabled;
|
||||||
extern pthread_mutex_t list_lock;
|
extern pthread_mutex_t list_lock;
|
||||||
extern Vector<CharArray> hide_list;
|
extern std::vector<std::string> hide_list;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
LAUNCH_MAGISKHIDE,
|
LAUNCH_MAGISKHIDE,
|
||||||
|
@ -15,19 +15,23 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <sys/mount.h>
|
#include <sys/mount.h>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "magisk.h"
|
#include "magisk.h"
|
||||||
#include "daemon.h"
|
#include "daemon.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "magiskhide.h"
|
#include "magiskhide.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
static int sockfd = -1;
|
static int sockfd = -1;
|
||||||
extern char *system_block, *vendor_block, *magiskloop;
|
extern char *system_block, *vendor_block, *magiskloop;
|
||||||
|
|
||||||
// Workaround for the lack of pthread_cancel
|
// Workaround for the lack of pthread_cancel
|
||||||
static void term_thread(int) {
|
static void term_thread(int) {
|
||||||
LOGD("proc_monitor: running cleanup\n");
|
LOGD("proc_monitor: running cleanup\n");
|
||||||
hide_list.clear(true);
|
hide_list.clear();
|
||||||
hide_enabled = false;
|
hide_enabled = false;
|
||||||
close(sockfd);
|
close(sockfd);
|
||||||
sockfd = -1;
|
sockfd = -1;
|
||||||
@ -64,7 +68,7 @@ static void hide_daemon(int pid) {
|
|||||||
LOGD("hide_daemon: handling pid=[%d]\n", pid);
|
LOGD("hide_daemon: handling pid=[%d]\n", pid);
|
||||||
|
|
||||||
char buffer[4096];
|
char buffer[4096];
|
||||||
Vector<CharArray> mounts;
|
vector<string> mounts;
|
||||||
|
|
||||||
manage_selinux();
|
manage_selinux();
|
||||||
clean_magisk_props();
|
clean_magisk_props();
|
||||||
@ -75,24 +79,24 @@ static void hide_daemon(int pid) {
|
|||||||
snprintf(buffer, sizeof(buffer), "/proc/%d", pid);
|
snprintf(buffer, sizeof(buffer), "/proc/%d", pid);
|
||||||
chdir(buffer);
|
chdir(buffer);
|
||||||
|
|
||||||
file_to_vector("mounts", mounts);
|
mounts = file_to_vector("mounts");
|
||||||
// Unmount dummy skeletons and /sbin links
|
// Unmount dummy skeletons and /sbin links
|
||||||
for (auto &s : mounts) {
|
for (auto &s : mounts) {
|
||||||
if (s.contains("tmpfs /system/") || s.contains("tmpfs /vendor/") || s.contains("tmpfs /sbin")) {
|
if (str_contains(s, "tmpfs /system/") || str_contains(s, "tmpfs /vendor/") ||
|
||||||
sscanf(s, "%*s %4096s", buffer);
|
str_contains(s, "tmpfs /sbin")) {
|
||||||
|
sscanf(s.c_str(), "%*s %4096s", buffer);
|
||||||
lazy_unmount(buffer);
|
lazy_unmount(buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mounts.clear();
|
|
||||||
|
|
||||||
// Re-read mount infos
|
// Re-read mount infos
|
||||||
file_to_vector("mounts", mounts);
|
mounts = file_to_vector("mounts");
|
||||||
|
|
||||||
// Unmount everything under /system, /vendor, and loop mounts
|
// Unmount everything under /system, /vendor, and loop mounts
|
||||||
for (auto &s : mounts) {
|
for (auto &s : mounts) {
|
||||||
if ((s.contains(" /system/") || s.contains(" /vendor/")) &&
|
if ((str_contains(s, " /system/") || str_contains(s, " /vendor/")) &&
|
||||||
(s.contains(system_block) || s.contains(vendor_block) || s.contains(magiskloop))) {
|
(str_contains(s, system_block) || str_contains(s, vendor_block) || str_contains(s, magiskloop))) {
|
||||||
sscanf(s, "%*s %4096s", buffer);
|
sscanf(s.c_str(), "%*s %4096s", buffer);
|
||||||
lazy_unmount(buffer);
|
lazy_unmount(buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -108,13 +112,12 @@ void proc_monitor() {
|
|||||||
sigset_t block_set;
|
sigset_t block_set;
|
||||||
sigemptyset(&block_set);
|
sigemptyset(&block_set);
|
||||||
sigaddset(&block_set, TERM_THREAD);
|
sigaddset(&block_set, TERM_THREAD);
|
||||||
pthread_sigmask(SIG_UNBLOCK, &block_set, NULL);
|
pthread_sigmask(SIG_UNBLOCK, &block_set, nullptr);
|
||||||
|
|
||||||
// Register the cancel signal
|
// Register the cancel signal
|
||||||
struct sigaction act;
|
struct sigaction act{};
|
||||||
memset(&act, 0, sizeof(act));
|
|
||||||
act.sa_handler = term_thread;
|
act.sa_handler = term_thread;
|
||||||
sigaction(TERM_THREAD, &act, NULL);
|
sigaction(TERM_THREAD, &act, nullptr);
|
||||||
|
|
||||||
if (access("/proc/1/ns/mnt", F_OK) != 0) {
|
if (access("/proc/1/ns/mnt", F_OK) != 0) {
|
||||||
LOGE("proc_monitor: Your kernel doesn't support mount namespace :(\n");
|
LOGE("proc_monitor: Your kernel doesn't support mount namespace :(\n");
|
||||||
@ -155,7 +158,7 @@ void proc_monitor() {
|
|||||||
bool hide = false;
|
bool hide = false;
|
||||||
pthread_mutex_lock(&list_lock);
|
pthread_mutex_lock(&list_lock);
|
||||||
for (auto &s : hide_list) {
|
for (auto &s : hide_list) {
|
||||||
if (strncmp(cpnt, s, s.size() - 1) == 0) {
|
if (strncmp(cpnt, s.c_str(), s.size() - 1) == 0) {
|
||||||
hide = true;
|
hide = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "sepolicy.h"
|
#include "sepolicy.h"
|
||||||
#include "magiskpolicy.h"
|
#include "magiskpolicy.h"
|
||||||
@ -12,6 +14,8 @@
|
|||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "flags.h"
|
#include "flags.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
static const char *type_msg_1 =
|
static const char *type_msg_1 =
|
||||||
"Type 1:\n"
|
"Type 1:\n"
|
||||||
"\"<rule_name> source_type target_type class perm_set\"\n"
|
"\"<rule_name> source_type target_type class perm_set\"\n"
|
||||||
@ -101,7 +105,7 @@ static const char *type_msg_6 =
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parse_bracket(char *tok, char *&stmt, Vector<const char *> *vec) {
|
static int parse_bracket(char *tok, char *&stmt, vector<const char *> *vec) {
|
||||||
if (tok == nullptr || tok[0] != '{') {
|
if (tok == nullptr || tok[0] != '{') {
|
||||||
// Not in a bracket
|
// Not in a bracket
|
||||||
vec->push_back(tok);
|
vec->push_back(tok);
|
||||||
@ -143,10 +147,10 @@ static int parse_pattern_1(int action, const char *action_str, char *stmt) {
|
|||||||
|
|
||||||
int state = 0;
|
int state = 0;
|
||||||
char *cur, *cls;
|
char *cur, *cls;
|
||||||
Vector<const char*> source, target, permission;
|
vector<const char*> source, target, permission;
|
||||||
while ((cur = strtok_r(nullptr, " ", &stmt)) != nullptr) {
|
while ((cur = strtok_r(nullptr, " ", &stmt)) != nullptr) {
|
||||||
if (cur[0] == '*') cur = ALL;
|
if (cur[0] == '*') cur = ALL;
|
||||||
Vector<const char *> *vec;
|
vector<const char *> *vec;
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case 0:
|
case 0:
|
||||||
vec = &source;
|
vec = &source;
|
||||||
@ -200,10 +204,10 @@ static int parse_pattern_2(int action, const char *action_str, char *stmt) {
|
|||||||
|
|
||||||
int state = 0;
|
int state = 0;
|
||||||
char *cur, *range;
|
char *cur, *range;
|
||||||
Vector<const char *> source, target, classes;
|
vector<const char *> source, target, classes;
|
||||||
while ((cur = strtok_r(nullptr, " ", &stmt)) != nullptr) {
|
while ((cur = strtok_r(nullptr, " ", &stmt)) != nullptr) {
|
||||||
if (cur[0] == '*') cur = ALL;
|
if (cur[0] == '*') cur = ALL;
|
||||||
Vector<const char *> *vec;
|
vector<const char *> *vec;
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case 0:
|
case 0:
|
||||||
vec = &source;
|
vec = &source;
|
||||||
@ -216,7 +220,7 @@ static int parse_pattern_2(int action, const char *action_str, char *stmt) {
|
|||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
// Currently only support ioctl
|
// Currently only support ioctl
|
||||||
if (strcmp(cur, "ioctl"))
|
if (strcmp(cur, "ioctl") != 0)
|
||||||
return 1;
|
return 1;
|
||||||
vec = nullptr;
|
vec = nullptr;
|
||||||
break;
|
break;
|
||||||
@ -262,7 +266,7 @@ static int parse_pattern_3(int action, const char *action_str, char* stmt) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
char *cur;
|
char *cur;
|
||||||
Vector<const char *> domains;
|
vector<const char *> domains;
|
||||||
while ((cur = strtok_r(nullptr, " {}", &stmt)) != nullptr) {
|
while ((cur = strtok_r(nullptr, " {}", &stmt)) != nullptr) {
|
||||||
if (cur[0] == '*') cur = ALL;
|
if (cur[0] == '*') cur = ALL;
|
||||||
domains.push_back(cur);
|
domains.push_back(cur);
|
||||||
@ -291,10 +295,10 @@ static int parse_pattern_4(int action, const char *action_str, char *stmt) {
|
|||||||
|
|
||||||
int state = 0;
|
int state = 0;
|
||||||
char *cur;
|
char *cur;
|
||||||
Vector<const char *> classes, attribute;
|
vector<const char *> classes, attribute;
|
||||||
while ((cur = strtok_r(nullptr, " ", &stmt)) != nullptr) {
|
while ((cur = strtok_r(nullptr, " ", &stmt)) != nullptr) {
|
||||||
if (cur[0] == '*') cur = ALL;
|
if (cur[0] == '*') cur = ALL;
|
||||||
Vector<const char *> *vec;
|
vector<const char *> *vec;
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case 0:
|
case 0:
|
||||||
vec = &classes;
|
vec = &classes;
|
||||||
@ -409,7 +413,7 @@ static void parse_statement(char *statement) {
|
|||||||
char *action, *remain;
|
char *action, *remain;
|
||||||
|
|
||||||
// strtok will modify the origin string, duplicate the statement for error messages
|
// strtok will modify the origin string, duplicate the statement for error messages
|
||||||
CharArray orig(statement);
|
string orig(statement);
|
||||||
|
|
||||||
action = strtok_r(statement, " ", &remain);
|
action = strtok_r(statement, " ", &remain);
|
||||||
if (remain == nullptr) remain = &action[strlen(action)];
|
if (remain == nullptr) remain = &action[strlen(action)];
|
||||||
|
@ -5,15 +5,15 @@
|
|||||||
#ifndef MAGISK_PROPS_H
|
#ifndef MAGISK_PROPS_H
|
||||||
#define MAGISK_PROPS_H
|
#define MAGISK_PROPS_H
|
||||||
|
|
||||||
#include <CharArray.h>
|
#include <string>
|
||||||
#include "resetprop/private/system_properties.h"
|
#include "resetprop/private/system_properties.h"
|
||||||
#include "logging.h"
|
#include "logging.h"
|
||||||
|
|
||||||
struct prop_t {
|
struct prop_t {
|
||||||
char *name;
|
char *name;
|
||||||
char value[PROP_VALUE_MAX];
|
char value[PROP_VALUE_MAX];
|
||||||
prop_t() = default;
|
prop_t() : name(nullptr) {}
|
||||||
prop_t(const char *name) {
|
explicit prop_t(const char *name) {
|
||||||
this->name = strdup(name);
|
this->name = strdup(name);
|
||||||
value[0] = '\0';
|
value[0] = '\0';
|
||||||
}
|
}
|
||||||
@ -21,7 +21,13 @@ struct prop_t {
|
|||||||
this->name = strdup(name);
|
this->name = strdup(name);
|
||||||
strcpy(this->value, value);
|
strcpy(this->value, value);
|
||||||
}
|
}
|
||||||
prop_t& operator= (prop_t&& prop) {
|
prop_t(prop_t &&prop): name(nullptr) {
|
||||||
|
operator=(std::move(prop));
|
||||||
|
}
|
||||||
|
bool operator<(const prop_t &prop) const {
|
||||||
|
return strcmp(name, prop.name) < 0;
|
||||||
|
}
|
||||||
|
prop_t& operator= (prop_t &&prop) {
|
||||||
if (this != &prop) {
|
if (this != &prop) {
|
||||||
free(name);
|
free(name);
|
||||||
name = prop.name;
|
name = prop.name;
|
||||||
@ -38,7 +44,7 @@ struct prop_t {
|
|||||||
struct read_cb_t {
|
struct read_cb_t {
|
||||||
void (*cb)(const char *, const char *, void *);
|
void (*cb)(const char *, const char *, void *);
|
||||||
void *arg;
|
void *arg;
|
||||||
read_cb_t(void (*cb)(const char *, const char *, void *) = nullptr, void *arg = nullptr)
|
explicit read_cb_t(void (*cb)(const char *, const char *, void *) = nullptr, void *arg = nullptr)
|
||||||
: cb(cb), arg(arg) {}
|
: cb(cb), arg(arg) {}
|
||||||
void exec(const char *name, const char *value) {
|
void exec(const char *name, const char *value) {
|
||||||
cb(name, value, arg);
|
cb(name, value, arg);
|
||||||
@ -49,7 +55,7 @@ struct read_cb_t {
|
|||||||
|
|
||||||
extern bool use_pb;
|
extern bool use_pb;
|
||||||
|
|
||||||
CharArray persist_getprop(const char *name);
|
std::string persist_getprop(const char *name);
|
||||||
void persist_getprop(read_cb_t *read_cb);
|
void persist_getprop(read_cb_t *read_cb);
|
||||||
bool persist_deleteprop(const char *name);
|
bool persist_deleteprop(const char *name);
|
||||||
void collect_props(const char *name, const char *value, void *v_plist);
|
void collect_props(const char *name, const char *value, void *v_plist);
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <pb.h>
|
#include <pb.h>
|
||||||
#include <pb_decode.h>
|
#include <pb_decode.h>
|
||||||
#include <pb_encode.h>
|
#include <pb_encode.h>
|
||||||
@ -12,6 +14,8 @@
|
|||||||
#include "_resetprop.h"
|
#include "_resetprop.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
/* ***********************************************************************
|
/* ***********************************************************************
|
||||||
* Auto generated header and constant definitions compiled from
|
* Auto generated header and constant definitions compiled from
|
||||||
* android/platform/system/core/master/init/persistent_properties.proto
|
* android/platform/system/core/master/init/persistent_properties.proto
|
||||||
@ -113,7 +117,7 @@ static bool prop_encode(pb_ostream_t *stream, const pb_field_t *field, void * co
|
|||||||
PersistentProperties_PersistentPropertyRecord prop = {};
|
PersistentProperties_PersistentPropertyRecord prop = {};
|
||||||
prop.name.funcs.encode = name_encode;
|
prop.name.funcs.encode = name_encode;
|
||||||
prop.has_value = true;
|
prop.has_value = true;
|
||||||
Vector<prop_t> &prop_list = *(Vector<prop_t> *) *arg;
|
auto &prop_list = *(vector<prop_t> *) *arg;
|
||||||
for (auto &p : prop_list) {
|
for (auto &p : prop_list) {
|
||||||
if (!pb_encode_tag_for_field(stream, field))
|
if (!pb_encode_tag_for_field(stream, field))
|
||||||
return false;
|
return false;
|
||||||
@ -160,16 +164,16 @@ static void pb_getprop(read_cb_t *read_cb) {
|
|||||||
munmap(buf, size);
|
munmap(buf, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void file_getprop(const char *name, char *value) {
|
static bool file_getprop(const char *name, char *value) {
|
||||||
value[0] = '\0';
|
|
||||||
char path[PATH_MAX];
|
char path[PATH_MAX];
|
||||||
snprintf(path, sizeof(path), PERSISTENT_PROPERTY_DIR "/%s", name);
|
snprintf(path, sizeof(path), PERSISTENT_PROPERTY_DIR "/%s", name);
|
||||||
int fd = open(path, O_RDONLY | O_CLOEXEC);
|
int fd = open(path, O_RDONLY | O_CLOEXEC);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return;
|
return false;
|
||||||
LOGD("resetprop: read prop from [%s]\n", path);
|
LOGD("resetprop: read prop from [%s]\n", path);
|
||||||
value[read(fd, value, sizeof(PROP_VALUE_MAX))] = '\0'; // Null terminate the read value
|
value[read(fd, value, PROP_VALUE_MAX)] = '\0'; // Null terminate the read value
|
||||||
close(fd);
|
close(fd);
|
||||||
|
return value[0] != '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
void persist_getprop(read_cb_t *read_cb) {
|
void persist_getprop(read_cb_t *read_cb) {
|
||||||
@ -182,14 +186,13 @@ void persist_getprop(read_cb_t *read_cb) {
|
|||||||
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0 )
|
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0 )
|
||||||
continue;
|
continue;
|
||||||
char value[PROP_VALUE_MAX];
|
char value[PROP_VALUE_MAX];
|
||||||
file_getprop(entry->d_name, value);
|
if (file_getprop(entry->d_name, value))
|
||||||
if (value[0])
|
|
||||||
read_cb->exec(entry->d_name, value);
|
read_cb->exec(entry->d_name, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CharArray persist_getprop(const char *name) {
|
string persist_getprop(const char *name) {
|
||||||
prop_t prop(name);
|
prop_t prop(name);
|
||||||
if (use_pb) {
|
if (use_pb) {
|
||||||
read_cb_t read_cb(pb_getprop_cb, &prop);
|
read_cb_t read_cb(pb_getprop_cb, &prop);
|
||||||
@ -199,21 +202,20 @@ CharArray persist_getprop(const char *name) {
|
|||||||
} else {
|
} else {
|
||||||
// Try to read from file
|
// Try to read from file
|
||||||
char value[PROP_VALUE_MAX];
|
char value[PROP_VALUE_MAX];
|
||||||
file_getprop(name, value);
|
if (file_getprop(name, value))
|
||||||
if (value[0])
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
return CharArray();
|
return string();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool persist_deleteprop(const char *name) {
|
bool persist_deleteprop(const char *name) {
|
||||||
if (use_pb) {
|
if (use_pb) {
|
||||||
Vector<prop_t> prop_list;
|
vector<prop_t> prop_list;
|
||||||
read_cb_t read_cb(collect_props, &prop_list);
|
read_cb_t read_cb(collect_props, &prop_list);
|
||||||
persist_getprop(&read_cb);
|
persist_getprop(&read_cb);
|
||||||
|
|
||||||
for (auto it = prop_list.begin(); it != prop_list.end(); ++it) {
|
for (auto it = prop_list.begin(); it != prop_list.end(); ++it) {
|
||||||
if (strcmp((*it).name, name) == 0) {
|
if (strcmp(it->name, name) == 0) {
|
||||||
prop_list.erase(it);
|
prop_list.erase(it);
|
||||||
// Dump the props back
|
// Dump the props back
|
||||||
PersistentProperties props = PersistentProperties_init_zero;
|
PersistentProperties props = PersistentProperties_init_zero;
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <vector>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
|
#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
|
||||||
#include "private/_system_properties.h"
|
#include "private/_system_properties.h"
|
||||||
@ -17,6 +19,8 @@
|
|||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "flags.h"
|
#include "flags.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
bool use_pb = false;
|
bool use_pb = false;
|
||||||
static bool verbose = false;
|
static bool verbose = false;
|
||||||
|
|
||||||
@ -74,12 +78,6 @@ illegal:
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define the way to sort prop_t
|
|
||||||
template<>
|
|
||||||
int(*Vector<prop_t>::_cmp)(prop_t&, prop_t&) = [](auto a, auto b) -> int {
|
|
||||||
return strcmp(a.name, b.name);
|
|
||||||
};
|
|
||||||
|
|
||||||
static void read_props(const prop_info *pi, void *read_cb) {
|
static void read_props(const prop_info *pi, void *read_cb) {
|
||||||
__system_property_read_callback(
|
__system_property_read_callback(
|
||||||
pi, [](auto cb, auto name, auto value, auto) -> void
|
pi, [](auto cb, auto name, auto value, auto) -> void
|
||||||
@ -89,12 +87,12 @@ static void read_props(const prop_info *pi, void *read_cb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void collect_props(const char *name, const char *value, void *v_plist) {
|
void collect_props(const char *name, const char *value, void *v_plist) {
|
||||||
Vector<prop_t> &prop_list = *static_cast<Vector<prop_t> *>(v_plist);
|
auto &prop_list = *static_cast<vector<prop_t> *>(v_plist);
|
||||||
prop_list.push_back(prop_t(name, value));
|
prop_list.emplace_back(name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void collect_unique_props(const char *name, const char *value, void *v_plist) {
|
static void collect_unique_props(const char *name, const char *value, void *v_plist) {
|
||||||
Vector<prop_t> &prop_list = *static_cast<Vector<prop_t> *>(v_plist);
|
auto &prop_list = *static_cast<vector<prop_t> *>(v_plist);
|
||||||
for (auto &prop : prop_list) {
|
for (auto &prop : prop_list) {
|
||||||
if (strcmp(name, prop.name) == 0)
|
if (strcmp(name, prop.name) == 0)
|
||||||
return;
|
return;
|
||||||
@ -112,9 +110,9 @@ static int init_resetprop() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void print_props(bool persist) {
|
static void print_props(bool persist) {
|
||||||
Vector<prop_t> prop_list;
|
vector<prop_t> prop_list;
|
||||||
getprop(collect_props, &prop_list, persist);
|
getprop(collect_props, &prop_list, persist);
|
||||||
prop_list.sort();
|
sort(prop_list.begin(), prop_list.end());
|
||||||
for (auto &prop : prop_list)
|
for (auto &prop : prop_list)
|
||||||
printf("[%s]: [%s]\n", prop.name, prop.value);
|
printf("[%s]: [%s]\n", prop.name, prop.value);
|
||||||
}
|
}
|
||||||
@ -128,19 +126,19 @@ int prop_exist(const char *name) {
|
|||||||
return __system_property_find(name) != nullptr;
|
return __system_property_find(name) != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get prop by name, return string (should free manually!)
|
// Get prop by name, return string
|
||||||
CharArray getprop(const char *name, bool persist) {
|
string getprop(const char *name, bool persist) {
|
||||||
if (!check_legal_property_name(name) || init_resetprop())
|
if (!check_legal_property_name(name) || init_resetprop())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
const prop_info *pi = __system_property_find(name);
|
const prop_info *pi = __system_property_find(name);
|
||||||
if (pi == nullptr) {
|
if (pi == nullptr) {
|
||||||
if (persist && strncmp(name, "persist.", 8) == 0) {
|
if (persist && strncmp(name, "persist.", 8) == 0) {
|
||||||
CharArray value = persist_getprop(name);
|
auto value = persist_getprop(name);
|
||||||
if (!value.empty())
|
if (value.empty())
|
||||||
return value;
|
LOGD("resetprop: prop [%s] does not exist\n", name);
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
LOGD("resetprop: prop [%s] does not exist\n", name);
|
return string();
|
||||||
return CharArray();
|
|
||||||
} else {
|
} else {
|
||||||
char value[PROP_VALUE_MAX];
|
char value[PROP_VALUE_MAX];
|
||||||
read_cb_t read_cb;
|
read_cb_t read_cb;
|
||||||
@ -162,7 +160,7 @@ void getprop(void (*callback)(const char *, const char *, void *), void *cookie,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int setprop(const char *name, const char *value, const bool trigger) {
|
int setprop(const char *name, const char *value, bool trigger) {
|
||||||
if (!check_legal_property_name(name))
|
if (!check_legal_property_name(name))
|
||||||
return 1;
|
return 1;
|
||||||
if (init_resetprop())
|
if (init_resetprop())
|
||||||
@ -170,7 +168,7 @@ int setprop(const char *name, const char *value, const bool trigger) {
|
|||||||
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
prop_info *pi = (prop_info*) __system_property_find(name);
|
auto pi = (prop_info*) __system_property_find(name);
|
||||||
if (pi != nullptr) {
|
if (pi != nullptr) {
|
||||||
if (trigger) {
|
if (trigger) {
|
||||||
if (strncmp(name, "ro.", 3) == 0) deleteprop(name);
|
if (strncmp(name, "ro.", 3) == 0) deleteprop(name);
|
||||||
@ -208,7 +206,7 @@ int deleteprop(const char *name, bool persist) {
|
|||||||
return __system_property_del(name) && !(persist && strncmp(name, "persist.", 8) == 0);
|
return __system_property_del(name) && !(persist && strncmp(name, "persist.", 8) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int load_prop_file(const char *filename, const bool trigger) {
|
int load_prop_file(const char *filename, bool trigger) {
|
||||||
if (init_resetprop()) return -1;
|
if (init_resetprop()) return -1;
|
||||||
LOGD("resetprop: Load prop file [%s]\n", filename);
|
LOGD("resetprop: Load prop file [%s]\n", filename);
|
||||||
FILE *fp = xfopen(filename, "re");
|
FILE *fp = xfopen(filename, "re");
|
||||||
@ -254,14 +252,14 @@ int resetprop_main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
bool trigger = true, persist = false;
|
bool trigger = true, persist = false;
|
||||||
char *argv0 = argv[0];
|
char *argv0 = argv[0];
|
||||||
CharArray prop;
|
string prop;
|
||||||
|
|
||||||
--argc;
|
--argc;
|
||||||
++argv;
|
++argv;
|
||||||
|
|
||||||
// Parse flags and -- options
|
// Parse flags and -- options
|
||||||
while (argc && argv[0][0] == '-') {
|
while (argc && argv[0][0] == '-') {
|
||||||
for (int idx = 1; 1; ++idx) {
|
for (int idx = 1; true; ++idx) {
|
||||||
switch (argv[0][idx]) {
|
switch (argv[0][idx]) {
|
||||||
case '-':
|
case '-':
|
||||||
if (strcmp(argv[0], "--file") == 0 && argc == 2) {
|
if (strcmp(argv[0], "--file") == 0 && argc == 2) {
|
||||||
@ -275,10 +273,10 @@ int resetprop_main(int argc, char *argv[]) {
|
|||||||
verbose = true;
|
verbose = true;
|
||||||
continue;
|
continue;
|
||||||
case 'p':
|
case 'p':
|
||||||
persist = 1;
|
persist = true;
|
||||||
continue;
|
continue;
|
||||||
case 'n':
|
case 'n':
|
||||||
trigger = 0;
|
trigger = false;
|
||||||
continue;
|
continue;
|
||||||
case '\0':
|
case '\0':
|
||||||
break;
|
break;
|
||||||
@ -297,8 +295,8 @@ int resetprop_main(int argc, char *argv[]) {
|
|||||||
print_props(persist);
|
print_props(persist);
|
||||||
return 0;
|
return 0;
|
||||||
case 1:
|
case 1:
|
||||||
prop = utils::move(getprop(argv[0], persist));
|
prop = getprop(argv[0], persist);
|
||||||
if (!prop) return 1;
|
if (prop.empty()) return 1;
|
||||||
printf("%s\n", prop.c_str());
|
printf("%s\n", prop.c_str());
|
||||||
return 0;
|
return 0;
|
||||||
case 2:
|
case 2:
|
||||||
|
@ -9,7 +9,6 @@ LOCAL_SRC_FILES := \
|
|||||||
misc.cpp \
|
misc.cpp \
|
||||||
selinux.cpp \
|
selinux.cpp \
|
||||||
logging.cpp \
|
logging.cpp \
|
||||||
xwrap.cpp \
|
xwrap.cpp
|
||||||
CharArray.cpp
|
|
||||||
|
|
||||||
include $(BUILD_STATIC_LIBRARY)
|
include $(BUILD_STATIC_LIBRARY)
|
||||||
|
@ -1,99 +0,0 @@
|
|||||||
#include "CharArray.h"
|
|
||||||
#include "utils.h"
|
|
||||||
|
|
||||||
CharArray::CharArray() : _buf(nullptr), _size(0){}
|
|
||||||
|
|
||||||
CharArray::CharArray(const char *s) : CharArray() {
|
|
||||||
this->operator=(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
CharArray::CharArray(const CharArray &s) : CharArray() {
|
|
||||||
this->operator=(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
CharArray::CharArray(size_t i) {
|
|
||||||
_size = i;
|
|
||||||
_buf = new char[i](); /* Zero initialize */
|
|
||||||
}
|
|
||||||
|
|
||||||
CharArray::~CharArray() {
|
|
||||||
delete[] _buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
CharArray::operator char *() {
|
|
||||||
return _buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
CharArray::operator const char *() const {
|
|
||||||
return _buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *CharArray::c_str() const {
|
|
||||||
return _buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t CharArray::length() const {
|
|
||||||
return strlen(_buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t CharArray::size() const {
|
|
||||||
return _size;
|
|
||||||
}
|
|
||||||
|
|
||||||
CharArray &CharArray::operator=(const CharArray &s) {
|
|
||||||
delete[] _buf;
|
|
||||||
_size = s._size;
|
|
||||||
_buf = new char[_size];
|
|
||||||
memcpy(_buf, s._buf, _size);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
CharArray &CharArray::operator=(const char *s) {
|
|
||||||
delete[] _buf;
|
|
||||||
_buf = strdup2(s, &_size);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
CharArray &CharArray::operator=(CharArray &&s) {
|
|
||||||
delete[] _buf;
|
|
||||||
_size = s._size;
|
|
||||||
_buf = s._buf;
|
|
||||||
s._buf = nullptr;
|
|
||||||
s._size = 0;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CharArray::operator==(const char *s) const {
|
|
||||||
if (_buf == nullptr || s == nullptr)
|
|
||||||
return false;
|
|
||||||
return strcmp(_buf, s) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CharArray::operator==(char *s) const {
|
|
||||||
return *this == (const char *) s;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CharArray::operator!=(const char *s) const {
|
|
||||||
return !(*this == s);
|
|
||||||
}
|
|
||||||
|
|
||||||
int CharArray::compare(const char *s) const {
|
|
||||||
return strcmp(_buf, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
int CharArray::compare(const char *s, size_t len) const {
|
|
||||||
return strncmp(_buf, s, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CharArray::contains(const char *s) const {
|
|
||||||
return s == nullptr ? false : strstr(_buf, s) != nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CharArray::starts_with(const char *s) const {
|
|
||||||
return s == nullptr ? false : compare(s, strlen(s)) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CharArray::empty() const {
|
|
||||||
return _buf == nullptr || _buf[0] == '\0';
|
|
||||||
}
|
|
||||||
|
|
@ -15,6 +15,8 @@
|
|||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "selinux.h"
|
#include "selinux.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
const char **excl_list = nullptr;
|
const char **excl_list = nullptr;
|
||||||
|
|
||||||
static int is_excl(const char *name) {
|
static int is_excl(const char *name) {
|
||||||
@ -307,7 +309,7 @@ void clone_attr(const char *source, const char *target) {
|
|||||||
setattr(target, &a);
|
setattr(target, &a);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fclone_attr(const int sourcefd, const int targetfd) {
|
void fclone_attr(int sourcefd, int targetfd) {
|
||||||
struct file_attr a;
|
struct file_attr a;
|
||||||
fgetattr(sourcefd, &a);
|
fgetattr(sourcefd, &a);
|
||||||
fsetattr(targetfd, &a);
|
fsetattr(targetfd, &a);
|
||||||
@ -388,24 +390,25 @@ void write_zero(int fd, size_t size) {
|
|||||||
lseek(fd, pos + size, SEEK_SET);
|
lseek(fd, pos + size, SEEK_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
int file_to_vector(const char *filename, Vector<CharArray> &arr) {
|
vector<string> file_to_vector(const char *filename) {
|
||||||
|
auto arr = vector<string>();
|
||||||
if (access(filename, R_OK) != 0)
|
if (access(filename, R_OK) != 0)
|
||||||
return 1;
|
return arr;
|
||||||
char *line = nullptr;
|
char *line = nullptr;
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
ssize_t read;
|
ssize_t read;
|
||||||
|
|
||||||
FILE *fp = xfopen(filename, "re");
|
FILE *fp = xfopen(filename, "re");
|
||||||
if (fp == nullptr)
|
if (fp == nullptr)
|
||||||
return 1;
|
return arr;
|
||||||
|
|
||||||
while ((read = getline(&line, &len, fp)) != -1) {
|
while ((read = getline(&line, &len, fp)) != -1) {
|
||||||
// Remove end newline
|
// Remove end newline
|
||||||
if (line[read - 1] == '\n')
|
if (line[read - 1] == '\n')
|
||||||
line[read - 1] = '\0';
|
line[read - 1] = '\0';
|
||||||
arr.push_back(line);
|
arr.emplace_back(line);
|
||||||
}
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
free(line);
|
free(line);
|
||||||
return 0;
|
return arr;
|
||||||
}
|
}
|
||||||
|
@ -1,39 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
/* A wrapper around char array */
|
|
||||||
class CharArray {
|
|
||||||
public:
|
|
||||||
CharArray();
|
|
||||||
CharArray(const char *s);
|
|
||||||
CharArray(const CharArray &s);
|
|
||||||
CharArray(size_t i);
|
|
||||||
~CharArray();
|
|
||||||
|
|
||||||
CharArray &operator=(const CharArray &s);
|
|
||||||
CharArray &operator=(CharArray &&s);
|
|
||||||
CharArray &operator=(const char *s);
|
|
||||||
|
|
||||||
operator char *();
|
|
||||||
operator const char *() const;
|
|
||||||
bool operator==(char *s) const;
|
|
||||||
bool operator==(const char *s) const;
|
|
||||||
bool operator!=(const char *s) const;
|
|
||||||
int compare(const char *s) const;
|
|
||||||
int compare(const char *s, size_t len) const;
|
|
||||||
bool starts_with(const char *s) const;
|
|
||||||
bool contains(const char *s) const;
|
|
||||||
bool empty() const;
|
|
||||||
const char *c_str() const;
|
|
||||||
size_t length() const;
|
|
||||||
size_t size() const;
|
|
||||||
|
|
||||||
/* These 2 ops are incompatible with implicit char* conversion */
|
|
||||||
// char &operator[](size_t i);
|
|
||||||
// const char &operator[](size_t i) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
char *_buf;
|
|
||||||
size_t _size;
|
|
||||||
};
|
|
@ -1,191 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "cpputils.h"
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
class Vector {
|
|
||||||
public:
|
|
||||||
Vector() : _data(0), _size(0), _capacity(0) {}
|
|
||||||
~Vector() { delete []_data; }
|
|
||||||
|
|
||||||
class iterator {
|
|
||||||
friend class Vector;
|
|
||||||
|
|
||||||
public:
|
|
||||||
iterator(T* n= 0): _node(n) {}
|
|
||||||
iterator(const iterator& i): _node(i._node) {}
|
|
||||||
~iterator() {} // Should NOT delete _node
|
|
||||||
|
|
||||||
const T& operator * () const { return (*_node); }
|
|
||||||
T& operator * () { return (*_node); }
|
|
||||||
iterator& operator ++ () {
|
|
||||||
++_node;
|
|
||||||
return (*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator operator ++ (int) {
|
|
||||||
iterator temp = *this;
|
|
||||||
++_node;
|
|
||||||
return temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator& operator -- () {
|
|
||||||
--_node;
|
|
||||||
return (*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator operator -- (int) {
|
|
||||||
iterator temp = *this;
|
|
||||||
--_node;
|
|
||||||
return temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator operator + (int i) const {
|
|
||||||
iterator temp = *this;
|
|
||||||
temp += i;
|
|
||||||
return temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator& operator += (int i) {
|
|
||||||
_node += i;
|
|
||||||
return (*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator& operator = (const iterator& i) {
|
|
||||||
_node = i._node;
|
|
||||||
return (*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator != (const iterator& i) const {
|
|
||||||
return _node != i._node;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator == (const iterator& i) const { return !(*this != i); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
T* _node;
|
|
||||||
};
|
|
||||||
|
|
||||||
Vector &operator=(const Vector& a) {
|
|
||||||
delete [] _data;
|
|
||||||
_data = nullptr;
|
|
||||||
_size = a._size;
|
|
||||||
_capacity = a._capacity;
|
|
||||||
if (_capacity) {
|
|
||||||
_data = new T[_capacity];
|
|
||||||
for(int i = 0; i < _size; ++i)
|
|
||||||
_data[i] = a[i];
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector &operator=(Vector&& a) {
|
|
||||||
delete [] _data;
|
|
||||||
_size = a._size;
|
|
||||||
_capacity = a._capacity;
|
|
||||||
_data = a._data;
|
|
||||||
a._size = 0;
|
|
||||||
a._capacity = 0;
|
|
||||||
a._data = nullptr;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator begin() const { return iterator(_data); }
|
|
||||||
|
|
||||||
iterator end() const { return iterator(_data + _size); }
|
|
||||||
|
|
||||||
bool empty() const { return !_size; }
|
|
||||||
|
|
||||||
size_t size() const { return _size; }
|
|
||||||
|
|
||||||
T& operator [] (size_t i) { return _data[i]; }
|
|
||||||
|
|
||||||
const T& operator [] (size_t i) const { return _data[i]; }
|
|
||||||
|
|
||||||
const T& back() const { return _data[_size - 1]; }
|
|
||||||
|
|
||||||
void push_back(const T& x) {
|
|
||||||
if(_size == _capacity)
|
|
||||||
expand();
|
|
||||||
_data[_size] = x;
|
|
||||||
++_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
void push_back(T&& x) {
|
|
||||||
if(_size == _capacity)
|
|
||||||
expand();
|
|
||||||
_data[_size] = utils::move(x);
|
|
||||||
++_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
void pop_front() { erase(begin()); }
|
|
||||||
|
|
||||||
void pop_back() { if(_size) --_size; }
|
|
||||||
|
|
||||||
bool erase(iterator pos) {
|
|
||||||
T* d = pos._node;
|
|
||||||
if (_size == 0 || d < _data || d >= _data + _size)
|
|
||||||
return false;
|
|
||||||
for (; d < _data + _size - 1; ++d)
|
|
||||||
*d = utils::move(*(d + 1));
|
|
||||||
--_size;
|
|
||||||
return true;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
bool erase(const T& x) {
|
|
||||||
for (T* i = _data; i < _data + _size; ++i) {
|
|
||||||
if(*i == x) {
|
|
||||||
erase(iterator(i));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear(bool dealloc = false) {
|
|
||||||
_size = 0;
|
|
||||||
if (dealloc) {
|
|
||||||
_capacity = 0;
|
|
||||||
delete [] _data;
|
|
||||||
_data = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void sort() {
|
|
||||||
qsort(_data, _size, sizeof(T), compare);
|
|
||||||
}
|
|
||||||
|
|
||||||
T* data() { return _data; }
|
|
||||||
|
|
||||||
const T* data() const { return _data; }
|
|
||||||
|
|
||||||
// void reserve(size_t n) { ... }
|
|
||||||
// void resize(size_t n) { ... }
|
|
||||||
|
|
||||||
private:
|
|
||||||
T* _data;
|
|
||||||
size_t _size; // number of valid elements
|
|
||||||
size_t _capacity; // max number of elements
|
|
||||||
static int(*_cmp)(T&, T&);
|
|
||||||
|
|
||||||
static int compare(const void *a, const void *b) {
|
|
||||||
return _cmp ? _cmp(*((T*) a), *((T*) b)) : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void expand() {
|
|
||||||
if (_capacity == 0)
|
|
||||||
_capacity = 1;
|
|
||||||
else
|
|
||||||
_capacity *= 2;
|
|
||||||
T* temp = _data;
|
|
||||||
_data = new T[_capacity];
|
|
||||||
for(int i = 0; i < _size; ++i)
|
|
||||||
_data[i] = utils::move(temp[i]);
|
|
||||||
delete [] temp;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
int(* Vector<T>::_cmp)(T&, T&) = nullptr;
|
|
@ -1,12 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
namespace utils {
|
|
||||||
template< class T > struct remove_reference {typedef T type;};
|
|
||||||
template< class T > struct remove_reference<T&> {typedef T type;};
|
|
||||||
template< class T > struct remove_reference<T&&> {typedef T type;};
|
|
||||||
|
|
||||||
template< class T >
|
|
||||||
constexpr typename remove_reference<T>::type&& move( T&& t ) noexcept {
|
|
||||||
return static_cast<typename remove_reference<T>::type&&>(t);
|
|
||||||
}
|
|
||||||
}
|
|
@ -13,15 +13,17 @@
|
|||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
#include "Vector.h"
|
#include <string>
|
||||||
#include "CharArray.h"
|
#include <vector>
|
||||||
#include "cpputils.h"
|
|
||||||
|
|
||||||
int file_to_vector(const char *filename, Vector<CharArray> &arr);
|
#define str_contains(s, ss) ((s).find(ss) != string::npos)
|
||||||
|
#define str_starts(s, ss) ((s).compare(0, strlen(ss), ss) == 0)
|
||||||
|
|
||||||
|
std::vector<std::string> file_to_vector(const char *filename);
|
||||||
char *strdup2(const char *s, size_t *size = nullptr);
|
char *strdup2(const char *s, size_t *size = nullptr);
|
||||||
|
|
||||||
int exec_array(bool err, int *fd, void (*pre_exec)(void), const char **argv);
|
int exec_array(bool err, int *fd, void (*pre_exec)(), const char **argv);
|
||||||
int exec_command(bool err, int *fd, void (*cb)(void), const char *argv0, ...);
|
int exec_command(bool err, int *fd, void (*cb)(), const char *argv0, ...);
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
@ -134,7 +136,7 @@ int fgetattr(int fd, struct file_attr *a);
|
|||||||
int setattr(const char *path, struct file_attr *a);
|
int setattr(const char *path, struct file_attr *a);
|
||||||
int setattrat(int dirfd, const char *pathname, struct file_attr *a);
|
int setattrat(int dirfd, const char *pathname, struct file_attr *a);
|
||||||
int fsetattr(int fd, struct file_attr *a);
|
int fsetattr(int fd, struct file_attr *a);
|
||||||
void fclone_attr(const int sourcefd, const int targetfd);
|
void fclone_attr(int sourcefd, int targetfd);
|
||||||
void clone_attr(const char *source, const char *target);
|
void clone_attr(const char *source, const char *target);
|
||||||
void mmap_ro(const char *filename, void **buf, size_t *size);
|
void mmap_ro(const char *filename, void **buf, size_t *size);
|
||||||
void mmap_rw(const char *filename, void **buf, size_t *size);
|
void mmap_rw(const char *filename, void **buf, size_t *size);
|
||||||
|
@ -11,10 +11,13 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <sys/sysmacros.h>
|
#include <sys/sysmacros.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "logging.h"
|
#include "logging.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
unsigned get_shell_uid() {
|
unsigned get_shell_uid() {
|
||||||
struct passwd* ppwd = getpwnam("shell");
|
struct passwd* ppwd = getpwnam("shell");
|
||||||
if (nullptr == ppwd)
|
if (nullptr == ppwd)
|
||||||
@ -199,7 +202,7 @@ int exec_array(bool err, int *fd, void (*pre_exec)(void), const char **argv) {
|
|||||||
|
|
||||||
static int v_exec_command(bool err, int *fd, void (*cb)(void), const char *argv0, va_list argv) {
|
static int v_exec_command(bool err, int *fd, void (*cb)(void), const char *argv0, va_list argv) {
|
||||||
// Collect va_list into vector
|
// Collect va_list into vector
|
||||||
Vector<const char *> args;
|
vector<const char *> args;
|
||||||
args.push_back(argv0);
|
args.push_back(argv0);
|
||||||
for (const char *arg = va_arg(argv, char*); arg; arg = va_arg(argv, char*))
|
for (const char *arg = va_arg(argv, char*); arg; arg = va_arg(argv, char*))
|
||||||
args.push_back(arg);
|
args.push_back(arg);
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
#include <new>
|
#include <new>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* Override libc++ new implementation
|
||||||
|
* to optimize final build size */
|
||||||
|
|
||||||
void* operator new(std::size_t s) { return malloc(s); }
|
void* operator new(std::size_t s) { return malloc(s); }
|
||||||
void* operator new[](std::size_t s) { return malloc(s); }
|
void* operator new[](std::size_t s) { return malloc(s); }
|
||||||
void operator delete(void *p) { free(p); }
|
void operator delete(void *p) { free(p); }
|
||||||
|
@ -86,7 +86,7 @@ ssize_t xread(int fd, void *buf, size_t count) {
|
|||||||
ssize_t xxread(int fd, void *buf, size_t count) {
|
ssize_t xxread(int fd, void *buf, size_t count) {
|
||||||
int ret = read(fd, buf, count);
|
int ret = read(fd, buf, count);
|
||||||
if (count != ret) {
|
if (count != ret) {
|
||||||
PLOGE("read");
|
PLOGE("read (%d != %d)", count, ret);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user