Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
M
Magisk
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
Magisk
Commits
3942858c
Commit
3942858c
authored
Oct 08, 2017
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Introduce a single general purpose logcat monitor
parent
03c8d716
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
193 additions
and
106 deletions
+193
-106
bootstages.c
jni/daemon/bootstages.c
+3
-21
daemon.c
jni/daemon/daemon.c
+3
-0
log_monitor.c
jni/daemon/log_monitor.c
+131
-14
daemon.h
jni/include/daemon.h
+0
-4
logging.h
jni/include/logging.h
+11
-0
utils.h
jni/include/utils.h
+1
-0
proc_monitor.c
jni/magiskhide/proc_monitor.c
+33
-67
misc.c
jni/utils/misc.c
+11
-0
No files found.
jni/daemon/bootstages.c
View file @
3942858c
...
...
@@ -28,10 +28,6 @@ static int seperate_vendor = 0;
extern
char
**
environ
;
#ifdef MAGISK_DEBUG
static
int
debug_log_pid
,
debug_log_fd
;
#endif
/******************
* Node structure *
******************/
...
...
@@ -599,15 +595,8 @@ void post_fs_data(int client) {
if
(
!
check_data
())
goto
unblock
;
// Start log monitor
monitor_logs
();
#ifdef MAGISK_DEBUG
// Log everything initially
debug_log_fd
=
xopen
(
DEBUG_LOG
,
O_WRONLY
|
O_CREAT
|
O_CLOEXEC
|
O_TRUNC
,
0644
);
xwrite
(
debug_log_fd
,
"Boot logs:
\n
"
,
11
);
debug_log_pid
=
exec_command
(
0
,
&
debug_log_fd
,
NULL
,
"logcat"
,
"-v"
,
"thread"
,
NULL
);
#endif
// Start the debug log
start_debug_full_log
();
LOGI
(
"** post-fs-data mode running
\n
"
);
...
...
@@ -804,12 +793,5 @@ core_only:
buf
=
buf2
=
NULL
;
vec_deep_destroy
(
&
module_list
);
#ifdef MAGISK_DEBUG
// Stop recording the boot logcat after every boot task is done
kill
(
debug_log_pid
,
SIGTERM
);
waitpid
(
debug_log_pid
,
NULL
,
0
);
// Then start to log Magisk verbosely
xwrite
(
debug_log_fd
,
"
\n
Verbose logs:
\n
"
,
15
);
debug_log_pid
=
exec_command
(
0
,
&
debug_log_fd
,
NULL
,
"logcat"
,
"-v"
,
"thread"
,
"-s"
,
"Magisk"
,
NULL
);
#endif
stop_debug_full_log
();
}
jni/daemon/daemon.c
View file @
3942858c
...
...
@@ -123,6 +123,9 @@ void start_daemon() {
xdup2
(
fd
,
STDERR_FILENO
);
close
(
fd
);
// Start the log monitor
monitor_logs
();
// Patch selinux with medium patch before we do anything
load_policydb
(
SELINUX_POLICY
);
sepol_med_rules
();
...
...
jni/daemon/log_monitor.c
View file @
3942858c
/* log_monitor.c - New thread to monitor logcat
*
*
Open a new thread to call logcat and get logs with tag "Magisk"
*
Also, write the logs to a log file for debugging purpose
*
*
A universal logcat monitor for many usages. Add listeners to the list,
*
and the pointer of the new log line will be sent through pipes to trigger
*
asynchronous events without polling
*/
#include <stdio.h>
...
...
@@ -13,33 +13,150 @@
#include "magisk.h"
#include "utils.h"
#include "daemon.h"
int
logcat_events
[]
=
{
-
1
,
-
1
,
-
1
};
static
int
is_restart
=
0
;
#ifdef MAGISK_DEBUG
static
int
debug_log_pid
,
debug_log_fd
;
#endif
static
void
*
logger_thread
(
void
*
args
)
{
// Setup error handler
err_handler
=
exit_thread
;
rename
(
LOGFILE
,
LASTLOG
);
int
log_fd
,
log_pid
;
log_fd
=
xopen
(
LOGFILE
,
O_WRONLY
|
O_CREAT
|
O_CLOEXEC
|
O_TRUNC
,
0644
);
int
log_fd
=
-
1
,
log_pid
;
char
line
[
4096
];
while
(
1
)
{
// Clear buffer
exec_command_sync
(
"logcat"
,
"-b"
,
"all"
,
"-c"
,
NULL
);
// Start logcat
log_pid
=
exec_command
(
0
,
&
log_fd
,
NULL
,
"logcat"
,
"-v"
,
"thread"
,
"Magisk:I"
,
"*:S"
,
NULL
);
if
(
log_pid
>
0
)
waitpid
(
log_pid
,
NULL
,
0
);
// For some reason it went here, clear buffer and restart
exec_command_sync
(
"logcat"
,
"-c"
,
NULL
);
log_pid
=
exec_command
(
0
,
&
log_fd
,
NULL
,
"logcat"
,
"-b"
,
"events"
,
"-b"
,
"default"
,
"-s"
,
"am_proc_start"
,
"Magisk"
,
NULL
);
while
(
fdgets
(
line
,
sizeof
(
line
),
log_fd
))
{
for
(
int
i
=
0
;
i
<
(
sizeof
(
logcat_events
)
/
sizeof
(
int
));
++
i
)
{
if
(
logcat_events
[
i
]
>
0
)
{
char
*
s
=
strdup
(
line
);
xwrite
(
logcat_events
[
i
],
&
s
,
sizeof
(
s
));
}
}
if
(
kill
(
log_pid
,
0
))
break
;
}
}
// Should never be here, but well...
return
NULL
;
}
/* Start a new thread to monitor logcat and dump to logfile */
static
void
*
magisk_log_thread
(
void
*
args
)
{
// Setup error handler
err_handler
=
exit_thread
;
int
have_data
=
0
;
// Temp buffer for logs before we have data access
struct
vector
logs
;
vec_init
(
&
logs
);
FILE
*
log
;
int
pipefd
[
2
];
if
(
xpipe2
(
pipefd
,
O_CLOEXEC
)
==
-
1
)
return
NULL
;
// Register our listener
logcat_events
[
LOG_EVENT
]
=
pipefd
[
1
];
for
(
char
*
line
;
xxread
(
pipefd
[
0
],
&
line
,
sizeof
(
line
))
>
0
;
free
(
line
))
{
char
*
ss
;
if
((
ss
=
strstr
(
line
,
" Magisk"
))
&&
(
ss
[
-
1
]
!=
'D'
)
&&
(
ss
[
-
1
]
!=
'V'
))
{
if
(
!
have_data
)
{
if
((
have_data
=
check_data
()))
{
// Dump buffered logs to file
if
(
!
is_restart
)
rename
(
LOGFILE
,
LASTLOG
);
log
=
xfopen
(
LOGFILE
,
"a"
);
setbuf
(
log
,
NULL
);
char
*
tmp
;
vec_for_each
(
&
logs
,
tmp
)
{
fprintf
(
log
,
"%s"
,
tmp
);
free
(
tmp
);
}
vec_destroy
(
&
logs
);
}
else
{
vec_push_back
(
&
logs
,
line
);
}
}
if
(
have_data
)
fprintf
(
log
,
"%s"
,
line
);
}
}
return
NULL
;
}
static
void
*
debug_magisk_log_thread
(
void
*
args
)
{
// Setup error handler
err_handler
=
exit_thread
;
FILE
*
log
=
xfopen
(
DEBUG_LOG
,
"a"
);
setbuf
(
log
,
NULL
);
int
pipefd
[
2
];
if
(
xpipe2
(
pipefd
,
O_CLOEXEC
)
==
-
1
)
return
NULL
;
// Register our listener
logcat_events
[
DEBUG_EVENT
]
=
pipefd
[
1
];
for
(
char
*
line
;
xxread
(
pipefd
[
0
],
&
line
,
sizeof
(
line
))
>
0
;
free
(
line
))
{
char
*
ss
;
if
((
ss
=
strstr
(
line
,
"Magisk"
)))
fprintf
(
log
,
"%s"
,
line
);
}
return
NULL
;
}
/* Start new threads to monitor logcat and dump to logfile */
void
monitor_logs
()
{
pthread_t
thread
;
is_restart
=
check_data
();
// Start log file dumper before monitor
xpthread_create
(
&
thread
,
NULL
,
magisk_log_thread
,
NULL
);
pthread_detach
(
thread
);
#ifdef MAGISK_DEBUG
if
(
is_restart
)
{
// Restart debug logs
xpthread_create
(
&
thread
,
NULL
,
debug_magisk_log_thread
,
NULL
);
pthread_detach
(
thread
);
}
#endif
// Start logcat monitor
xpthread_create
(
&
thread
,
NULL
,
logger_thread
,
NULL
);
pthread_detach
(
thread
);
}
void
start_debug_full_log
()
{
#ifdef MAGISK_DEBUG
// Log everything initially
debug_log_fd
=
xopen
(
DEBUG_LOG
,
O_WRONLY
|
O_CREAT
|
O_CLOEXEC
|
O_TRUNC
,
0644
);
debug_log_pid
=
exec_command
(
0
,
&
debug_log_fd
,
NULL
,
"logcat"
,
NULL
);
close
(
debug_log_fd
);
#endif
}
void
stop_debug_full_log
()
{
#ifdef MAGISK_DEBUG
// Stop recording the boot logcat after every boot task is done
kill
(
debug_log_pid
,
SIGTERM
);
waitpid
(
debug_log_pid
,
NULL
,
0
);
pthread_t
thread
;
// Start debug thread
xpthread_create
(
&
thread
,
NULL
,
debug_magisk_log_thread
,
NULL
);
pthread_detach
(
thread
);
#endif
}
jni/include/daemon.h
View file @
3942858c
...
...
@@ -50,10 +50,6 @@ void write_int(int fd, int val);
char
*
read_string
(
int
fd
);
void
write_string
(
int
fd
,
const
char
*
val
);
// log_monitor.c
void
monitor_logs
();
/***************
* Boot Stages *
***************/
...
...
jni/include/logging.h
View file @
3942858c
...
...
@@ -34,6 +34,17 @@ static inline void do_nothing() {}
#define PLOGE(fmt, args...) { LOGE(fmt " failed with %d: %s", ##args, errno, strerror(errno)); err_handler(); }
enum
{
HIDE_EVENT
,
LOG_EVENT
,
DEBUG_EVENT
};
extern
int
logcat_events
[];
void
monitor_logs
();
void
start_debug_full_log
();
void
stop_debug_full_log
();
#else // IS_DAEMON
#include <stdio.h>
...
...
jni/include/utils.h
View file @
3942858c
...
...
@@ -90,6 +90,7 @@ void fclone_attr(const int sourcefd, const int targetfd);
void
clone_attr
(
const
char
*
source
,
const
char
*
target
);
void
get_client_cred
(
int
fd
,
struct
ucred
*
cred
);
int
switch_mnt_ns
(
int
pid
);
int
fork_dont_care
();
// img.c
...
...
jni/magiskhide/proc_monitor.c
View file @
3942858c
...
...
@@ -19,27 +19,20 @@
#include "utils.h"
#include "magiskhide.h"
static
int
zygote_num
;
static
char
init_ns
[
32
],
zygote_ns
[
2
][
32
],
cache_block
[
256
];
static
int
log_pid
,
log_fd
,
target_pid
,
has_cache
=
1
;
static
char
*
buffer
;
static
int
zygote_num
,
has_cache
=
1
,
pipefd
[
2
]
=
{
-
1
,
-
1
};
// Workaround for the lack of pthread_cancel
static
void
quit_pthread
(
int
sig
)
{
err_handler
=
do_nothing
;
LOGD
(
"proc_monitor: running cleanup
\n
"
);
destroy_list
();
free
(
buffer
);
hideEnabled
=
0
;
// Kill the logging if needed
if
(
log_pid
>
0
)
{
kill
(
log_pid
,
SIGTERM
);
waitpid
(
log_pid
,
NULL
,
0
);
close
(
log_fd
);
}
// Resume process if possible
if
(
target_pid
>
0
)
kill
(
target_pid
,
SIGCONT
);
// Unregister listener
logcat_events
[
HIDE_EVENT
]
=
-
1
;
close
(
pipefd
[
0
]);
close
(
pipefd
[
1
]);
pipefd
[
0
]
=
pipefd
[
1
]
=
-
1
;
pthread_mutex_destroy
(
&
hide_lock
);
pthread_mutex_destroy
(
&
file_lock
);
LOGD
(
"proc_monitor: terminating...
\n
"
);
...
...
@@ -47,7 +40,7 @@ static void quit_pthread(int sig) {
}
static
void
proc_monitor_err
()
{
LOG
D
(
"proc_monitor: error occured, stopping magiskhide services
\n
"
);
LOG
E
(
"proc_monitor: error occured, stopping magiskhide services
\n
"
);
quit_pthread
(
SIGUSR1
);
}
...
...
@@ -77,25 +70,24 @@ static void lazy_unmount(const char* mountpoint) {
}
static
void
hide_daemon_err
()
{
LOGD
(
"hide_daemon: error occured, stopping magiskhide services
\n
"
);
_exit
(
-
1
);
LOGE
(
"hide_daemon: error occured
\n
"
);
}
static
void
hide_daemon
(
int
pid
)
{
LOGD
(
"hide_daemon: start unmount for pid=[%d]
\n
"
,
pid
);
// When an error occurs, report its failure
to main process
// When an error occurs, report its failure
err_handler
=
hide_daemon_err
;
char
*
line
;
char
*
line
,
buffer
[
PATH_MAX
]
;
struct
vector
mount_list
;
manage_selinux
();
clean_magisk_props
();
if
(
switch_mnt_ns
(
pid
))
return
;
goto
exit
;
snprintf
(
buffer
,
PATH_MAX
,
"/proc/%d/mounts"
,
pid
);
snprintf
(
buffer
,
sizeof
(
buffer
)
,
"/proc/%d/mounts"
,
pid
);
vec_init
(
&
mount_list
);
file_to_vector
(
buffer
,
&
mount_list
);
...
...
@@ -132,7 +124,7 @@ static void hide_daemon(int pid) {
vec_destroy
(
&
mount_list
);
// Re-read mount infos
snprintf
(
buffer
,
PATH_MAX
,
"/proc/%d/mounts"
,
pid
);
snprintf
(
buffer
,
sizeof
(
buffer
)
,
"/proc/%d/mounts"
,
pid
);
vec_init
(
&
mount_list
);
file_to_vector
(
buffer
,
&
mount_list
);
...
...
@@ -145,8 +137,12 @@ static void hide_daemon(int pid) {
free
(
line
);
}
// Free uo memory
exit:
// Send resume signal
kill
(
pid
,
SIGCONT
);
// Free up memory
vec_destroy
(
&
mount_list
);
_exit
(
0
);
}
void
proc_monitor
()
{
...
...
@@ -158,9 +154,7 @@ void proc_monitor() {
// The error handler should stop magiskhide services
err_handler
=
proc_monitor_err
;
log_pid
=
target_pid
=
-
1
;
buffer
=
xmalloc
(
PATH_MAX
);
cache_block
[
0
]
=
'\0'
;
// Get the mount namespace of init
...
...
@@ -188,20 +182,15 @@ void proc_monitor() {
break
;
}
while
(
1
)
{
// Clear previous logcat buffer
exec_command_sync
(
"logcat"
,
"-b"
,
"events"
,
"-c"
,
NULL
);
// Monitor am_proc_start
log_fd
=
-
1
;
log_pid
=
exec_command
(
0
,
&
log_fd
,
NULL
,
"logcat"
,
"-b"
,
"events"
,
"-v"
,
"raw"
,
"-s"
,
"am_proc_start"
,
NULL
);
// Register our listener to logcat monitor
xpipe2
(
pipefd
,
O_CLOEXEC
);
logcat_events
[
HIDE_EVENT
]
=
pipefd
[
1
];
if
(
log_pid
<
0
)
continue
;
if
(
kill
(
log_pid
,
0
))
continue
;
while
(
fdgets
(
buffer
,
PATH_MAX
,
log_fd
))
{
for
(
char
*
log
,
*
line
;
xxread
(
pipefd
[
0
],
&
log
,
sizeof
(
log
))
>
0
;
free
(
log
))
{
char
*
ss
;
if
((
ss
=
strstr
(
log
,
"am_proc_start"
))
&&
(
ss
=
strchr
(
ss
,
'['
)))
{
int
pid
,
ret
,
comma
=
0
;
char
*
pos
=
buffer
,
*
line
,
processName
[
256
];
char
*
pos
=
ss
,
processName
[
256
],
ns
[
32
];
while
(
1
)
{
pos
=
strchr
(
pos
,
','
);
...
...
@@ -212,9 +201,9 @@ void proc_monitor() {
}
if
(
comma
==
6
)
ret
=
sscanf
(
buffer
,
"[%*d %d %*d %*d %256s"
,
&
pid
,
processName
);
ret
=
sscanf
(
ss
,
"[%*d %d %*d %*d %256s"
,
&
pid
,
processName
);
else
ret
=
sscanf
(
buffer
,
"[%*d %d %*d %256s"
,
&
pid
,
processName
);
ret
=
sscanf
(
ss
,
"[%*d %d %*d %256s"
,
&
pid
,
processName
);
if
(
ret
!=
2
)
continue
;
...
...
@@ -225,12 +214,11 @@ void proc_monitor() {
pthread_mutex_lock
(
&
hide_lock
);
vec_for_each
(
hide_list
,
line
)
{
if
(
strcmp
(
processName
,
line
)
==
0
)
{
target_pid
=
pid
;
while
(
1
)
{
ret
=
1
;
for
(
int
i
=
0
;
i
<
zygote_num
;
++
i
)
{
read_namespace
(
target_pid
,
buffer
,
32
);
if
(
strcmp
(
buffer
,
zygote_ns
[
i
])
==
0
)
{
read_namespace
(
pid
,
ns
,
sizeof
(
ns
)
);
if
(
strcmp
(
ns
,
zygote_ns
[
i
])
==
0
)
{
usleep
(
50
);
ret
=
0
;
break
;
...
...
@@ -240,43 +228,21 @@ void proc_monitor() {
}
// Send pause signal ASAP
if
(
kill
(
target_
pid
,
SIGSTOP
)
==
-
1
)
continue
;
if
(
kill
(
pid
,
SIGSTOP
)
==
-
1
)
continue
;
LOGI
(
"proc_monitor: %s (PID=%d ns=%s)
\n
"
,
processName
,
target_pid
,
buffer
);
LOGI
(
"proc_monitor: %s (PID=%d ns=%s)
\n
"
,
processName
,
pid
,
ns
);
/*
* The setns system call do not support multithread processes
* We have to fork a new process, setns, then do the unmounts
*/
int
hide_pid
=
fork
();
switch
(
hide_pid
)
{
case
-
1
:
PLOGE
(
"fork"
);
return
;
case
0
:
hide_daemon
(
target_pid
);
_exit
(
0
);
default:
break
;
}
if
(
fork_dont_care
()
==
0
)
hide_daemon
(
pid
);
// Wait till the unmount process is done
waitpid
(
hide_pid
,
&
ret
,
0
);
if
(
WEXITSTATUS
(
ret
))
quit_pthread
(
SIGUSR1
);
// All done, send resume signal
kill
(
target_pid
,
SIGCONT
);
target_pid
=
-
1
;
break
;
}
}
pthread_mutex_unlock
(
&
hide_lock
);
}
// For some reason it went here, restart logging
kill
(
log_pid
,
SIGTERM
);
waitpid
(
log_pid
,
NULL
,
0
);
close
(
log_fd
);
}
}
jni/utils/misc.c
View file @
3942858c
...
...
@@ -408,3 +408,14 @@ int switch_mnt_ns(int pid) {
close
(
fd
);
return
ret
;
}
int
fork_dont_care
()
{
int
pid
=
fork
();
if
(
pid
)
{
waitpid
(
pid
,
NULL
,
0
);
return
pid
;
}
else
if
((
pid
=
fork
()))
{
exit
(
0
);
}
return
0
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment