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
86789a86
Commit
86789a86
authored
Apr 04, 2019
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add logging in magiskinit
parent
ca2235ae
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
146 additions
and
90 deletions
+146
-90
init.cpp
native/jni/core/init.cpp
+144
-88
magisk.h
native/jni/include/magisk.h
+0
-1
policydb.cpp
native/jni/magiskpolicy/policydb.cpp
+2
-1
No files found.
native/jni/core/init.cpp
View file @
86789a86
...
...
@@ -32,8 +32,30 @@
#endif
#include "magiskrc.h"
using
namespace
std
;
#define DEFAULT_DT_DIR "/proc/device-tree/firmware/android"
#ifdef MAGISK_DEBUG
static
FILE
*
kmsg
;
static
char
kbuf
[
4096
];
static
int
vprintk
(
const
char
*
fmt
,
va_list
ap
)
{
vsprintf
(
kbuf
,
fmt
,
ap
);
return
fprintf
(
kmsg
,
"magiskinit: %s"
,
kbuf
);
}
static
void
setup_klog
()
{
mknod
(
"/kmsg"
,
S_IFCHR
|
0666
,
makedev
(
1
,
11
));
kmsg
=
xfopen
(
"/kmsg"
,
"ae"
);
setbuf
(
kmsg
,
nullptr
);
unlink
(
"/kmsg"
);
log_cb
.
d
=
log_cb
.
i
=
log_cb
.
w
=
log_cb
.
e
=
vprintk
;
log_cb
.
ex
=
nop_ex
;
}
#else
#define setup_klog(...)
#endif
static
int
test_main
(
int
argc
,
char
*
argv
[]);
constexpr
const
char
*
init_applet
[]
=
...
...
@@ -47,14 +69,6 @@ struct cmdline {
char
dt_dir
[
128
];
};
struct
device
{
dev_t
major
;
dev_t
minor
;
char
devname
[
32
];
char
partname
[
32
];
char
path
[
64
];
};
struct
raw_data
{
void
*
buf
;
size_t
sz
;
...
...
@@ -88,6 +102,7 @@ static void decompress_ramdisk() {
constexpr
char
ramdisk_xz
[]
=
"ramdisk.cpio.xz"
;
if
(
access
(
ramdisk_xz
,
F_OK
))
return
;
LOGD
(
"Decompressing ramdisk from %s
\n
"
,
ramdisk_xz
);
uint8_t
*
buf
;
size_t
sz
;
mmap_ro
(
ramdisk_xz
,
buf
,
sz
);
...
...
@@ -138,7 +153,7 @@ private:
void
preset
();
void
early_mount
();
void
setup_rootfs
();
bool
read_dt_fstab
(
const
char
*
mnt_point
,
char
*
partname
,
char
*
partfs
);
bool
read_dt_fstab
(
const
char
*
name
,
char
*
partname
,
char
*
partfs
);
bool
patch_sepolicy
();
void
cleanup
();
...
...
@@ -211,6 +226,7 @@ static bool check_key_combo() {
ioctl
(
eventfd
,
EVIOCGKEY
(
sizeof
(
bitmask
)),
bitmask
);
count
=
test_bit
(
KEY_VOLUMEUP
,
bitmask
)
?
count
+
1
:
0
;
if
(
count
>=
300
)
{
LOGD
(
"KEY_VOLUMEUP detected: disable system-as-root
\n
"
);
close
(
eventfd
);
return
true
;
}
...
...
@@ -223,9 +239,9 @@ static bool check_key_combo() {
void
MagiskInit
::
load_kernel_info
()
{
// Communicate with kernel using procfs and sysfs
mkdir
(
"/proc"
,
0755
);
x
mkdir
(
"/proc"
,
0755
);
xmount
(
"proc"
,
"/proc"
,
"proc"
,
0
,
nullptr
);
mkdir
(
"/sys"
,
0755
);
x
mkdir
(
"/sys"
,
0755
);
xmount
(
"sysfs"
,
"/sys"
,
"sysfs"
,
0
,
nullptr
);
bool
enter_recovery
=
false
;
...
...
@@ -267,13 +283,17 @@ void MagiskInit::load_kernel_info() {
}
}
if
(
recovery_mode
)
if
(
recovery_mode
)
{
LOGD
(
"Running in recovery mode, waiting for key...
\n
"
);
cmd
.
system_as_root
=
!
check_key_combo
();
}
if
(
cmd
.
dt_dir
[
0
]
==
'\0'
)
strcpy
(
cmd
.
dt_dir
,
DEFAULT_DT_DIR
);
LOGD
(
"system_as_root[%d]
\n
slot[%s]
\n
dt_dir[%s]
\n
"
,
cmd
.
system_as_root
,
cmd
.
slot
,
cmd
.
dt_dir
);
LOGD
(
"system_as_root=[%d]
\n
"
,
cmd
.
system_as_root
);
LOGD
(
"slot=[%s]
\n
"
,
cmd
.
slot
);
LOGD
(
"dt_dir=[%s]
\n
"
,
cmd
.
dt_dir
);
}
void
MagiskInit
::
preset
()
{
...
...
@@ -281,6 +301,7 @@ void MagiskInit::preset() {
if
(
cmd
.
system_as_root
)
{
// Clear rootfs
LOGD
(
"Cleaning rootfs
\n
"
);
frm_rf
(
root
,
{
"overlay"
,
"proc"
,
"sys"
});
}
else
{
decompress_ramdisk
();
...
...
@@ -290,20 +311,29 @@ void MagiskInit::preset() {
rm_rf
(
"/.backup"
);
// Do not go further if device is booting into recovery
if
(
access
(
"/sbin/recovery"
,
F_OK
)
==
0
)
if
(
access
(
"/sbin/recovery"
,
F_OK
)
==
0
)
{
LOGD
(
"Ramdisk is recovery, abort
\n
"
);
re_exec_init
();
}
}
}
static
inline
void
parse_device
(
struct
device
*
dev
,
const
char
*
uevent
)
{
struct
device
{
int
major
;
int
minor
;
char
devname
[
32
];
char
partname
[
32
];
};
static
inline
void
parse_device
(
device
*
dev
,
const
char
*
uevent
)
{
dev
->
partname
[
0
]
=
'\0'
;
FILE
*
fp
=
xfopen
(
uevent
,
"r"
);
FILE
*
fp
=
xfopen
(
uevent
,
"r
e
"
);
char
buf
[
64
];
while
(
fgets
(
buf
,
sizeof
(
buf
),
fp
))
{
if
(
strncmp
(
buf
,
"MAJOR"
,
5
)
==
0
)
{
sscanf
(
buf
,
"MAJOR=%
ld"
,
(
long
*
)
&
dev
->
major
);
sscanf
(
buf
,
"MAJOR=%
d"
,
&
dev
->
major
);
}
else
if
(
strncmp
(
buf
,
"MINOR"
,
5
)
==
0
)
{
sscanf
(
buf
,
"MINOR=%
ld"
,
(
long
*
)
&
dev
->
minor
);
sscanf
(
buf
,
"MINOR=%
d"
,
&
dev
->
minor
);
}
else
if
(
strncmp
(
buf
,
"DEVNAME"
,
7
)
==
0
)
{
sscanf
(
buf
,
"DEVNAME=%s"
,
dev
->
devname
);
}
else
if
(
strncmp
(
buf
,
"PARTNAME"
,
8
)
==
0
)
{
...
...
@@ -311,36 +341,61 @@ static inline void parse_device(struct device *dev, const char *uevent) {
}
}
fclose
(
fp
);
LOGD
(
"%s [%s] (%u, %u)
\n
"
,
dev
->
devname
,
dev
->
partname
,
(
unsigned
)
dev
->
major
,
(
unsigned
)
dev
->
minor
);
}
static
bool
setup_block
(
struct
device
*
dev
,
const
char
*
partname
)
{
static
vector
<
device
>
dev_list
;
static
void
collect_devices
()
{
char
path
[
128
];
struct
dirent
*
entry
;
DIR
*
dir
=
opendir
(
"/sys/dev/block"
);
device
dev
;
DIR
*
dir
=
xopendir
(
"/sys/dev/block"
);
if
(
dir
==
nullptr
)
return
false
;
bool
found
=
false
;
return
;
while
((
entry
=
readdir
(
dir
)))
{
if
(
strcmp
(
entry
->
d_name
,
"."
)
==
0
||
strcmp
(
entry
->
d_name
,
".."
)
==
0
)
if
(
entry
->
d_name
==
"."
sv
||
entry
->
d_name
==
".."
sv
)
continue
;
sprintf
(
path
,
"/sys/dev/block/%s/uevent"
,
entry
->
d_name
);
parse_device
(
dev
,
path
);
if
(
strcasecmp
(
dev
->
partname
,
partname
)
==
0
)
{
sprintf
(
dev
->
path
,
"/dev/block/%s"
,
dev
->
devname
);
found
=
true
;
break
;
}
parse_device
(
&
dev
,
path
);
dev_list
.
push_back
(
dev
);
}
closedir
(
dir
);
}
if
(
!
found
)
return
false
;
static
bool
setup_block
(
const
char
*
partname
,
char
*
block_dev
)
{
if
(
dev_list
.
empty
())
collect_devices
();
for
(
auto
&
dev
:
dev_list
)
{
if
(
strcasecmp
(
dev
.
partname
,
partname
)
==
0
)
{
sprintf
(
block_dev
,
"/dev/block/%s"
,
dev
.
devname
);
LOGD
(
"Found %s: [%s] (%d, %d)
\n
"
,
dev
.
partname
,
dev
.
devname
,
dev
.
major
,
dev
.
minor
);
xmkdir
(
"/dev"
,
0755
);
xmkdir
(
"/dev/block"
,
0755
);
mknod
(
block_dev
,
S_IFBLK
|
0600
,
makedev
(
dev
.
major
,
dev
.
minor
));
return
true
;
}
}
return
false
;
}
mkdir
(
"/dev"
,
0755
);
mkdir
(
"/dev/block"
,
0755
);
mknod
(
dev
->
path
,
S_IFBLK
|
0600
,
makedev
(
dev
->
major
,
dev
->
minor
));
return
true
;
bool
MagiskInit
::
read_dt_fstab
(
const
char
*
name
,
char
*
partname
,
char
*
partfs
)
{
char
path
[
128
];
int
fd
;
sprintf
(
path
,
"%s/fstab/%s/dev"
,
cmd
.
dt_dir
,
name
);
if
((
fd
=
xopen
(
path
,
O_RDONLY
|
O_CLOEXEC
))
>=
0
)
{
read
(
fd
,
path
,
sizeof
(
path
));
close
(
fd
);
// Some custom treble use different names, so use what we read
name
=
rtrim
(
strrchr
(
path
,
'/'
)
+
1
);
sprintf
(
partname
,
"%s%s"
,
name
,
strend
(
name
,
cmd
.
slot
)
?
cmd
.
slot
:
""
);
sprintf
(
path
,
"%s/fstab/%s/type"
,
cmd
.
dt_dir
,
name
);
if
((
fd
=
xopen
(
path
,
O_RDONLY
|
O_CLOEXEC
))
>=
0
)
{
read
(
fd
,
partfs
,
32
);
close
(
fd
);
return
true
;
}
}
return
false
;
}
static
inline
bool
is_lnk
(
const
char
*
name
)
{
...
...
@@ -350,28 +405,30 @@ static inline bool is_lnk(const char *name) {
return
S_ISLNK
(
st
.
st_mode
);
}
#define link_root(part) \
if (is_lnk("/system_root" part)) \
cp_afc("/system_root" part, part)
#define mount_root(part) \
if (!is_lnk("/" #part) && read_dt_fstab(#part, partname, fstype)) { \
setup_block(&dev, partname); \
xmkdir("/" #part, 0755); \
xmount(dev.path, "/" #part, fstype, MS_RDONLY, nullptr); \
mnt_##part = true; \
#define link_root(name) \
if (is_lnk("/system_root" name)) \
cp_afc("/system_root" name, name)
#define mount_root(name) \
if (!is_lnk("/" #name) && read_dt_fstab(#name, partname, fstype)) { \
LOGD("Early mount " #name "\n"); \
setup_block(partname, block_dev); \
xmkdir("/" #name, 0755); \
xmount(block_dev, "/" #name, fstype, MS_RDONLY, nullptr); \
mnt_##name = true; \
}
void
MagiskInit
::
early_mount
()
{
struct
device
dev
;
char
partname
[
32
];
char
fstype
[
32
];
char
block_dev
[
64
];
if
(
cmd
.
system_as_root
)
{
LOGD
(
"Early mount system_root
\n
"
);
sprintf
(
partname
,
"system%s"
,
cmd
.
slot
);
setup_block
(
&
dev
,
partname
);
setup_block
(
partname
,
block_dev
);
xmkdir
(
"/system_root"
,
0755
);
xmount
(
dev
.
path
,
"/system_root"
,
"ext4"
,
MS_RDONLY
,
nullptr
);
xmount
(
block_dev
,
"/system_root"
,
"ext4"
,
MS_RDONLY
,
nullptr
);
xmkdir
(
"/system"
,
0755
);
xmount
(
"/system_root/system"
,
"/system"
,
nullptr
,
MS_BIND
,
nullptr
);
...
...
@@ -401,7 +458,8 @@ void MagiskInit::setup_rootfs() {
if
(
cmd
.
system_as_root
)
{
// Clone rootfs
int
system_root
=
open
(
"/system_root"
,
O_RDONLY
|
O_CLOEXEC
);
LOGD
(
"Clone root dir from system to rootfs
\n
"
);
int
system_root
=
xopen
(
"/system_root"
,
O_RDONLY
|
O_CLOEXEC
);
clone_dir
(
system_root
,
root
,
false
);
close
(
system_root
);
}
...
...
@@ -418,10 +476,12 @@ void MagiskInit::setup_rootfs() {
for
(
char
*
p
=
addr
;
p
<
addr
+
size
;
++
p
)
{
if
(
memcmp
(
p
,
SPLIT_PLAT_CIL
,
sizeof
(
SPLIT_PLAT_CIL
))
==
0
)
{
// Force init to load /sepolicy
LOGD
(
"Remove from init: "
SPLIT_PLAT_CIL
"
\n
"
);
memset
(
p
,
'x'
,
sizeof
(
SPLIT_PLAT_CIL
)
-
1
);
p
+=
sizeof
(
SPLIT_PLAT_CIL
)
-
1
;
}
else
if
(
memcmp
(
p
,
SYSTEM_INIT
,
sizeof
(
SYSTEM_INIT
))
==
0
)
{
// Force execute /init instead of /system/bin/init
LOGD
(
"Patch init: [/system/bin/init] -> [/init]
\n
"
);
strcpy
(
p
,
"/init"
);
p
+=
sizeof
(
SYSTEM_INIT
)
-
1
;
}
...
...
@@ -432,6 +492,7 @@ void MagiskInit::setup_rootfs() {
// Handle ramdisk overlays
int
fd
=
open
(
"/overlay"
,
O_RDONLY
|
O_CLOEXEC
);
if
(
fd
>=
0
)
{
LOGD
(
"Merge overlay folder
\n
"
);
mv_dir
(
fd
,
root
);
close
(
fd
);
rmdir
(
"/overlay"
);
...
...
@@ -441,10 +502,13 @@ void MagiskInit::setup_rootfs() {
FILE
*
rc
=
xfopen
(
"/init.p.rc"
,
"we"
);
file_readline
(
"/init.rc"
,
[
&
](
auto
line
)
->
bool
{
// Do not start vaultkeeper
if
(
str_contains
(
line
,
"start vaultkeeper"
))
if
(
str_contains
(
line
,
"start vaultkeeper"
))
{
LOGD
(
"Remove vaultkeeper
\n
"
);
return
true
;
}
// Do not run flash_recovery
if
(
str_starts
(
line
,
"service flash_recovery"
))
{
LOGD
(
"Remove flash_recovery
\n
"
);
fprintf
(
rc
,
"service flash_recovery /system/bin/xxxxx
\n
"
);
return
true
;
}
...
...
@@ -476,12 +540,16 @@ void MagiskInit::setup_rootfs() {
bool
MagiskInit
::
patch_sepolicy
()
{
bool
patch_init
=
false
;
if
(
access
(
SPLIT_PLAT_CIL
,
R_OK
)
==
0
)
patch_init
=
true
;
/* Split sepolicy */
else
if
(
access
(
"/sepolicy"
,
R_OK
)
==
0
)
load_policydb
(
"/sepolicy"
);
/* Monolithic sepolicy */
else
return
false
;
/* No SELinux */
if
(
access
(
SPLIT_PLAT_CIL
,
R_OK
)
==
0
)
{
LOGD
(
"sepol: split policy
\n
"
);
patch_init
=
true
;
}
else
if
(
access
(
"/sepolicy"
,
R_OK
)
==
0
)
{
LOGD
(
"sepol: monolithic policy
\n
"
);
load_policydb
(
"/sepolicy"
);
}
else
{
LOGD
(
"sepol: no selinux
\n
"
);
return
false
;
}
// Mount selinuxfs to communicate with kernel
xmount
(
"selinuxfs"
,
SELINUX_MNT
,
"selinuxfs"
,
0
,
nullptr
);
...
...
@@ -494,8 +562,10 @@ bool MagiskInit::patch_sepolicy() {
dump_policydb
(
"/sepolicy"
);
// Load policy to kernel so we can label rootfs
if
(
load_sepol
)
if
(
load_sepol
)
{
LOGD
(
"sepol: preload sepolicy
\n
"
);
dump_policydb
(
SELINUX_LOAD
);
}
// Remove OnePlus stupid debug sepolicy and use our own
if
(
access
(
"/sepolicy_debug"
,
F_OK
)
==
0
)
{
...
...
@@ -509,28 +579,9 @@ bool MagiskInit::patch_sepolicy() {
return
patch_init
;
}
bool
MagiskInit
::
read_dt_fstab
(
const
char
*
mnt_point
,
char
*
partname
,
char
*
partfs
)
{
char
path
[
128
];
int
fd
;
sprintf
(
path
,
"%s/fstab/%s/dev"
,
cmd
.
dt_dir
,
mnt_point
);
if
((
fd
=
xopen
(
path
,
O_RDONLY
|
O_CLOEXEC
))
>=
0
)
{
read
(
fd
,
path
,
sizeof
(
path
));
close
(
fd
);
char
*
name
=
rtrim
(
strrchr
(
path
,
'/'
)
+
1
);
sprintf
(
partname
,
"%s%s"
,
name
,
strend
(
name
,
cmd
.
slot
)
?
cmd
.
slot
:
""
);
sprintf
(
path
,
"%s/fstab/%s/type"
,
cmd
.
dt_dir
,
mnt_point
);
if
((
fd
=
xopen
(
path
,
O_RDONLY
|
O_CLOEXEC
))
>=
0
)
{
read
(
fd
,
partfs
,
32
);
close
(
fd
);
return
true
;
}
}
return
false
;
}
#define umount_root(part) \
if (mnt_##part) \
umount("/" #part);
#define umount_root(name) \
if (mnt_##name) \
umount("/" #name);
void
MagiskInit
::
cleanup
()
{
umount
(
SELINUX_MNT
);
...
...
@@ -553,11 +604,6 @@ static inline void patch_socket_name(const char *path) {
memcpy
(
buf
+
i
,
name
,
sizeof
(
name
));
i
+=
sizeof
(
name
);
}
if
(
memcmp
(
buf
+
i
,
LOG_SOCKET
,
sizeof
(
LOG_SOCKET
))
==
0
)
{
gen_rand_str
(
name
,
sizeof
(
name
));
memcpy
(
buf
+
i
,
name
,
sizeof
(
name
));
i
+=
sizeof
(
name
);
}
}
munmap
(
buf
,
size
);
}
...
...
@@ -577,6 +623,13 @@ void MagiskInit::setup_overlay() {
setcon
(
"u:r:"
SEPOL_PROC_DOMAIN
":s0"
);
unlink
(
EARLYINIT
);
#ifdef MAGISK_DEBUG
kmsg
=
xfopen
(
"/dev/kmsg"
,
"ae"
);
setbuf
(
kmsg
,
nullptr
);
#endif
LOGD
(
"Setting up overlay
\n
"
);
// Mount the /sbin tmpfs overlay
xmount
(
"tmpfs"
,
"/sbin"
,
"tmpfs"
,
0
,
nullptr
);
chmod
(
"/sbin"
,
0755
);
...
...
@@ -591,6 +644,7 @@ void MagiskInit::setup_overlay() {
write
(
fd
,
self
.
buf
,
self
.
sz
);
close
(
fd
);
if
(
access
(
"/system/apex"
,
F_OK
)
==
0
)
{
LOGD
(
"APEX detected, use wrapper
\n
"
);
dump_magisk
(
"/sbin/magisk.bin"
,
0755
);
patch_socket_name
(
"/sbin/magisk.bin"
);
setfilecon
(
"/sbin/magisk.bin"
,
"u:object_r:"
SEPOL_FILE_DOMAIN
":s0"
);
...
...
@@ -619,9 +673,9 @@ void MagiskInit::setup_overlay() {
struct
dirent
*
entry
;
fd
=
xopen
(
"/sbin"
,
O_RDONLY
);
while
((
entry
=
xreaddir
(
dir
)))
{
if
(
strcmp
(
entry
->
d_name
,
"."
)
==
0
||
strcmp
(
entry
->
d_name
,
".."
)
==
0
)
if
(
entry
->
d_name
==
"."
sv
||
entry
->
d_name
==
".."
sv
)
continue
;
s
nprintf
(
path
,
PATH_MAX
,
"/root/%s"
,
entry
->
d_name
);
s
printf
(
path
,
"/root/%s"
,
entry
->
d_name
);
xsymlinkat
(
path
,
fd
,
entry
->
d_name
);
}
closedir
(
dir
);
...
...
@@ -648,6 +702,8 @@ void MagiskInit::start() {
if
(
null
>
STDERR_FILENO
)
close
(
null
);
setup_klog
();
load_kernel_info
();
full_read
(
"/init"
,
&
self
.
buf
,
&
self
.
sz
);
...
...
@@ -673,7 +729,7 @@ void MagiskInit::test() {
cleanup
();
}
static
int
test_main
(
int
argc
,
char
*
argv
[])
{
static
int
test_main
(
int
,
char
*
argv
[])
{
MagiskInit
init
(
argv
);
init
.
test
();
return
0
;
...
...
native/jni/include/magisk.h
View file @
86789a86
...
...
@@ -3,7 +3,6 @@
#include <logging.h>
#define MAIN_SOCKET "d30138f2310a9fb9c54a3e0c21f58591"
#define LOG_SOCKET "5864cd77f2f8c59b3882e2d35dbf51e4"
#define JAVA_PACKAGE_NAME "com.topjohnwu.magisk"
#define LOGFILE "/cache/magisk.log"
#define UNBLOCKFILE "/dev/.magisk_unblock"
...
...
native/jni/magiskpolicy/policydb.cpp
View file @
86789a86
...
...
@@ -48,7 +48,8 @@ static bool cmp_sha256(const char *a, const char *b) {
}
else
{
return
false
;
}
LOGD
(
"%s=[%.*s]
\n
%s=[%.*s]
\n
"
,
a
,
SHALEN
,
id_a
,
b
,
SHALEN
,
id_b
);
LOGD
(
"%s=[%.*s]
\n
"
,
a
,
SHALEN
,
id_a
);
LOGD
(
"%s=[%.*s]
\n
"
,
b
,
SHALEN
,
id_b
);
return
memcmp
(
id_a
,
id_b
,
SHALEN
)
==
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