Minor MagiskHide adjustments

- Fail fast on unsupported systems
- Show proper fail message on unsupported systems
- inotify_fd shall be swapped out before closing to prevent
  the proc_monitor thread to read from incomplete inotify fd
This commit is contained in:
topjohnwu 2019-02-14 04:08:05 -05:00
parent d584360de2
commit 99db0672b4
4 changed files with 34 additions and 42 deletions

View File

@ -297,7 +297,7 @@ static void set_hide_config() {
} }
static inline void launch_err(int client, int code = DAEMON_ERROR) { static inline void launch_err(int client, int code = DAEMON_ERROR) {
if (code == DAEMON_ERROR) if (code != HIDE_IS_ENABLED)
hide_enabled = false; hide_enabled = false;
if (client >= 0) { if (client >= 0) {
write_int(client, code); write_int(client, code);
@ -315,6 +315,9 @@ void launch_magiskhide(int client) {
if (hide_enabled) if (hide_enabled)
launch_err(client, HIDE_IS_ENABLED); launch_err(client, HIDE_IS_ENABLED);
if (access("/proc/1/ns/mnt", F_OK) != 0)
launch_err(client, HIDE_NO_NS);
hide_enabled = true; hide_enabled = true;
set_hide_config(); set_hide_config();
LOGI("* Starting MagiskHide\n"); LOGI("* Starting MagiskHide\n");

View File

@ -20,16 +20,12 @@ bool hide_enabled = false;
FULL_VER(MagiskHide) "\n\n" FULL_VER(MagiskHide) "\n\n"
"Usage: %s [--option [arguments...] ]\n\n" "Usage: %s [--option [arguments...] ]\n\n"
"Options:\n" "Options:\n"
" --status Return the status of MagiskHide\n" " --status Return the status of magiskhide\n"
" --enable Start magiskhide\n" " --enable Start magiskhide\n"
" --disable Stop magiskhide\n" " --disable Stop magiskhide\n"
" --add TARGET Add TARGET to the hide list\n" " --add PKG Add PKG to the hide list\n"
" --rm TARGET Remove TARGET from the hide list\n" " --rm PKG Remove PKG from the hide list\n"
" --ls Print out the current hide list\n" " --ls List the current hide list\n"
"\n"
"TARGET can be either a package name or a specific component name\n"
"If TARGET is a package name, all components of the app will be targeted\n"
"A component name is composed of <pkg>/<cls>\n"
, arg0); , arg0);
exit(1); exit(1);
} }
@ -122,6 +118,9 @@ int magiskhide_main(int argc, char *argv[]) {
case HIDE_ITEM_NOT_EXIST: case HIDE_ITEM_NOT_EXIST:
fprintf(stderr, "[%s] does not exist in hide list\n", argv[2]); fprintf(stderr, "[%s] does not exist in hide list\n", argv[2]);
break; break;
case HIDE_NO_NS:
fprintf(stderr, "Your kernel doesn't support mount namespace\n");
break;
/* Errors */ /* Errors */
case ROOT_REQUIRED: case ROOT_REQUIRED:
@ -129,7 +128,7 @@ int magiskhide_main(int argc, char *argv[]) {
break; break;
case DAEMON_ERROR: case DAEMON_ERROR:
default: default:
fprintf(stderr, "Error occured in daemon...\n"); fprintf(stderr, "Daemon error\n");
return DAEMON_ERROR; return DAEMON_ERROR;
} }

View File

@ -68,7 +68,8 @@ enum {
HIDE_IS_ENABLED = DAEMON_LAST, HIDE_IS_ENABLED = DAEMON_LAST,
HIDE_NOT_ENABLED, HIDE_NOT_ENABLED,
HIDE_ITEM_EXIST, HIDE_ITEM_EXIST,
HIDE_ITEM_NOT_EXIST HIDE_ITEM_NOT_EXIST,
HIDE_NO_NS
}; };
#endif #endif

View File

@ -33,10 +33,6 @@ extern char *system_block, *vendor_block, *data_block;
static int inotify_fd = -1; static int inotify_fd = -1;
#define EVENT_SIZE sizeof(struct inotify_event)
#define EVENT_BUF_LEN (1024 * (EVENT_SIZE + 16))
#define __ALIGN_EVENT __attribute__ ((aligned(__alignof__(struct inotify_event))))
// 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");
@ -208,7 +204,7 @@ static char *append_path(char *eof, const char *name) {
} }
#define DATA_APP "/data/app" #define DATA_APP "/data/app"
static int new_inotify;
static void find_apks(char *path, char *eof) { static void find_apks(char *path, char *eof) {
DIR *dir = opendir(path); DIR *dir = opendir(path);
if (dir == nullptr) if (dir == nullptr)
@ -231,7 +227,7 @@ static void find_apks(char *path, char *eof) {
if (s == path + sizeof(DATA_APP)) { if (s == path + sizeof(DATA_APP)) {
*dash = '-'; *dash = '-';
append_path(eof, entry->d_name); append_path(eof, entry->d_name);
xinotify_add_watch(inotify_fd, path, IN_OPEN | IN_DELETE); xinotify_add_watch(new_inotify, path, IN_OPEN | IN_DELETE);
*eof = '\0'; *eof = '\0';
break; break;
} }
@ -247,23 +243,27 @@ static void find_apks(char *path, char *eof) {
void update_inotify_mask() { void update_inotify_mask() {
char buf[4096]; char buf[4096];
if (inotify_fd >= 0) new_inotify = inotify_init();
close(inotify_fd); if (new_inotify < 0) {
inotify_fd = inotify_init();
if (inotify_fd < 0) {
LOGE("proc_monitor: Cannot initialize inotify: %s\n", strerror(errno)); LOGE("proc_monitor: Cannot initialize inotify: %s\n", strerror(errno));
term_thread(TERM_THREAD); term_thread(TERM_THREAD);
} }
LOGI("proc_monitor: Updating APK list\n"); LOGI("proc_monitor: Updating inotify list\n");
strcpy(buf, DATA_APP); strcpy(buf, DATA_APP);
pthread_mutex_lock(&list_lock); pthread_mutex_lock(&list_lock);
find_apks(buf, buf + sizeof(DATA_APP) - 1); find_apks(buf, buf + sizeof(DATA_APP) - 1);
pthread_mutex_unlock(&list_lock); pthread_mutex_unlock(&list_lock);
// Add /data/app itself to the watch list to detect app (un)installations/updates // Add /data/app itself to the watch list to detect app (un)installations/updates
xinotify_add_watch(inotify_fd, DATA_APP, IN_CLOSE_WRITE | IN_MOVED_TO | IN_DELETE); xinotify_add_watch(new_inotify, DATA_APP, IN_CLOSE_WRITE | IN_MOVED_TO | IN_DELETE);
if (inotify_fd >= 0) {
// Swap and close old fd
int tmp = inotify_fd;
inotify_fd = new_inotify;
close(tmp);
}
} }
void proc_monitor() { void proc_monitor() {
@ -278,25 +278,13 @@ void proc_monitor() {
act.sa_handler = term_thread; act.sa_handler = term_thread;
sigaction(TERM_THREAD, &act, nullptr); sigaction(TERM_THREAD, &act, nullptr);
if (access("/proc/1/ns/mnt", F_OK) != 0) {
LOGE("proc_monitor: Your kernel doesn't support mount namespace :(\n");
term_thread(TERM_THREAD);
}
// Read inotify events // Read inotify events
struct inotify_event *event; struct inotify_event *event;
ssize_t len; ssize_t len;
char *p; char *p;
char buffer[EVENT_BUF_LEN] __ALIGN_EVENT; char buf[4096];
for (;;) { while ((len = read(inotify_fd, buf, sizeof(buf))) >= 0) {
len = read(inotify_fd, buffer, EVENT_BUF_LEN); for (p = buf; p < buf + len; ) {
if (len == -1) {
PLOGE("proc_monitor: read inotify");
sleep(1);
continue;
}
for (p = buffer; p < buffer + len; ) {
event = (struct inotify_event *)p; event = (struct inotify_event *)p;
if (event->mask & IN_OPEN) { if (event->mask & IN_OPEN) {
@ -314,7 +302,8 @@ void proc_monitor() {
break; break;
} }
p += EVENT_SIZE + event->len; p += sizeof(*event) + event->len;
} }
} }
PLOGE("proc_monitor: read inotify");
} }