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
cda57dd4
Commit
cda57dd4
authored
Nov 04, 2018
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fully migrate Magisk to C++
parent
4351de50
Show whitespace changes
Inline
Side-by-side
Showing
27 changed files
with
472 additions
and
531 deletions
+472
-531
Android.mk
native/jni/Android.mk
+12
-12
bootstages.cpp
native/jni/daemon/bootstages.cpp
+252
-269
daemon.cpp
native/jni/daemon/daemon.cpp
+3
-3
db.cpp
native/jni/daemon/db.cpp
+23
-23
log_daemon.cpp
native/jni/daemon/log_daemon.cpp
+31
-25
magisk.cpp
native/jni/daemon/magisk.cpp
+1
-2
socket.cpp
native/jni/daemon/socket.cpp
+5
-3
db.h
native/jni/include/db.h
+15
-20
img.h
native/jni/include/img.h
+8
-0
magisk.h
native/jni/include/magisk.h
+2
-2
resetprop.h
native/jni/include/resetprop.h
+6
-19
hide_utils.cpp
native/jni/magiskhide/hide_utils.cpp
+4
-4
magiskhide.cpp
native/jni/magiskhide/magiskhide.cpp
+3
-3
magiskhide.h
native/jni/magiskhide/magiskhide.h
+0
-2
applets.cpp
native/jni/misc/applets.cpp
+0
-0
img.cpp
native/jni/misc/img.cpp
+1
-1
resetprop.cpp
native/jni/resetprop/resetprop.cpp
+14
-26
connect.cpp
native/jni/su/connect.cpp
+10
-11
pts.cpp
native/jni/su/pts.cpp
+0
-1
su.cpp
native/jni/su/su.cpp
+13
-16
su.h
native/jni/su/su.h
+23
-9
su_daemon.cpp
native/jni/su/su_daemon.cpp
+34
-31
Android.mk
native/jni/utils/Android.mk
+1
-2
array.h
native/jni/utils/include/array.h
+11
-1
selinux.h
native/jni/utils/include/selinux.h
+0
-1
utils.h
native/jni/utils/include/utils.h
+0
-4
legacy.c
native/jni/utils/legacy.c
+0
-41
No files found.
native/jni/Android.mk
View file @
cda57dd4
...
@@ -32,14 +32,14 @@ LOCAL_C_INCLUDES := \
...
@@ -32,14 +32,14 @@ LOCAL_C_INCLUDES := \
$(LIBUTILS)
$(LIBUTILS)
LOCAL_SRC_FILES := \
LOCAL_SRC_FILES := \
misc/applets.c \
misc/applets.c
pp
\
misc/img.c \
misc/img.c
pp
\
daemon/magisk.c \
daemon/magisk.c
pp
\
daemon/daemon.c \
daemon/daemon.c
pp
\
daemon/log_daemon.c \
daemon/log_daemon.c
pp
\
daemon/bootstages.c \
daemon/bootstages.c
pp
\
daemon/socket.c \
daemon/socket.c
pp
\
daemon/db.c \
daemon/db.c
pp
\
magiskhide/magiskhide.cpp \
magiskhide/magiskhide.cpp \
magiskhide/proc_monitor.cpp \
magiskhide/proc_monitor.cpp \
magiskhide/hide_utils.cpp \
magiskhide/hide_utils.cpp \
...
@@ -47,10 +47,10 @@ LOCAL_SRC_FILES := \
...
@@ -47,10 +47,10 @@ LOCAL_SRC_FILES := \
resetprop/resetprop.cpp \
resetprop/resetprop.cpp \
resetprop/system_property_api.cpp \
resetprop/system_property_api.cpp \
resetprop/system_property_set.cpp \
resetprop/system_property_set.cpp \
su/su.c \
su/su.c
pp
\
su/connect.c \
su/connect.c
pp
\
su/pts.c \
su/pts.c
pp
\
su/su_daemon.c
su/su_daemon.c
pp
LOCAL_LDLIBS := -llog
LOCAL_LDLIBS := -llog
include $(BUILD_EXECUTABLE)
include $(BUILD_EXECUTABLE)
...
...
native/jni/daemon/bootstages.c
→
native/jni/daemon/bootstages.c
pp
View file @
cda57dd4
...
@@ -24,13 +24,13 @@
...
@@ -24,13 +24,13 @@
#include "flags.h"
#include "flags.h"
static
char
buf
[
PATH_MAX
],
buf2
[
PATH_MAX
];
static
char
buf
[
PATH_MAX
],
buf2
[
PATH_MAX
];
static
struct
vector
module_list
;
static
Array
<
char
*>
module_list
;
extern
char
**
environ
;
static
int
bind_mount
(
const
char
*
from
,
const
char
*
to
)
;
/***************
***
/***************
*
Node structure
*
*
Magic Mount
*
***************
***
/
***************/
// Precedence: MODULE > SKEL > INTER > DUMMY
// Precedence: MODULE > SKEL > INTER > DUMMY
#define IS_DUMMY 0x01
/* mount from mirror */
#define IS_DUMMY 0x01
/* mount from mirror */
...
@@ -42,157 +42,83 @@ extern char **environ;
...
@@ -42,157 +42,83 @@ extern char **environ;
#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)
struct
node_entry
{
class
node_entry
{
public
:
const
char
*
module
;
/* Only used when status & IS_MODULE */
const
char
*
module
;
/* Only used when status & IS_MODULE */
char
*
name
;
char
*
name
;
uint8_t
type
;
uint8_t
type
;
uint8_t
status
;
uint8_t
status
;
struct
node_entry
*
parent
;
node_entry
*
parent
;
struct
vector
*
children
;
Array
<
node_entry
*>
children
;
node_entry
()
=
default
;
node_entry
(
const
char
*
,
const
char
*
,
uint8_t
type
=
0
,
uint8_t
status
=
0
);
node_entry
(
const
char
*
,
uint8_t
type
=
0
,
uint8_t
status
=
0
);
~
node_entry
();
void
create_module_tree
(
const
char
*
module
);
void
magic_mount
();
private
:
char
*
get_path
();
node_entry
*
insert
(
node_entry
*
);
void
clone_skeleton
();
int
get_path
(
char
*
path
);
};
};
static
void
concat_path
(
struct
node_entry
*
node
)
{
node_entry
::
node_entry
(
const
char
*
module
,
const
char
*
name
,
uint8_t
type
,
uint8_t
status
)
if
(
node
->
parent
)
:
node_entry
(
name
,
type
,
status
)
{
concat_path
(
node
->
parent
);
this
->
module
=
module
;
size_t
len
=
strlen
(
buf
);
buf
[
len
]
=
'/'
;
strcpy
(
buf
+
len
+
1
,
node
->
name
);
}
}
static
char
*
get_full_path
(
struct
node_entry
*
node
)
{
node_entry
::
node_entry
(
const
char
*
name
,
uint8_t
type
,
uint8_t
status
)
buf
[
0
]
=
'\0'
;
:
type
(
type
),
status
(
status
),
parent
(
nullptr
)
{
concat_path
(
node
);
this
->
name
=
strdup
(
name
);
return
strdup
(
buf
);
}
}
// Free the node
node_entry
::~
node_entry
()
{
static
void
destroy_node
(
struct
node_entry
*
node
)
{
free
(
name
);
free
(
node
->
name
);
for
(
auto
&
node
:
children
)
vec_destroy
(
node
->
children
);
delete
node
;
free
(
node
->
children
);
free
(
node
);
}
}
// Free the node and all children recursively
char
*
node_entry
::
get_path
()
{
static
void
destroy_subtree
(
struct
node_entry
*
node
)
{
get_path
(
buf
);
// Never free parent, since it shall be freed by themselves
return
strdup
(
buf
);
struct
node_entry
*
e
;
vec_for_each
(
node
->
children
,
e
)
{
destroy_subtree
(
e
);
}
destroy_node
(
node
);
}
// Return the child
static
struct
node_entry
*
insert_child
(
struct
node_entry
*
p
,
struct
node_entry
*
c
)
{
c
->
parent
=
p
;
if
(
p
->
children
==
NULL
)
{
p
->
children
=
xmalloc
(
sizeof
(
struct
vector
));
vec_init
(
p
->
children
);
}
struct
node_entry
*
e
;
vec_for_each
(
p
->
children
,
e
)
{
if
(
strcmp
(
e
->
name
,
c
->
name
)
==
0
)
{
// Exist duplicate
if
(
c
->
status
>
e
->
status
)
{
// Precedence is higher, replace with new node
destroy_subtree
(
e
);
vec_cur
(
p
->
children
)
=
c
;
return
c
;
}
else
{
// Free the new entry, return old
destroy_node
(
c
);
return
e
;
}
}
}
// New entry, push back
vec_push_back
(
p
->
children
,
c
);
return
c
;
}
/***********
* setenvs *
***********/
static
void
set_path
()
{
char
buffer
[
512
];
sprintf
(
buffer
,
BBPATH
":%s"
,
getenv
(
"PATH"
));
setenv
(
"PATH"
,
buffer
,
1
);
}
}
static
void
set_mirror_path
()
{
int
node_entry
::
get_path
(
char
*
path
)
{
setenv
(
"PATH"
,
BBPATH
":/sbin:"
MIRRDIR
"/system/bin:"
int
len
=
0
;
MIRRDIR
"/system/xbin:"
MIRRDIR
"/vendor/bin"
,
1
);
if
(
parent
)
len
=
parent
->
get_path
(
path
);
len
+=
sprintf
(
path
+
len
,
"/%s"
,
name
);
return
len
;
}
}
/***********
node_entry
*
node_entry
::
insert
(
node_entry
*
node
)
{
* Scripts *
node
->
parent
=
this
;
***********/
for
(
auto
&
child
:
children
)
{
if
(
strcmp
(
child
->
name
,
node
->
name
)
==
0
)
{
static
void
exec_common_script
(
const
char
*
stage
)
{
if
(
node
->
status
>
child
->
status
)
{
DIR
*
dir
;
// The new node has higher precedence
struct
dirent
*
entry
;
delete
child
;
snprintf
(
buf2
,
PATH_MAX
,
"%s/%s.d"
,
COREDIR
,
stage
);
child
=
node
;
return
node
;
if
(
!
(
dir
=
xopendir
(
buf2
)))
}
else
{
return
;
delete
node
;
return
child
;
while
((
entry
=
xreaddir
(
dir
)))
{
if
(
entry
->
d_type
==
DT_REG
)
{
snprintf
(
buf2
,
PATH_MAX
,
"%s/%s.d/%s"
,
COREDIR
,
stage
,
entry
->
d_name
);
if
(
access
(
buf2
,
X_OK
)
==
-
1
)
continue
;
LOGI
(
"%s.d: exec [%s]
\n
"
,
stage
,
entry
->
d_name
);
int
pid
=
exec_command
(
0
,
NULL
,
strcmp
(
stage
,
"post-fs-data"
)
?
set_path
:
set_mirror_path
,
"sh"
,
buf2
,
NULL
);
if
(
pid
!=
-
1
)
waitpid
(
pid
,
NULL
,
0
);
}
}
}
}
closedir
(
dir
);
}
static
void
exec_module_script
(
const
char
*
stage
)
{
char
*
module
;
vec_for_each
(
&
module_list
,
module
)
{
snprintf
(
buf2
,
PATH_MAX
,
"%s/%s/%s.sh"
,
MOUNTPOINT
,
module
,
stage
);
snprintf
(
buf
,
PATH_MAX
,
"%s/%s/disable"
,
MOUNTPOINT
,
module
);
if
(
access
(
buf2
,
F_OK
)
==
-
1
||
access
(
buf
,
F_OK
)
==
0
)
continue
;
LOGI
(
"%s: exec [%s.sh]
\n
"
,
module
,
stage
);
int
pid
=
exec_command
(
0
,
NULL
,
strcmp
(
stage
,
"post-fs-data"
)
?
set_path
:
set_mirror_path
,
"sh"
,
buf2
,
NULL
);
if
(
pid
!=
-
1
)
waitpid
(
pid
,
NULL
,
0
);
}
}
children
.
push_back
(
node
);
}
return
node
;
/***************
* Magic Mount *
***************/
static
int
bind_mount
(
const
char
*
from
,
const
char
*
to
)
{
int
ret
=
xmount
(
from
,
to
,
NULL
,
MS_BIND
,
NULL
);
#ifdef MAGISK_DEBUG
LOGI
(
"bind_mount: %s <- %s
\n
"
,
to
,
from
);
#else
LOGI
(
"bind_mount: %s
\n
"
,
to
);
#endif
return
ret
;
}
}
static
void
construct_tree
(
const
char
*
module
,
struct
node_entry
*
parent
)
{
void
node_entry
::
create_module_tree
(
const
char
*
module
)
{
DIR
*
dir
;
DIR
*
dir
;
struct
dirent
*
entry
;
struct
dirent
*
entry
;
struct
node_entry
*
node
;
char
*
parent_path
=
get_full_path
(
parent
);
char
*
full_path
=
get_path
(
);
snprintf
(
buf
,
PATH_MAX
,
"%s/%s%s"
,
MOUNTPOINT
,
module
,
parent
_path
);
snprintf
(
buf
,
PATH_MAX
,
"%s/%s%s"
,
MOUNTPOINT
,
module
,
full
_path
);
if
(
!
(
dir
=
xopendir
(
buf
)))
if
(
!
(
dir
=
xopendir
(
buf
)))
goto
cleanup
;
goto
cleanup
;
...
@@ -201,31 +127,28 @@ static void construct_tree(const char *module, struct node_entry *parent) {
...
@@ -201,31 +127,28 @@ static void construct_tree(const char *module, struct node_entry *parent) {
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
=
xcalloc
(
sizeof
(
*
node
),
1
);
node_entry
*
node
=
new
node_entry
(
module
,
entry
->
d_name
,
entry
->
d_type
);
node
->
module
=
module
;
snprintf
(
buf
,
PATH_MAX
,
"%s/%s"
,
full_path
,
node
->
name
);
node
->
name
=
strdup
(
entry
->
d_name
);
node
->
type
=
entry
->
d_type
;
snprintf
(
buf
,
PATH_MAX
,
"%s/%s"
,
parent_path
,
node
->
name
);
/*
/*
* Clone the parent in the following condition:
* Clone the parent in the following condition:
* 1. File in module is a symlink
* 1. File in module is a symlink
* 2. Target file do not exist
* 2. Target file do not exist
* 3. Target file is a symlink
, but not /system/vendor
* 3. Target file is a symlink
(exclude /system/vendor)
*/
*/
int
clone
=
0
;
bool
clone
=
false
;
if
(
IS_LNK
(
node
)
||
access
(
buf
,
F_OK
)
==
-
1
)
{
if
(
IS_LNK
(
node
)
||
access
(
buf
,
F_OK
)
==
-
1
)
{
clone
=
1
;
clone
=
true
;
}
else
if
(
parent
->
parent
!=
NULL
||
strcmp
(
node
->
name
,
"vendor"
)
!=
0
)
{
}
else
if
(
parent
!=
nullptr
||
strcmp
(
node
->
name
,
"vendor"
)
!=
0
)
{
struct
stat
s
;
struct
stat
s
;
xstat
(
buf
,
&
s
);
xstat
(
buf
,
&
s
);
if
(
S_ISLNK
(
s
.
st_mode
))
if
(
S_ISLNK
(
s
.
st_mode
))
clone
=
1
;
clone
=
true
;
}
}
if
(
clone
)
{
if
(
clone
)
{
// Mark
the parent folder
as a skeleton
// Mark
self
as a skeleton
parent
->
status
|=
IS_SKEL
;
/* This will not overwrite if parent is module */
status
|=
IS_SKEL
;
/* This will not overwrite if parent is module */
node
->
status
=
IS_MODULE
;
node
->
status
=
IS_MODULE
;
}
else
if
(
IS_DIR
(
node
))
{
}
else
if
(
IS_DIR
(
node
))
{
// Check if marked as replace
// Check if marked as replace
...
@@ -238,29 +161,28 @@ static void construct_tree(const char *module, struct node_entry *parent) {
...
@@ -238,29 +161,28 @@ static void construct_tree(const char *module, struct node_entry *parent) {
node
->
status
=
IS_INTER
;
node
->
status
=
IS_INTER
;
}
}
}
else
if
(
IS_REG
(
node
))
{
}
else
if
(
IS_REG
(
node
))
{
// This is a
leaf, mark as target
// This is a
file, mark as leaf
node
->
status
=
IS_MODULE
;
node
->
status
=
IS_MODULE
;
}
}
node
=
insert
_child
(
parent
,
node
);
node
=
insert
(
node
);
if
(
node
->
status
&
(
IS_SKEL
|
IS_INTER
))
{
if
(
node
->
status
&
(
IS_SKEL
|
IS_INTER
))
{
// Intermediate folder, travel deeper
// Intermediate folder, travel deeper
construct_tree
(
module
,
nod
e
);
node
->
create_module_tree
(
modul
e
);
}
}
}
}
closedir
(
dir
);
closedir
(
dir
);
cleanup
:
cleanup
:
free
(
parent
_path
);
free
(
full
_path
);
}
}
static
void
clone_skeleton
(
struct
node_entry
*
node
)
{
void
node_entry
::
clone_skeleton
(
)
{
DIR
*
dir
;
DIR
*
dir
;
struct
dirent
*
entry
;
struct
dirent
*
entry
;
struct
node_entry
*
dummy
,
*
child
;
struct
node_entry
*
dummy
;
// Clone the structure
// Clone the structure
char
*
full_path
=
get_
full_path
(
node
);
char
*
full_path
=
get_
path
(
);
snprintf
(
buf
,
PATH_MAX
,
"%s%s"
,
MIRRDIR
,
full_path
);
snprintf
(
buf
,
PATH_MAX
,
"%s%s"
,
MIRRDIR
,
full_path
);
if
(
!
(
dir
=
xopendir
(
buf
)))
if
(
!
(
dir
=
xopendir
(
buf
)))
goto
cleanup
;
goto
cleanup
;
...
@@ -268,28 +190,25 @@ static void clone_skeleton(struct node_entry *node) {
...
@@ -268,28 +190,25 @@ static void clone_skeleton(struct node_entry *node) {
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 dummy node
// Create dummy node
dummy
=
xcalloc
(
sizeof
(
*
dummy
),
1
);
dummy
=
new
node_entry
(
entry
->
d_name
,
entry
->
d_type
,
IS_DUMMY
);
dummy
->
name
=
strdup
(
entry
->
d_name
);
insert
(
dummy
);
dummy
->
type
=
entry
->
d_type
;
dummy
->
status
=
IS_DUMMY
;
insert_child
(
node
,
dummy
);
}
}
closedir
(
dir
);
closedir
(
dir
);
if
(
node
->
status
&
IS_SKEL
)
{
if
(
status
&
IS_SKEL
)
{
struct
stat
s
;
struct
stat
s
;
char
*
con
;
char
*
con
;
xstat
(
full_path
,
&
s
);
xstat
(
full_path
,
&
s
);
getfilecon
(
full_path
,
&
con
);
getfilecon
(
full_path
,
&
con
);
LOGI
(
"mnt_tmpfs : %s
\n
"
,
full_path
);
LOGI
(
"mnt_tmpfs : %s
\n
"
,
full_path
);
xmount
(
"tmpfs"
,
full_path
,
"tmpfs"
,
0
,
NULL
);
xmount
(
"tmpfs"
,
full_path
,
"tmpfs"
,
0
,
nullptr
);
chmod
(
full_path
,
s
.
st_mode
&
0777
);
chmod
(
full_path
,
s
.
st_mode
&
0777
);
chown
(
full_path
,
s
.
st_uid
,
s
.
st_gid
);
chown
(
full_path
,
s
.
st_uid
,
s
.
st_gid
);
setfilecon
(
full_path
,
con
);
setfilecon
(
full_path
,
con
);
free
(
con
);
free
(
con
);
}
}
vec_for_each
(
node
->
children
,
child
)
{
for
(
auto
&
child
:
children
)
{
snprintf
(
buf
,
PATH_MAX
,
"%s/%s"
,
full_path
,
child
->
name
);
snprintf
(
buf
,
PATH_MAX
,
"%s/%s"
,
full_path
,
child
->
name
);
// Create the dummy file/directory
// Create the dummy file/directory
...
@@ -299,7 +218,7 @@ static void clone_skeleton(struct node_entry *node) {
...
@@ -299,7 +218,7 @@ static void clone_skeleton(struct node_entry *node) {
close
(
creat
(
buf
,
0644
));
close
(
creat
(
buf
,
0644
));
// Links will be handled later
// Links will be handled later
if
(
child
->
parent
->
parent
==
NULL
&&
strcmp
(
child
->
name
,
"vendor"
)
==
0
)
{
if
(
child
->
parent
->
parent
==
nullptr
&&
strcmp
(
child
->
name
,
"vendor"
)
==
0
)
{
if
(
IS_LNK
(
child
))
{
if
(
IS_LNK
(
child
))
{
cp_afc
(
MIRRDIR
"/system/vendor"
,
"/system/vendor"
);
cp_afc
(
MIRRDIR
"/system/vendor"
,
"/system/vendor"
);
LOGI
(
"creat_link: %s <- %s
\n
"
,
"/system/vendor"
,
MIRRDIR
"/system/vendor"
);
LOGI
(
"creat_link: %s <- %s
\n
"
,
"/system/vendor"
,
MIRRDIR
"/system/vendor"
);
...
@@ -311,7 +230,7 @@ static void clone_skeleton(struct node_entry *node) {
...
@@ -311,7 +230,7 @@ static void clone_skeleton(struct node_entry *node) {
snprintf
(
buf2
,
PATH_MAX
,
"%s/%s%s/%s"
,
MOUNTPOINT
,
child
->
module
,
full_path
,
child
->
name
);
snprintf
(
buf2
,
PATH_MAX
,
"%s/%s%s/%s"
,
MOUNTPOINT
,
child
->
module
,
full_path
,
child
->
name
);
}
else
if
(
child
->
status
&
(
IS_SKEL
|
IS_INTER
))
{
}
else
if
(
child
->
status
&
(
IS_SKEL
|
IS_INTER
))
{
// It's an intermediate folder, recursive clone
// It's an intermediate folder, recursive clone
c
lone_skeleton
(
child
);
c
hild
->
clone_skeleton
(
);
continue
;
continue
;
}
else
if
(
child
->
status
&
IS_DUMMY
)
{
}
else
if
(
child
->
status
&
IS_DUMMY
)
{
// Mount from mirror to dummy file
// Mount from mirror to dummy file
...
@@ -336,28 +255,86 @@ cleanup:
...
@@ -336,28 +255,86 @@ cleanup:
free
(
full_path
);
free
(
full_path
);
}
}
static
void
magic_mount
(
struct
node_entry
*
node
)
{
void
node_entry
::
magic_mount
()
{
char
*
real_path
;
if
(
status
&
IS_MODULE
)
{
struct
node_entry
*
child
;
// Mount module item
char
*
real_path
=
get_path
();
if
(
node
->
status
&
IS_MODULE
)
{
snprintf
(
buf
,
PATH_MAX
,
"%s/%s%s"
,
MOUNTPOINT
,
module
,
real_path
);
// The real deal, mount module item
real_path
=
get_full_path
(
node
);
snprintf
(
buf
,
PATH_MAX
,
"%s/%s%s"
,
MOUNTPOINT
,
node
->
module
,
real_path
);
bind_mount
(
buf
,
real_path
);
bind_mount
(
buf
,
real_path
);
free
(
real_path
);
free
(
real_path
);
}
else
if
(
node
->
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
(
node
);
clone_skeleton
();
}
else
if
(
node
->
status
&
IS_INTER
)
{
}
else
if
(
status
&
IS_INTER
)
{
// It's an intermediate node, travel deeper
// It's an intermediate node, travel deeper
vec_for_each
(
node
->
children
,
child
)
for
(
auto
&
child
:
children
)
magic_mount
(
child
);
child
->
magic_mount
(
);
}
}
// The only thing goes here should be vendor placeholder
// The only thing goes here should be vendor placeholder
// There should be no dummies, so don't need to handle it here
// There should be no dummies, so don't need to handle it here
}
}
/***********
* setenvs *
***********/
static
void
set_path
()
{
char
buffer
[
512
];
sprintf
(
buffer
,
BBPATH
":%s"
,
getenv
(
"PATH"
));
setenv
(
"PATH"
,
buffer
,
1
);
}
static
void
set_mirror_path
()
{
setenv
(
"PATH"
,
BBPATH
":/sbin:"
MIRRDIR
"/system/bin:"
MIRRDIR
"/system/xbin:"
MIRRDIR
"/vendor/bin"
,
1
);
}
/***********
* Scripts *
***********/
static
void
exec_common_script
(
const
char
*
stage
)
{
DIR
*
dir
;
struct
dirent
*
entry
;
snprintf
(
buf2
,
PATH_MAX
,
"%s/%s.d"
,
COREDIR
,
stage
);
if
(
!
(
dir
=
xopendir
(
buf2
)))
return
;
while
((
entry
=
xreaddir
(
dir
)))
{
if
(
entry
->
d_type
==
DT_REG
)
{
snprintf
(
buf2
,
PATH_MAX
,
"%s/%s.d/%s"
,
COREDIR
,
stage
,
entry
->
d_name
);
if
(
access
(
buf2
,
X_OK
)
==
-
1
)
continue
;
LOGI
(
"%s.d: exec [%s]
\n
"
,
stage
,
entry
->
d_name
);
int
pid
=
exec_command
(
0
,
nullptr
,
strcmp
(
stage
,
"post-fs-data"
)
?
set_path
:
set_mirror_path
,
"sh"
,
buf2
,
nullptr
);
if
(
pid
!=
-
1
)
waitpid
(
pid
,
nullptr
,
0
);
}
}
closedir
(
dir
);
}
static
void
exec_module_script
(
const
char
*
stage
)
{
for
(
auto
&
module
:
module_list
)
{
snprintf
(
buf2
,
PATH_MAX
,
"%s/%s/%s.sh"
,
MOUNTPOINT
,
module
,
stage
);
snprintf
(
buf
,
PATH_MAX
,
"%s/%s/disable"
,
MOUNTPOINT
,
module
);
if
(
access
(
buf2
,
F_OK
)
==
-
1
||
access
(
buf
,
F_OK
)
==
0
)
continue
;
LOGI
(
"%s: exec [%s.sh]
\n
"
,
module
,
stage
);
int
pid
=
exec_command
(
0
,
nullptr
,
strcmp
(
stage
,
"post-fs-data"
)
?
set_path
:
set_mirror_path
,
"sh"
,
buf2
,
nullptr
);
if
(
pid
!=
-
1
)
waitpid
(
pid
,
nullptr
,
0
);
}
}
/****************
/****************
* Simple Mount *
* Simple Mount *
****************/
****************/
...
@@ -399,8 +376,18 @@ static void simple_mount(const char *path) {
...
@@ -399,8 +376,18 @@ static void simple_mount(const char *path) {
* Miscellaneous *
* Miscellaneous *
*****************/
*****************/
#define alt_img ((char *[]) \
static
int
bind_mount
(
const
char
*
from
,
const
char
*
to
)
{
{ "/cache/magisk.img", "/data/magisk_merge.img", "/data/adb/magisk_merge.img", NULL })
int
ret
=
xmount
(
from
,
to
,
nullptr
,
MS_BIND
,
nullptr
);
#ifdef MAGISK_DEBUG
LOGI
(
"bind_mount: %s <- %s
\n
"
,
to
,
from
);
#else
LOGI
(
"bind_mount: %s
\n
"
,
to
);
#endif
return
ret
;
}
#define alt_img ((const char *[]) \
{ "/cache/magisk.img", "/data/magisk_merge.img", "/data/adb/magisk_merge.img", nullptr })
static
int
prepare_img
()
{
static
int
prepare_img
()
{
// Merge images
// Merge images
...
@@ -419,7 +406,7 @@ static int prepare_img() {
...
@@ -419,7 +406,7 @@ static int prepare_img() {
LOGI
(
"* Mounting "
MAINIMG
"
\n
"
);
LOGI
(
"* Mounting "
MAINIMG
"
\n
"
);
// Mounting magisk image
// Mounting magisk image
char
*
magiskloop
=
mount_image
(
MAINIMG
,
MOUNTPOINT
);
char
*
magiskloop
=
mount_image
(
MAINIMG
,
MOUNTPOINT
);
if
(
magiskloop
==
NULL
)
if
(
magiskloop
==
nullptr
)
return
1
;
return
1
;
xmkdir
(
COREDIR
,
0755
);
xmkdir
(
COREDIR
,
0755
);
...
@@ -447,7 +434,7 @@ static int prepare_img() {
...
@@ -447,7 +434,7 @@ static int prepare_img() {
snprintf
(
buf
,
PATH_MAX
,
"%s/%s/disable"
,
MOUNTPOINT
,
entry
->
d_name
);
snprintf
(
buf
,
PATH_MAX
,
"%s/%s/disable"
,
MOUNTPOINT
,
entry
->
d_name
);
if
(
access
(
buf
,
F_OK
)
==
0
)
if
(
access
(
buf
,
F_OK
)
==
0
)
continue
;
continue
;
vec_push_back
(
&
module_list
,
strdup
(
entry
->
d_name
));
module_list
.
push_back
(
strdup
(
entry
->
d_name
));
}
}
}
}
closedir
(
dir
);
closedir
(
dir
);
...
@@ -459,19 +446,19 @@ static int prepare_img() {
...
@@ -459,19 +446,19 @@ static int 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
(
1
)
{
sleep
(
5
);
sleep
(
5
);
LOGD
(
"apk_install: attempting to install APK"
);
LOGD
(
"apk_install: attempting to install APK"
);
int
apk_res
=
-
1
,
pid
;
int
apk_res
=
-
1
,
pid
;
pid
=
exec_command
(
1
,
&
apk_res
,
NULL
,
"/system/bin/pm"
,
"install"
,
"-r"
,
apk
,
NULL
);
pid
=
exec_command
(
1
,
&
apk_res
,
nullptr
,
"/system/bin/pm"
,
"install"
,
"-r"
,
apk
,
nullptr
);
if
(
pid
!=
-
1
)
{
if
(
pid
!=
-
1
)
{
int
err
=
0
;
int
err
=
0
;
while
(
fdgets
(
buf
,
PATH_MAX
,
apk_res
)
>
0
)
{
while
(
fdgets
(
buf
,
PATH_MAX
,
apk_res
)
>
0
)
{
LOGD
(
"apk_install: %s"
,
buf
);
LOGD
(
"apk_install: %s"
,
buf
);
err
|=
strstr
(
buf
,
"Error:"
)
!=
NULL
;
err
|=
strstr
(
buf
,
"Error:"
)
!=
nullptr
;
}
}
waitpid
(
pid
,
NULL
,
0
);
waitpid
(
pid
,
nullptr
,
0
);
close
(
apk_res
);
close
(
apk_res
);
// Keep trying until pm is started
// Keep trying until pm is started
if
(
err
)
if
(
err
)
...
@@ -482,38 +469,35 @@ static void install_apk(const char *apk) {
...
@@ -482,38 +469,35 @@ static void install_apk(const char *apk) {
unlink
(
apk
);
unlink
(
apk
);
}
}
static
int
check_data
()
{
static
bool
check_data
()
{
struct
vector
v
;
bool
mnt
=
false
;
vec_init
(
&
v
);
bool
data
=
false
;
file_to_vector
(
"/proc/mounts"
,
&
v
);
Array
<
char
*>
mounts
;
char
*
line
;
file_to_array
(
"/proc/mounts"
,
mounts
);
int
mnt
=
0
;
for
(
auto
&
line
:
mounts
)
{
vec_for_each
(
&
v
,
line
)
{
if
(
strstr
(
line
,
" /data "
)
&&
strstr
(
line
,
"tmpfs"
)
==
nullptr
)
if
(
strstr
(
line
,
" /data "
)
&&
strstr
(
line
,
"tmpfs"
)
==
NULL
)
{
mnt
=
true
;
mnt
=
1
;
free
(
line
);
break
;
}
}
}
vec_deep_destroy
(
&
v
);
mounts
.
clear
();
int
data
=
0
;
if
(
mnt
)
{
if
(
mnt
)
{
char
*
crypto
=
getprop
(
"ro.crypto.state"
);
char
*
crypto
=
getprop
(
"ro.crypto.state"
);
if
(
crypto
!=
NULL
)
{
if
(
crypto
!=
nullptr
)
{
if
(
strcmp
(
crypto
,
"unencrypted"
)
==
0
)
{
if
(
strcmp
(
crypto
,
"unencrypted"
)
==
0
)
{
// Unencrypted, we can directly access data
// Unencrypted, we can directly access data
data
=
1
;
data
=
true
;
}
else
{
}
else
{
// Encrypted, check whether vold is started
// Encrypted, check whether vold is started
char
*
vold
=
getprop
(
"init.svc.vold"
);
char
*
vold
=
getprop
(
"init.svc.vold"
);
if
(
vold
!=
NULL
)
{
if
(
vold
!=
nullptr
)
{
free
(
vold
);
free
(
vold
);
data
=
1
;
data
=
true
;
}
}
}
}
free
(
crypto
);
free
(
crypto
);
}
else
{
}
else
{
// ro.crypto.state is not set, assume it's unencrypted
// ro.crypto.state is not set, assume it's unencrypted
data
=
1
;
data
=
true
;
}
}
}
}
return
data
;
return
data
;
...
@@ -521,18 +505,18 @@ static int check_data() {
...
@@ -521,18 +505,18 @@ static int check_data() {
extern
int
launch_magiskhide
();
extern
int
launch_magiskhide
();
static
void
*
start_magisk_hide
(
void
*
args
)
{
static
void
*
start_magisk_hide
(
void
*
)
{
launch_magiskhide
();
launch_magiskhide
();
return
NULL
;
return
nullptr
;
}
}
static
void
auto_start_magiskhide
()
{
static
void
auto_start_magiskhide
()
{
if
(
!
start_log_daemon
())
if
(
!
start_log_daemon
())
return
;
return
;
char
*
hide_prop
=
getprop
2
(
MAGISKHIDE_PROP
,
1
);
char
*
hide_prop
=
getprop
(
MAGISKHIDE_PROP
,
1
);
if
(
hide_prop
==
NULL
||
strcmp
(
hide_prop
,
"0"
)
!=
0
)
{
if
(
hide_prop
==
nullptr
||
strcmp
(
hide_prop
,
"0"
)
!=
0
)
{
pthread_t
thread
;
pthread_t
thread
;
xpthread_create
(
&
thread
,
NULL
,
start_magisk_hide
,
NULL
);
xpthread_create
(
&
thread
,
nullptr
,
start_magisk_hide
,
nullptr
);
pthread_detach
(
thread
);
pthread_detach
(
thread
);
}
}
free
(
hide_prop
);
free
(
hide_prop
);
...
@@ -565,7 +549,7 @@ void unlock_blocks() {
...
@@ -565,7 +549,7 @@ void unlock_blocks() {
static
void
unblock_boot_process
()
{
static
void
unblock_boot_process
()
{
close
(
xopen
(
UNBLOCKFILE
,
O_RDONLY
|
O_CREAT
,
0
));
close
(
xopen
(
UNBLOCKFILE
,
O_RDONLY
|
O_CREAT
,
0
));
pthread_exit
(
NULL
);
pthread_exit
(
nullptr
);
}
}
static
const
char
wrapper
[]
=
static
const
char
wrapper
[]
=
...
@@ -621,7 +605,7 @@ void startup() {
...
@@ -621,7 +605,7 @@ void startup() {
void
*
magisk
,
*
init
;
void
*
magisk
,
*
init
;
size_t
magisk_size
,
init_size
;
size_t
magisk_size
,
init_size
;
xmount
(
NULL
,
"/"
,
NULL
,
MS_REMOUNT
,
NULL
);
xmount
(
nullptr
,
"/"
,
nullptr
,
MS_REMOUNT
,
nullptr
);
// Remove some traits of Magisk
// Remove some traits of Magisk
unlink
(
MAGISKRC
);
unlink
(
MAGISKRC
);
...
@@ -645,7 +629,7 @@ void startup() {
...
@@ -645,7 +629,7 @@ void startup() {
close
(
sbin
);
close
(
sbin
);
// Mount the /sbin tmpfs overlay
// Mount the /sbin tmpfs overlay
xmount
(
"tmpfs"
,
"/sbin"
,
"tmpfs"
,
0
,
NULL
);
xmount
(
"tmpfs"
,
"/sbin"
,
"tmpfs"
,
0
,
nullptr
);
chmod
(
"/sbin"
,
0755
);
chmod
(
"/sbin"
,
0755
);
setfilecon
(
"/sbin"
,
"u:object_r:rootfs:s0"
);
setfilecon
(
"/sbin"
,
"u:object_r:rootfs:s0"
);
sbin
=
xopen
(
"/sbin"
,
O_RDONLY
|
O_CLOEXEC
);
sbin
=
xopen
(
"/sbin"
,
O_RDONLY
|
O_CLOEXEC
);
...
@@ -665,15 +649,15 @@ void startup() {
...
@@ -665,15 +649,15 @@ void startup() {
fd
=
creat
(
"/sbin/magisk"
,
0755
);
fd
=
creat
(
"/sbin/magisk"
,
0755
);
xwrite
(
fd
,
wrapper
,
sizeof
(
wrapper
)
-
1
);
xwrite
(
fd
,
wrapper
,
sizeof
(
wrapper
)
-
1
);
close
(
fd
);
close
(
fd
);
setfilecon
(
"/sbin/magisk.bin"
,
"u:object_r:"
SEPOL_FILE_DOMAIN
":s0"
);
setfilecon
(
"/sbin/magisk.bin"
,
"u:object_r:"
SEPOL_FILE_DOMAIN
":s0"
);
setfilecon
(
"/sbin/magisk"
,
"u:object_r:"
SEPOL_FILE_DOMAIN
":s0"
);
setfilecon
(
"/sbin/magisk"
,
"u:object_r:"
SEPOL_FILE_DOMAIN
":s0"
);
// Setup magiskinit symlinks
// Setup magiskinit symlinks
fd
=
creat
(
"/sbin/magiskinit"
,
0755
);
fd
=
creat
(
"/sbin/magiskinit"
,
0755
);
xwrite
(
fd
,
init
,
init_size
);
xwrite
(
fd
,
init
,
init_size
);
close
(
fd
);
close
(
fd
);
free
(
init
);
free
(
init
);
setfilecon
(
"/sbin/magiskinit"
,
"u:object_r:"
SEPOL_FILE_DOMAIN
":s0"
);
setfilecon
(
"/sbin/magiskinit"
,
"u:object_r:"
SEPOL_FILE_DOMAIN
":s0"
);
for
(
int
i
=
0
;
init_applet
[
i
];
++
i
)
{
for
(
int
i
=
0
;
init_applet
[
i
];
++
i
)
{
snprintf
(
buf
,
PATH_MAX
,
"/sbin/%s"
,
init_applet
[
i
]);
snprintf
(
buf
,
PATH_MAX
,
"/sbin/%s"
,
init_applet
[
i
]);
xsymlink
(
"/sbin/magiskinit"
,
buf
);
xsymlink
(
"/sbin/magiskinit"
,
buf
);
...
@@ -691,10 +675,10 @@ void startup() {
...
@@ -691,10 +675,10 @@ void startup() {
close
(
root
);
close
(
root
);
// Alternative binaries paths
// Alternative binaries paths
char
*
alt_bin
[]
=
{
"/cache/data_bin"
,
"/data/magisk"
,
c
onst
c
har
*
alt_bin
[]
=
{
"/cache/data_bin"
,
"/data/magisk"
,
"/data/data/com.topjohnwu.magisk/install"
,
"/data/data/com.topjohnwu.magisk/install"
,
"/data/user_de/0/com.topjohnwu.magisk/install"
,
NULL
};
"/data/user_de/0/com.topjohnwu.magisk/install"
,
nullptr
};
c
har
*
bin_path
=
NULL
;
c
onst
char
*
bin_path
=
nullptr
;
for
(
int
i
=
0
;
alt_bin
[
i
];
++
i
)
{
for
(
int
i
=
0
;
alt_bin
[
i
];
++
i
)
{
struct
stat
st
;
struct
stat
st
;
if
(
lstat
(
alt_bin
[
i
],
&
st
)
!=
-
1
&&
!
S_ISLNK
(
st
.
st_mode
))
{
if
(
lstat
(
alt_bin
[
i
],
&
st
)
!=
-
1
&&
!
S_ISLNK
(
st
.
st_mode
))
{
...
@@ -723,19 +707,17 @@ void startup() {
...
@@ -723,19 +707,17 @@ void startup() {
xmkdir
(
BLOCKDIR
,
0755
);
xmkdir
(
BLOCKDIR
,
0755
);
LOGI
(
"* Mounting mirrors"
);
LOGI
(
"* Mounting mirrors"
);
struct
vector
mounts
;
Array
<
char
*>
mounts
;
vec_init
(
&
mounts
);
file_to_array
(
"/proc/mounts"
,
mounts
);
file_to_vector
(
"/proc/mounts"
,
&
mounts
);
char
*
line
;
int
skip_initramfs
=
0
;
int
skip_initramfs
=
0
;
// Check whether skip_initramfs device
// Check whether skip_initramfs device
vec_for_each
(
&
mounts
,
line
)
{
for
(
auto
&
line
:
mounts
)
{
if
(
strstr
(
line
,
" /system_root "
))
{
if
(
strstr
(
line
,
" /system_root "
))
{
bind_mount
(
"/system_root/system"
,
MIRRDIR
"/system"
);
bind_mount
(
"/system_root/system"
,
MIRRDIR
"/system"
);
skip_initramfs
=
1
;
skip_initramfs
=
1
;
}
else
if
(
!
skip_initramfs
&&
strstr
(
line
,
" /system "
))
{
}
else
if
(
!
skip_initramfs
&&
strstr
(
line
,
" /system "
))
{
sscanf
(
line
,
"%s %*s %s"
,
buf
,
buf2
);
sscanf
(
line
,
"%s %*s %s"
,
buf
,
buf2
);
xmount
(
buf
,
MIRRDIR
"/system"
,
buf2
,
MS_RDONLY
,
NULL
);
xmount
(
buf
,
MIRRDIR
"/system"
,
buf2
,
MS_RDONLY
,
nullptr
);
#ifdef MAGISK_DEBUG
#ifdef MAGISK_DEBUG
LOGI
(
"mount: %s <- %s
\n
"
,
MIRRDIR
"/system"
,
buf
);
LOGI
(
"mount: %s <- %s
\n
"
,
MIRRDIR
"/system"
,
buf
);
#else
#else
...
@@ -745,7 +727,7 @@ void startup() {
...
@@ -745,7 +727,7 @@ void startup() {
seperate_vendor
=
1
;
seperate_vendor
=
1
;
sscanf
(
line
,
"%s %*s %s"
,
buf
,
buf2
);
sscanf
(
line
,
"%s %*s %s"
,
buf
,
buf2
);
xmkdir
(
MIRRDIR
"/vendor"
,
0755
);
xmkdir
(
MIRRDIR
"/vendor"
,
0755
);
xmount
(
buf
,
MIRRDIR
"/vendor"
,
buf2
,
MS_RDONLY
,
NULL
);
xmount
(
buf
,
MIRRDIR
"/vendor"
,
buf2
,
MS_RDONLY
,
nullptr
);
#ifdef MAGISK_DEBUG
#ifdef MAGISK_DEBUG
LOGI
(
"mount: %s <- %s
\n
"
,
MIRRDIR
"/vendor"
,
buf
);
LOGI
(
"mount: %s <- %s
\n
"
,
MIRRDIR
"/vendor"
,
buf
);
#else
#else
...
@@ -754,7 +736,7 @@ void startup() {
...
@@ -754,7 +736,7 @@ void startup() {
}
}
free
(
line
);
free
(
line
);
}
}
vec_destroy
(
&
mounts
);
mounts
.
clear
(
);
if
(
!
seperate_vendor
)
{
if
(
!
seperate_vendor
)
{
xsymlink
(
MIRRDIR
"/system/vendor"
,
MIRRDIR
"/vendor"
);
xsymlink
(
MIRRDIR
"/system/vendor"
,
MIRRDIR
"/vendor"
);
#ifdef MAGISK_DEBUG
#ifdef MAGISK_DEBUG
...
@@ -767,12 +749,23 @@ void startup() {
...
@@ -767,12 +749,23 @@ void startup() {
bind_mount
(
DATABIN
,
MIRRDIR
"/bin"
);
bind_mount
(
DATABIN
,
MIRRDIR
"/bin"
);
if
(
access
(
MIRRDIR
"/bin/busybox"
,
X_OK
)
==
0
)
{
if
(
access
(
MIRRDIR
"/bin/busybox"
,
X_OK
)
==
0
)
{
LOGI
(
"* Setting up internal busybox"
);
LOGI
(
"* Setting up internal busybox"
);
exec_command_sync
(
MIRRDIR
"/bin/busybox"
,
"--install"
,
"-s"
,
BBPATH
,
NULL
);
exec_command_sync
(
MIRRDIR
"/bin/busybox"
,
"--install"
,
"-s"
,
BBPATH
,
nullptr
);
xsymlink
(
MIRRDIR
"/bin/busybox"
,
BBPATH
"/busybox"
);
xsymlink
(
MIRRDIR
"/bin/busybox"
,
BBPATH
"/busybox"
);
}
}
// Start post-fs-data mode
// Start post-fs-data mode
execl
(
"/sbin/magisk.bin"
,
"magisk"
,
"--post-fs-data"
,
NULL
);
execl
(
"/sbin/magisk.bin"
,
"magisk"
,
"--post-fs-data"
,
nullptr
);
}
static
void
core_only
()
{
// Systemless hosts
if
(
access
(
HOSTSFILE
,
F_OK
)
==
0
)
{
LOGI
(
"* Enabling systemless hosts file support"
);
bind_mount
(
HOSTSFILE
,
"/system/etc/hosts"
);
}
auto_start_magiskhide
();
unblock_boot_process
();
}
}
void
post_fs_data
(
int
client
)
{
void
post_fs_data
(
int
client
)
{
...
@@ -783,20 +776,20 @@ void post_fs_data(int client) {
...
@@ -783,20 +776,20 @@ void post_fs_data(int client) {
// If post-fs-data mode is started, it means startup succeeded
// If post-fs-data mode is started, it means startup succeeded
setup_done
=
1
;
setup_done
=
1
;
xmount
(
NULL
,
"/"
,
NULL
,
MS_REMOUNT
|
MS_RDONLY
,
NULL
);
xmount
(
nullptr
,
"/"
,
nullptr
,
MS_REMOUNT
|
MS_RDONLY
,
nullptr
);
// Start log_daemon
// Start log_daemon
start_log_daemon
();
start_log_daemon
();
LOGI
(
"** post-fs-data mode running
\n
"
);
LOGI
(
"** post-fs-data mode running
\n
"
);
// Allocate buffer
vec_init
(
&
module_list
);
// Merge, trim, mount magisk.img, which will also travel through the modules
// Merge, trim, mount magisk.img, which will also travel through the modules
// After this, it will create the module list
// After this, it will create the module list
if
(
prepare_img
())
if
(
prepare_img
())
{
goto
core_only
;
// Mounting fails, we can only do core only stuffs
// Mounting fails, we can only do core only stuffs
core_only
();
return
;
}
restorecon
();
restorecon
();
chmod
(
SECURE_DIR
,
0700
);
chmod
(
SECURE_DIR
,
0700
);
...
@@ -806,30 +799,31 @@ void post_fs_data(int client) {
...
@@ -806,30 +799,31 @@ void post_fs_data(int client) {
exec_common_script
(
"post-fs-data"
);
exec_common_script
(
"post-fs-data"
);
// Core only mode
// Core only mode
if
(
access
(
DISABLEFILE
,
F_OK
)
==
0
)
if
(
access
(
DISABLEFILE
,
F_OK
)
==
0
)
{
goto
core_only
;
core_only
();
return
;
}
// Execute module scripts
// Execute module scripts
LOGI
(
"* Running module post-fs-data scripts
\n
"
);
LOGI
(
"* Running module post-fs-data scripts
\n
"
);
exec_module_script
(
"post-fs-data"
);
exec_module_script
(
"post-fs-data"
);
char
*
module
;
struct
node_entry
*
sys_root
,
*
ven_root
=
NULL
,
*
child
;
// Create the system root entry
// Create the system root entry
sys_root
=
xcalloc
(
sizeof
(
*
sys_root
),
1
);
node_entry
*
sys_root
=
new
node_entry
(
"system"
);
sys_root
->
name
=
strdup
(
"system"
);
sys_root
->
status
=
IS_INTER
;
sys_root
->
status
=
IS_INTER
;
int
has_modules
=
0
;
// Vendor root entry
node_entry
*
ven_root
=
nullptr
;
bool
has_modules
=
false
;
LOGI
(
"* Loading modules
\n
"
);
LOGI
(
"* Loading modules
\n
"
);
vec_for_each
(
&
module_list
,
module
)
{
for
(
auto
&
module
:
module_list
)
{
// 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
)
{
LOGI
(
"%s: loading [system.prop]
\n
"
,
module
);
LOGI
(
"%s: loading [system.prop]
\n
"
,
module
);
re
ad_prop_file
(
buf
,
0
);
lo
ad_prop_file
(
buf
,
0
);
}
}
// Check whether enable auto_mount
// Check whether enable auto_mount
snprintf
(
buf
,
PATH_MAX
,
"%s/%s/auto_mount"
,
MOUNTPOINT
,
module
);
snprintf
(
buf
,
PATH_MAX
,
"%s/%s/auto_mount"
,
MOUNTPOINT
,
module
);
...
@@ -841,7 +835,7 @@ void post_fs_data(int client) {
...
@@ -841,7 +835,7 @@ void post_fs_data(int client) {
continue
;
continue
;
// Construct structure
// Construct structure
has_modules
=
1
;
has_modules
=
true
;
LOGI
(
"%s: constructing magic mount structure
\n
"
,
module
);
LOGI
(
"%s: constructing magic mount structure
\n
"
,
module
);
// If /system/vendor exists in module, create a link outside
// If /system/vendor exists in module, create a link outside
snprintf
(
buf
,
PATH_MAX
,
"%s/%s/system/vendor"
,
MOUNTPOINT
,
module
);
snprintf
(
buf
,
PATH_MAX
,
"%s/%s/system/vendor"
,
MOUNTPOINT
,
module
);
...
@@ -850,44 +844,31 @@ void post_fs_data(int client) {
...
@@ -850,44 +844,31 @@ void post_fs_data(int client) {
unlink
(
buf2
);
unlink
(
buf2
);
xsymlink
(
buf
,
buf2
);
xsymlink
(
buf
,
buf2
);
}
}
construct_tree
(
module
,
sys_root
);
sys_root
->
create_module_tree
(
module
);
}
}
if
(
has_modules
)
{
if
(
has_modules
)
{
// Extract the vendor node out of system tree and swap with placeholder
// Extract the vendor node out of system tree and swap with placeholder
vec_for_each
(
sys_root
->
children
,
child
)
{
for
(
auto
&
child
:
sys_root
->
children
)
{
if
(
strcmp
(
child
->
name
,
"vendor"
)
==
0
)
{
if
(
strcmp
(
child
->
name
,
"vendor"
)
==
0
)
{
ven_root
=
child
;
ven_root
=
child
;
child
=
xcalloc
(
sizeof
(
*
child
),
1
);
child
=
new
node_entry
(
"vendor"
,
seperate_vendor
?
DT_LNK
:
DT_DIR
);
child
->
type
=
seperate_vendor
?
DT_LNK
:
DT_DIR
;
child
->
parent
=
ven_root
->
parent
;
child
->
parent
=
ven_root
->
parent
;
child
->
name
=
strdup
(
"vendor"
);
ven_root
->
parent
=
nullptr
;
child
->
status
=
0
;
// Swap!
vec_cur
(
sys_root
->
children
)
=
child
;
ven_root
->
parent
=
NULL
;
break
;
break
;
}
}
}
}
// Magic!!
// Magic!!
magic_mount
(
sys_root
);
sys_root
->
magic_mount
(
);
if
(
ven_root
)
magic_mount
(
ven_root
);
if
(
ven_root
)
ven_root
->
magic_mount
(
);
}
}
// Cleanup memory
// Cleanup memory
destroy_subtree
(
sys_root
);
delete
sys_root
;
if
(
ven_root
)
destroy_subtree
(
ven_root
);
if
(
ven_root
)
delete
ven_root
;
core_only:
// Systemless hosts
if
(
access
(
HOSTSFILE
,
F_OK
)
==
0
)
{
LOGI
(
"* Enabling systemless hosts file support"
);
bind_mount
(
HOSTSFILE
,
"/system/etc/hosts"
);
}
auto_start_magiskhide
();
core_only
();
unblock_boot_process
();
}
}
void
late_start
(
int
client
)
{
void
late_start
(
int
client
)
{
...
@@ -903,7 +884,7 @@ void late_start(int client) {
...
@@ -903,7 +884,7 @@ void late_start(int client) {
if
(
!
setup_done
)
{
if
(
!
setup_done
)
{
// The setup failed for some reason, reboot and try again
// The setup failed for some reason, reboot and try again
exec_command_sync
(
"/system/bin/reboot"
,
NULL
);
exec_command_sync
(
"/system/bin/reboot"
,
nullptr
);
return
;
return
;
}
}
...
@@ -932,9 +913,9 @@ core_only:
...
@@ -932,9 +913,9 @@ core_only:
struct
db_strings
str
;
struct
db_strings
str
;
memset
(
&
str
,
0
,
sizeof
(
str
));
memset
(
&
str
,
0
,
sizeof
(
str
));
get_db_strings
(
db
,
SU_MANAGER
,
&
str
);
get_db_strings
(
db
,
SU_MANAGER
,
&
str
);
if
(
validate_manager
(
str
.
s
[
SU_MANAGER
],
0
,
NULL
))
{
if
(
validate_manager
(
str
.
s
[
SU_MANAGER
],
0
,
nullptr
))
{
// There is no manager installed, install the stub
// There is no manager installed, install the stub
exec_command_sync
(
"/sbin/magiskinit"
,
"-x"
,
"manager"
,
"/data/magisk.apk"
,
NULL
);
exec_command_sync
(
"/sbin/magiskinit"
,
"-x"
,
"manager"
,
"/data/magisk.apk"
,
nullptr
);
install_apk
(
"/data/magisk.apk"
);
install_apk
(
"/data/magisk.apk"
);
}
}
sqlite3_close_v2
(
db
);
sqlite3_close_v2
(
db
);
...
@@ -942,7 +923,9 @@ core_only:
...
@@ -942,7 +923,9 @@ core_only:
}
}
// All boot stage done, cleanup
// All boot stage done, cleanup
vec_deep_destroy
(
&
module_list
);
for
(
auto
&
module
:
module_list
)
free
(
module
);
module_list
.
clear
();
}
}
void
boot_complete
(
int
client
)
{
void
boot_complete
(
int
client
)
{
...
...
native/jni/daemon/daemon.c
→
native/jni/daemon/daemon.c
pp
View file @
cda57dd4
...
@@ -31,7 +31,7 @@ static void get_client_cred(int fd, struct ucred *cred) {
...
@@ -31,7 +31,7 @@ static void get_client_cred(int fd, struct ucred *cred) {
static
void
*
request_handler
(
void
*
args
)
{
static
void
*
request_handler
(
void
*
args
)
{
int
client
=
*
((
int
*
)
args
);
int
client
=
*
((
int
*
)
args
);
free
(
args
)
;
delete
(
int
*
)
args
;
int
req
=
read_int
(
client
);
int
req
=
read_int
(
client
);
struct
ucred
credential
;
struct
ucred
credential
;
...
@@ -88,7 +88,7 @@ static void *request_handler(void *args) {
...
@@ -88,7 +88,7 @@ static void *request_handler(void *args) {
static
void
main_daemon
()
{
static
void
main_daemon
()
{
android_logging
();
android_logging
();
setsid
();
setsid
();
setcon
(
"u:r:"
SEPOL_PROC_DOMAIN
":s0"
);
setcon
(
"u:r:"
SEPOL_PROC_DOMAIN
":s0"
);
int
fd
=
xopen
(
"/dev/null"
,
O_RDWR
|
O_CLOEXEC
);
int
fd
=
xopen
(
"/dev/null"
,
O_RDWR
|
O_CLOEXEC
);
xdup2
(
fd
,
STDOUT_FILENO
);
xdup2
(
fd
,
STDOUT_FILENO
);
xdup2
(
fd
,
STDERR_FILENO
);
xdup2
(
fd
,
STDERR_FILENO
);
...
@@ -123,7 +123,7 @@ static void main_daemon() {
...
@@ -123,7 +123,7 @@ static void main_daemon() {
// Loop forever to listen for requests
// Loop forever to listen for requests
while
(
1
)
{
while
(
1
)
{
int
*
client
=
xmalloc
(
sizeof
(
int
))
;
int
*
client
=
new
int
;
*
client
=
xaccept4
(
fd
,
NULL
,
NULL
,
SOCK_CLOEXEC
);
*
client
=
xaccept4
(
fd
,
NULL
,
NULL
,
SOCK_CLOEXEC
);
pthread_t
thread
;
pthread_t
thread
;
xpthread_create
(
&
thread
,
NULL
,
request_handler
,
client
);
xpthread_create
(
&
thread
,
NULL
,
request_handler
,
client
);
...
...
native/jni/daemon/db.c
→
native/jni/daemon/db.c
pp
View file @
cda57dd4
...
@@ -10,8 +10,8 @@
...
@@ -10,8 +10,8 @@
#define DB_VERSION 7
#define DB_VERSION 7
static
int
ver_cb
(
void
*
v
,
int
col_num
,
char
**
data
,
char
**
col_name
)
{
static
int
ver_cb
(
void
*
v
er
,
int
,
char
**
data
,
char
**
)
{
*
((
int
*
)
v
)
=
atoi
(
data
[
0
]);
*
((
int
*
)
v
er
)
=
atoi
(
data
[
0
]);
return
0
;
return
0
;
}
}
...
@@ -19,7 +19,7 @@ static int ver_cb(void *v, int col_num, char **data, char **col_name) {
...
@@ -19,7 +19,7 @@ static int ver_cb(void *v, int col_num, char **data, char **col_name) {
if (err) { \
if (err) { \
LOGE("sqlite3_exec: %s\n", err); \
LOGE("sqlite3_exec: %s\n", err); \
sqlite3_free(err); \
sqlite3_free(err); \
return
NULL
; \
return
nullptr
; \
}
}
static
sqlite3
*
open_and_init_db
()
{
static
sqlite3
*
open_and_init_db
()
{
...
@@ -27,7 +27,7 @@ static sqlite3 *open_and_init_db() {
...
@@ -27,7 +27,7 @@ static sqlite3 *open_and_init_db() {
int
ret
=
sqlite3_open
(
MAGISKDB
,
&
db
);
int
ret
=
sqlite3_open
(
MAGISKDB
,
&
db
);
if
(
ret
)
{
if
(
ret
)
{
LOGE
(
"sqlite3 open failure: %s
\n
"
,
sqlite3_errstr
(
ret
));
LOGE
(
"sqlite3 open failure: %s
\n
"
,
sqlite3_errstr
(
ret
));
return
NULL
;
return
nullptr
;
}
}
int
ver
,
upgrade
=
0
;
int
ver
,
upgrade
=
0
;
char
*
err
;
char
*
err
;
...
@@ -36,7 +36,7 @@ static sqlite3 *open_and_init_db() {
...
@@ -36,7 +36,7 @@ static sqlite3 *open_and_init_db() {
if
(
ver
>
DB_VERSION
)
{
if
(
ver
>
DB_VERSION
)
{
// Don't support downgrading database
// Don't support downgrading database
sqlite3_close_v2
(
db
);
sqlite3_close_v2
(
db
);
return
NULL
;
return
nullptr
;
}
}
if
(
ver
<
3
)
{
if
(
ver
<
3
)
{
// Policies
// Policies
...
@@ -44,20 +44,20 @@ static sqlite3 *open_and_init_db() {
...
@@ -44,20 +44,20 @@ static sqlite3 *open_and_init_db() {
"CREATE TABLE IF NOT EXISTS policies "
"CREATE TABLE IF NOT EXISTS policies "
"(uid INT, package_name TEXT, policy INT, until INT, "
"(uid INT, package_name TEXT, policy INT, until INT, "
"logging INT, notification INT, PRIMARY KEY(uid))"
,
"logging INT, notification INT, PRIMARY KEY(uid))"
,
NULL
,
NULL
,
&
err
);
nullptr
,
nullptr
,
&
err
);
err_abort
(
err
);
err_abort
(
err
);
// Logs
// Logs
sqlite3_exec
(
db
,
sqlite3_exec
(
db
,
"CREATE TABLE IF NOT EXISTS logs "
"CREATE TABLE IF NOT EXISTS logs "
"(from_uid INT, package_name TEXT, app_name TEXT, from_pid INT, "
"(from_uid INT, package_name TEXT, app_name TEXT, from_pid INT, "
"to_uid INT, action INT, time INT, command TEXT)"
,
"to_uid INT, action INT, time INT, command TEXT)"
,
NULL
,
NULL
,
&
err
);
nullptr
,
nullptr
,
&
err
);
err_abort
(
err
);
err_abort
(
err
);
// Settings
// Settings
sqlite3_exec
(
db
,
sqlite3_exec
(
db
,
"CREATE TABLE IF NOT EXISTS settings "
"CREATE TABLE IF NOT EXISTS settings "
"(key TEXT, value INT, PRIMARY KEY(key))"
,
"(key TEXT, value INT, PRIMARY KEY(key))"
,
NULL
,
NULL
,
&
err
);
nullptr
,
nullptr
,
&
err
);
err_abort
(
err
);
err_abort
(
err
);
ver
=
3
;
ver
=
3
;
upgrade
=
1
;
upgrade
=
1
;
...
@@ -67,13 +67,13 @@ static sqlite3 *open_and_init_db() {
...
@@ -67,13 +67,13 @@ static sqlite3 *open_and_init_db() {
sqlite3_exec
(
db
,
sqlite3_exec
(
db
,
"CREATE TABLE IF NOT EXISTS strings "
"CREATE TABLE IF NOT EXISTS strings "
"(key TEXT, value TEXT, PRIMARY KEY(key))"
,
"(key TEXT, value TEXT, PRIMARY KEY(key))"
,
NULL
,
NULL
,
&
err
);
nullptr
,
nullptr
,
&
err
);
err_abort
(
err
);
err_abort
(
err
);
ver
=
4
;
ver
=
4
;
upgrade
=
1
;
upgrade
=
1
;
}
}
if
(
ver
==
4
)
{
if
(
ver
==
4
)
{
sqlite3_exec
(
db
,
"UPDATE policies SET uid=uid%100000"
,
NULL
,
NULL
,
&
err
);
sqlite3_exec
(
db
,
"UPDATE policies SET uid=uid%100000"
,
nullptr
,
nullptr
,
&
err
);
err_abort
(
err
);
err_abort
(
err
);
/* Skip version 5 */
/* Skip version 5 */
ver
=
6
;
ver
=
6
;
...
@@ -84,7 +84,7 @@ static sqlite3 *open_and_init_db() {
...
@@ -84,7 +84,7 @@ static sqlite3 *open_and_init_db() {
sqlite3_exec
(
db
,
sqlite3_exec
(
db
,
"CREATE TABLE IF NOT EXISTS hidelist "
"CREATE TABLE IF NOT EXISTS hidelist "
"(process TEXT, PRIMARY KEY(process))"
,
"(process TEXT, PRIMARY KEY(process))"
,
NULL
,
NULL
,
&
err
);
nullptr
,
nullptr
,
&
err
);
err_abort
(
err
);
err_abort
(
err
);
ver
=
7
;
ver
=
7
;
upgrade
=
1
;
upgrade
=
1
;
...
@@ -94,7 +94,7 @@ static sqlite3 *open_and_init_db() {
...
@@ -94,7 +94,7 @@ static sqlite3 *open_and_init_db() {
// Set version
// Set version
char
query
[
32
];
char
query
[
32
];
sprintf
(
query
,
"PRAGMA user_version=%d"
,
ver
);
sprintf
(
query
,
"PRAGMA user_version=%d"
,
ver
);
sqlite3_exec
(
db
,
query
,
NULL
,
NULL
,
&
err
);
sqlite3_exec
(
db
,
query
,
nullptr
,
nullptr
,
&
err
);
err_abort
(
err
);
err_abort
(
err
);
}
}
return
db
;
return
db
;
...
@@ -102,7 +102,7 @@ static sqlite3 *open_and_init_db() {
...
@@ -102,7 +102,7 @@ static sqlite3 *open_and_init_db() {
sqlite3
*
get_magiskdb
()
{
sqlite3
*
get_magiskdb
()
{
sqlite3
*
db
=
open_and_init_db
();
sqlite3
*
db
=
open_and_init_db
();
if
(
db
==
NULL
)
{
if
(
db
==
nullptr
)
{
// Open fails, remove and reconstruct
// Open fails, remove and reconstruct
unlink
(
MAGISKDB
);
unlink
(
MAGISKDB
);
db
=
open_and_init_db
();
db
=
open_and_init_db
();
...
@@ -111,7 +111,7 @@ sqlite3 *get_magiskdb() {
...
@@ -111,7 +111,7 @@ sqlite3 *get_magiskdb() {
}
}
static
int
settings_cb
(
void
*
v
,
int
col_num
,
char
**
data
,
char
**
col_name
)
{
static
int
settings_cb
(
void
*
v
,
int
col_num
,
char
**
data
,
char
**
col_name
)
{
struct
db_settings
*
dbs
=
v
;
auto
dbs
=
(
db_settings
*
)
v
;
int
key
=
-
1
,
value
;
int
key
=
-
1
,
value
;
for
(
int
i
=
0
;
i
<
col_num
;
++
i
)
{
for
(
int
i
=
0
;
i
<
col_num
;
++
i
)
{
if
(
strcmp
(
col_name
[
i
],
"key"
)
==
0
)
{
if
(
strcmp
(
col_name
[
i
],
"key"
)
==
0
)
{
...
@@ -131,7 +131,7 @@ static int settings_cb(void *v, int col_num, char **data, char **col_name) {
...
@@ -131,7 +131,7 @@ static int settings_cb(void *v, int col_num, char **data, char **col_name) {
}
}
int
get_db_settings
(
sqlite3
*
db
,
int
key
,
struct
db_settings
*
dbs
)
{
int
get_db_settings
(
sqlite3
*
db
,
int
key
,
struct
db_settings
*
dbs
)
{
if
(
db
==
NULL
)
if
(
db
==
nullptr
)
return
1
;
return
1
;
char
*
err
;
char
*
err
;
if
(
key
>
0
)
{
if
(
key
>
0
)
{
...
@@ -150,7 +150,7 @@ int get_db_settings(sqlite3 *db, int key, struct db_settings *dbs) {
...
@@ -150,7 +150,7 @@ int get_db_settings(sqlite3 *db, int key, struct db_settings *dbs) {
}
}
static
int
strings_cb
(
void
*
v
,
int
col_num
,
char
**
data
,
char
**
col_name
)
{
static
int
strings_cb
(
void
*
v
,
int
col_num
,
char
**
data
,
char
**
col_name
)
{
struct
db_strings
*
dbs
=
v
;
auto
dbs
=
(
db_strings
*
)
v
;
int
key
=
-
1
;
int
key
=
-
1
;
char
*
value
;
char
*
value
;
for
(
int
i
=
0
;
i
<
col_num
;
++
i
)
{
for
(
int
i
=
0
;
i
<
col_num
;
++
i
)
{
...
@@ -171,7 +171,7 @@ static int strings_cb(void *v, int col_num, char **data, char **col_name) {
...
@@ -171,7 +171,7 @@ static int strings_cb(void *v, int col_num, char **data, char **col_name) {
}
}
int
get_db_strings
(
sqlite3
*
db
,
int
key
,
struct
db_strings
*
str
)
{
int
get_db_strings
(
sqlite3
*
db
,
int
key
,
struct
db_strings
*
str
)
{
if
(
db
==
NULL
)
if
(
db
==
nullptr
)
return
1
;
return
1
;
char
*
err
;
char
*
err
;
if
(
key
>
0
)
{
if
(
key
>
0
)
{
...
@@ -190,7 +190,7 @@ int get_db_strings(sqlite3 *db, int key, struct db_strings *str) {
...
@@ -190,7 +190,7 @@ int get_db_strings(sqlite3 *db, int key, struct db_strings *str) {
}
}
static
int
policy_cb
(
void
*
v
,
int
col_num
,
char
**
data
,
char
**
col_name
)
{
static
int
policy_cb
(
void
*
v
,
int
col_num
,
char
**
data
,
char
**
col_name
)
{
struct
su_access
*
su
=
v
;
auto
su
=
(
su_access
*
)
v
;
for
(
int
i
=
0
;
i
<
col_num
;
i
++
)
{
for
(
int
i
=
0
;
i
<
col_num
;
i
++
)
{
if
(
strcmp
(
col_name
[
i
],
"policy"
)
==
0
)
if
(
strcmp
(
col_name
[
i
],
"policy"
)
==
0
)
su
->
policy
=
(
policy_t
)
atoi
(
data
[
i
]);
su
->
policy
=
(
policy_t
)
atoi
(
data
[
i
]);
...
@@ -204,11 +204,11 @@ static int policy_cb(void *v, int col_num, char **data, char **col_name) {
...
@@ -204,11 +204,11 @@ static int policy_cb(void *v, int col_num, char **data, char **col_name) {
}
}
int
get_uid_policy
(
sqlite3
*
db
,
int
uid
,
struct
su_access
*
su
)
{
int
get_uid_policy
(
sqlite3
*
db
,
int
uid
,
struct
su_access
*
su
)
{
if
(
db
==
NULL
)
if
(
db
==
nullptr
)
return
1
;
return
1
;
char
query
[
256
],
*
err
;
char
query
[
256
],
*
err
;
sprintf
(
query
,
"SELECT policy, logging, notification FROM policies "
sprintf
(
query
,
"SELECT policy, logging, notification FROM policies "
"WHERE uid=%d AND (until=0 OR until>%li)"
,
uid
,
time
(
NULL
));
"WHERE uid=%d AND (until=0 OR until>%li)"
,
uid
,
time
(
nullptr
));
sqlite3_exec
(
db
,
query
,
policy_cb
,
su
,
&
err
);
sqlite3_exec
(
db
,
query
,
policy_cb
,
su
,
&
err
);
if
(
err
)
{
if
(
err
)
{
LOGE
(
"sqlite3_exec: %s
\n
"
,
err
);
LOGE
(
"sqlite3_exec: %s
\n
"
,
err
);
...
@@ -219,7 +219,7 @@ int get_uid_policy(sqlite3 *db, int uid, struct su_access *su) {
...
@@ -219,7 +219,7 @@ int get_uid_policy(sqlite3 *db, int uid, struct su_access *su) {
}
}
int
validate_manager
(
char
*
alt_pkg
,
int
userid
,
struct
stat
*
st
)
{
int
validate_manager
(
char
*
alt_pkg
,
int
userid
,
struct
stat
*
st
)
{
if
(
st
==
NULL
)
{
if
(
st
==
nullptr
)
{
struct
stat
stat
;
struct
stat
stat
;
st
=
&
stat
;
st
=
&
stat
;
}
}
...
@@ -229,7 +229,7 @@ int validate_manager(char *alt_pkg, int userid, struct stat *st) {
...
@@ -229,7 +229,7 @@ int validate_manager(char *alt_pkg, int userid, struct stat *st) {
sprintf
(
app_path
,
"%s/%d/%s"
,
base
,
userid
,
alt_pkg
[
0
]
?
alt_pkg
:
"xxx"
);
sprintf
(
app_path
,
"%s/%d/%s"
,
base
,
userid
,
alt_pkg
[
0
]
?
alt_pkg
:
"xxx"
);
if
(
stat
(
app_path
,
st
))
{
if
(
stat
(
app_path
,
st
))
{
// Check the official package name
// Check the official package name
sprintf
(
app_path
,
"%s/%d/"
JAVA_PACKAGE_NAME
,
base
,
userid
);
sprintf
(
app_path
,
"%s/%d/"
JAVA_PACKAGE_NAME
,
base
,
userid
);
if
(
stat
(
app_path
,
st
))
{
if
(
stat
(
app_path
,
st
))
{
LOGE
(
"su: cannot find manager"
);
LOGE
(
"su: cannot find manager"
);
memset
(
st
,
0
,
sizeof
(
*
st
));
memset
(
st
,
0
,
sizeof
(
*
st
));
...
@@ -256,7 +256,7 @@ int exec_sql(const char *sql) {
...
@@ -256,7 +256,7 @@ int exec_sql(const char *sql) {
sqlite3
*
db
=
get_magiskdb
();
sqlite3
*
db
=
get_magiskdb
();
if
(
db
)
{
if
(
db
)
{
char
*
err
;
char
*
err
;
sqlite3_exec
(
db
,
sql
,
print_cb
,
NULL
,
&
err
);
sqlite3_exec
(
db
,
sql
,
print_cb
,
nullptr
,
&
err
);
sqlite3_close_v2
(
db
);
sqlite3_close_v2
(
db
);
if
(
err
)
{
if
(
err
)
{
fprintf
(
stderr
,
"sql_err: %s
\n
"
,
err
);
fprintf
(
stderr
,
"sql_err: %s
\n
"
,
err
);
...
...
native/jni/daemon/log_daemon.c
→
native/jni/daemon/log_daemon.c
pp
View file @
cda57dd4
...
@@ -19,7 +19,7 @@
...
@@ -19,7 +19,7 @@
#include "flags.h"
#include "flags.h"
int
log_daemon_started
=
0
;
int
log_daemon_started
=
0
;
static
struct
vector
log_cmd
,
clear_cmd
;
static
Array
<
const
char
*>
log_cmd
,
clear_cmd
;
static
pthread_mutex_t
lock
=
PTHREAD_MUTEX_INITIALIZER
;
static
pthread_mutex_t
lock
=
PTHREAD_MUTEX_INITIALIZER
;
enum
{
enum
{
...
@@ -33,7 +33,7 @@ struct log_listener {
...
@@ -33,7 +33,7 @@ struct log_listener {
};
};
static
int
am_proc_start_filter
(
const
char
*
log
)
{
static
int
am_proc_start_filter
(
const
char
*
log
)
{
return
strstr
(
log
,
"am_proc_start"
)
!=
NULL
;
return
strstr
(
log
,
"am_proc_start"
)
!=
nullptr
;
}
}
static
int
magisk_log_filter
(
const
char
*
log
)
{
static
int
magisk_log_filter
(
const
char
*
log
)
{
...
@@ -52,17 +52,17 @@ static struct log_listener events[] = {
...
@@ -52,17 +52,17 @@ static struct log_listener events[] = {
};
};
#define EVENT_NUM (sizeof(events) / sizeof(struct log_listener))
#define EVENT_NUM (sizeof(events) / sizeof(struct log_listener))
static
void
sigpipe_handler
(
int
sig
)
{
static
void
sigpipe_handler
(
int
)
{
close
(
events
[
HIDE_EVENT
].
fd
);
close
(
events
[
HIDE_EVENT
].
fd
);
events
[
HIDE_EVENT
].
fd
=
-
1
;
events
[
HIDE_EVENT
].
fd
=
-
1
;
}
}
static
void
*
monitor_thread
(
void
*
args
)
{
static
void
*
monitor_thread
(
void
*
)
{
// Block SIGPIPE to prevent interruption
// Block SIGPIPE to prevent interruption
sigset_t
block_set
;
sigset_t
block_set
;
sigemptyset
(
&
block_set
);
sigemptyset
(
&
block_set
);
sigaddset
(
&
block_set
,
SIGPIPE
);
sigaddset
(
&
block_set
,
SIGPIPE
);
pthread_sigmask
(
SIG_SETMASK
,
&
block_set
,
NULL
);
pthread_sigmask
(
SIG_SETMASK
,
&
block_set
,
nullptr
);
// Give the main daemon some time before we monitor it
// Give the main daemon some time before we monitor it
sleep
(
5
);
sleep
(
5
);
int
fd
;
int
fd
;
...
@@ -77,12 +77,12 @@ static void *monitor_thread(void *args) {
...
@@ -77,12 +77,12 @@ static void *monitor_thread(void *args) {
}
}
}
}
static
void
*
logcat_thread
(
void
*
args
)
{
static
void
*
logcat_thread
(
void
*
)
{
int
log_fd
=
-
1
,
log_pid
;
int
log_fd
=
-
1
,
log_pid
;
char
line
[
4096
];
char
line
[
4096
];
while
(
1
)
{
while
(
1
)
{
// Start logcat
// Start logcat
log_pid
=
exec_array
(
0
,
&
log_fd
,
NULL
,
(
const
char
**
)
vec_entry
(
&
log_cmd
));
log_pid
=
exec_array
(
0
,
&
log_fd
,
nullptr
,
log_cmd
.
data
(
));
FILE
*
logs
=
fdopen
(
log_fd
,
"r"
);
FILE
*
logs
=
fdopen
(
log_fd
,
"r"
);
while
(
fgets
(
line
,
sizeof
(
line
),
logs
))
{
while
(
fgets
(
line
,
sizeof
(
line
),
logs
))
{
if
(
line
[
0
]
==
'-'
)
if
(
line
[
0
]
==
'-'
)
...
@@ -99,12 +99,12 @@ static void *logcat_thread(void *args) {
...
@@ -99,12 +99,12 @@ static void *logcat_thread(void *args) {
fclose
(
logs
);
fclose
(
logs
);
log_fd
=
-
1
;
log_fd
=
-
1
;
kill
(
log_pid
,
SIGTERM
);
kill
(
log_pid
,
SIGTERM
);
waitpid
(
log_pid
,
NULL
,
0
);
waitpid
(
log_pid
,
nullptr
,
0
);
LOGI
(
"magisklogd: logcat output EOF"
);
LOGI
(
"magisklogd: logcat output EOF"
);
// Clear buffer
// Clear buffer
log_pid
=
exec_array
(
0
,
NULL
,
NULL
,
(
const
char
**
)
vec_entry
(
&
clear_cmd
));
log_pid
=
exec_array
(
0
,
nullptr
,
nullptr
,
clear_cmd
.
data
(
));
waitpid
(
log_pid
,
NULL
,
0
);
waitpid
(
log_pid
,
nullptr
,
0
);
}
}
}
}
...
@@ -117,36 +117,42 @@ static void log_daemon() {
...
@@ -117,36 +117,42 @@ static void log_daemon() {
struct
sigaction
act
;
struct
sigaction
act
;
memset
(
&
act
,
0
,
sizeof
(
act
));
memset
(
&
act
,
0
,
sizeof
(
act
));
act
.
sa_handler
=
sigpipe_handler
;
act
.
sa_handler
=
sigpipe_handler
;
sigaction
(
SIGPIPE
,
&
act
,
NULL
);
sigaction
(
SIGPIPE
,
&
act
,
nullptr
);
// Setup log dumps
// Setup log dumps
rename
(
LOGFILE
,
LOGFILE
".bak"
);
rename
(
LOGFILE
,
LOGFILE
".bak"
);
events
[
LOG_EVENT
].
fd
=
xopen
(
LOGFILE
,
O_CREAT
|
O_WRONLY
|
O_TRUNC
|
O_CLOEXEC
|
O_APPEND
,
0644
);
events
[
LOG_EVENT
].
fd
=
xopen
(
LOGFILE
,
O_CREAT
|
O_WRONLY
|
O_TRUNC
|
O_CLOEXEC
|
O_APPEND
,
0644
);
// Construct cmdline
// Construct cmdline
vec_init
(
&
log_cmd
);
log_cmd
.
push_back
(
MIRRDIR
"/system/bin/logcat"
);
vec_push_back
(
&
log_cmd
,
MIRRDIR
"/system/bin/logcat"
);
// Test whether these buffers actually works
// Test whether these buffers actually works
const
char
*
b
[]
=
{
"main"
,
"events"
,
"crash"
};
const
char
*
b
[]
=
{
"main"
,
"events"
,
"crash"
};
for
(
int
i
=
0
;
i
<
3
;
++
i
)
{
for
(
int
i
=
0
;
i
<
3
;
++
i
)
{
if
(
exec_command_sync
(
MIRRDIR
"/system/bin/logcat"
,
"-b"
,
b
[
i
],
"-d"
,
"-f"
,
"/dev/null"
,
NULL
)
==
0
)
if
(
exec_command_sync
(
MIRRDIR
"/system/bin/logcat"
,
"-b"
,
b
[
i
],
"-d"
,
"-f"
,
"/dev/null"
,
nullptr
)
==
0
)
{
vec_push_back_all
(
&
log_cmd
,
"-b"
,
b
[
i
],
NULL
);
log_cmd
.
push_back
(
"-b"
);
log_cmd
.
push_back
(
b
[
i
]);
}
}
}
chmod
(
"/dev/null"
,
0666
);
chmod
(
"/dev/null"
,
0666
);
vec_dup
(
&
log_cmd
,
&
clear_cmd
);
clear_cmd
=
log_cmd
;
vec_push_back_all
(
&
log_cmd
,
"-v"
,
"threadtime"
,
"-s"
,
"am_proc_start"
,
"Magisk"
,
NULL
);
log_cmd
.
push_back
(
"-v"
);
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
vec_push_back
(
&
log_cmd
,
"*:F"
);
log_cmd
.
push_back
(
"*:F"
);
#endif
#endif
vec_push_back
(
&
log_cmd
,
NULL
);
log_cmd
.
push_back
(
nullptr
);
vec_push_back
(
&
clear_cmd
,
"-c"
);
vec_push_back
(
&
clear_cmd
,
NULL
);
clear_cmd
.
push_back
(
"-c"
);
clear_cmd
.
push_back
(
nullptr
);
// Start worker threads
// Start worker threads
pthread_t
thread
;
pthread_t
thread
;
pthread_create
(
&
thread
,
NULL
,
monitor_thread
,
NULL
);
pthread_create
(
&
thread
,
nullptr
,
monitor_thread
,
nullptr
);
pthread_detach
(
thread
);
pthread_detach
(
thread
);
xpthread_create
(
&
thread
,
NULL
,
logcat_thread
,
NULL
);
xpthread_create
(
&
thread
,
nullptr
,
logcat_thread
,
nullptr
);
pthread_detach
(
thread
);
pthread_detach
(
thread
);
// Handle socket requests
// Handle socket requests
...
@@ -157,7 +163,7 @@ static void log_daemon() {
...
@@ -157,7 +163,7 @@ static void log_daemon() {
exit
(
1
);
exit
(
1
);
xlisten
(
sockfd
,
10
);
xlisten
(
sockfd
,
10
);
while
(
1
)
{
while
(
1
)
{
int
fd
=
xaccept4
(
sockfd
,
NULL
,
NULL
,
SOCK_CLOEXEC
);
int
fd
=
xaccept4
(
sockfd
,
nullptr
,
nullptr
,
SOCK_CLOEXEC
);
switch
(
read_int
(
fd
))
{
switch
(
read_int
(
fd
))
{
case
HIDE_CONNECT
:
case
HIDE_CONNECT
:
pthread_mutex_lock
(
&
lock
);
pthread_mutex_lock
(
&
lock
);
...
@@ -175,7 +181,7 @@ static void log_daemon() {
...
@@ -175,7 +181,7 @@ static void log_daemon() {
int
start_log_daemon
()
{
int
start_log_daemon
()
{
if
(
!
log_daemon_started
)
{
if
(
!
log_daemon_started
)
{
if
(
exec_command_sync
(
MIRRDIR
"/system/bin/logcat"
,
"-d"
,
"-f"
,
"/dev/null"
,
NULL
)
==
0
)
{
if
(
exec_command_sync
(
MIRRDIR
"/system/bin/logcat"
,
"-d"
,
"-f"
,
"/dev/null"
,
nullptr
)
==
0
)
{
if
(
fork_dont_care
()
==
0
)
if
(
fork_dont_care
()
==
0
)
log_daemon
();
log_daemon
();
log_daemon_started
=
1
;
log_daemon_started
=
1
;
...
...
native/jni/daemon/magisk.c
→
native/jni/daemon/magisk.c
pp
View file @
cda57dd4
...
@@ -26,7 +26,7 @@ static int create_links(const char *bin, const char *path) {
...
@@ -26,7 +26,7 @@ static int create_links(const char *bin, const char *path) {
return
ret
;
return
ret
;
}
}
static
void
usage
()
{
[[
noreturn
]]
static
void
usage
()
{
fprintf
(
stderr
,
fprintf
(
stderr
,
"Magisk v"
xstr
(
MAGISK_VERSION
)
"("
xstr
(
MAGISK_VER_CODE
)
") (by topjohnwu) multi-call binary
\n
"
"Magisk v"
xstr
(
MAGISK_VERSION
)
"("
xstr
(
MAGISK_VER_CODE
)
") (by topjohnwu) multi-call binary
\n
"
"
\n
"
"
\n
"
...
@@ -117,5 +117,4 @@ int magisk_main(int argc, char *argv[]) {
...
@@ -117,5 +117,4 @@ int magisk_main(int argc, char *argv[]) {
}
}
usage
();
usage
();
return
1
;
}
}
native/jni/daemon/socket.c
→
native/jni/daemon/socket.c
pp
View file @
cda57dd4
...
@@ -50,6 +50,7 @@ int socket_accept(int sockfd, int timeout) {
...
@@ -50,6 +50,7 @@ int socket_accept(int sockfd, int timeout) {
int
recv_fd
(
int
sockfd
)
{
int
recv_fd
(
int
sockfd
)
{
// Need to receive data from the message, otherwise don't care about it.
// Need to receive data from the message, otherwise don't care about it.
char
iovbuf
;
char
iovbuf
;
struct
cmsghdr
*
cmsg
;
struct
iovec
iov
=
{
struct
iovec
iov
=
{
.
iov_base
=
&
iovbuf
,
.
iov_base
=
&
iovbuf
,
...
@@ -79,7 +80,7 @@ int recv_fd(int sockfd) {
...
@@ -79,7 +80,7 @@ int recv_fd(int sockfd) {
goto
error
;
goto
error
;
}
}
struct
cmsghdr
*
cmsg
=
CMSG_FIRSTHDR
(
&
msg
);
cmsg
=
CMSG_FIRSTHDR
(
&
msg
);
if
(
cmsg
==
NULL
||
if
(
cmsg
==
NULL
||
cmsg
->
cmsg_len
!=
CMSG_LEN
(
sizeof
(
int
))
||
cmsg
->
cmsg_len
!=
CMSG_LEN
(
sizeof
(
int
))
||
...
@@ -104,8 +105,9 @@ error:
...
@@ -104,8 +105,9 @@ error:
*/
*/
void
send_fd
(
int
sockfd
,
int
fd
)
{
void
send_fd
(
int
sockfd
,
int
fd
)
{
// Need to send some data in the message, this will do.
// Need to send some data in the message, this will do.
char
junk
[]
=
{
'\0'
};
struct
iovec
iov
=
{
struct
iovec
iov
=
{
.
iov_base
=
""
,
.
iov_base
=
junk
,
.
iov_len
=
1
,
.
iov_len
=
1
,
};
};
...
@@ -166,7 +168,7 @@ void write_int_be(int fd, int val) {
...
@@ -166,7 +168,7 @@ void write_int_be(int fd, int val) {
}
}
static
char
*
rd_str
(
int
fd
,
int
len
)
{
static
char
*
rd_str
(
int
fd
,
int
len
)
{
char
*
val
=
xmalloc
(
sizeof
(
char
)
*
(
len
+
1
));
char
*
val
=
(
char
*
)
xmalloc
(
sizeof
(
char
)
*
(
len
+
1
));
xxread
(
fd
,
val
,
len
);
xxread
(
fd
,
val
,
len
);
val
[
len
]
=
'\0'
;
val
[
len
]
=
'\0'
;
return
val
;
return
val
;
...
...
native/jni/include/db.h
View file @
cda57dd4
...
@@ -4,10 +4,6 @@
...
@@ -4,10 +4,6 @@
#include <sqlite3.h>
#include <sqlite3.h>
#include <sys/stat.h>
#include <sys/stat.h>
#ifdef __cplusplus
extern
"C"
{
#endif
/***************
/***************
* DB Settings *
* DB Settings *
***************/
***************/
...
@@ -19,7 +15,7 @@ extern "C" {
...
@@ -19,7 +15,7 @@ extern "C" {
"mnt_ns" \
"mnt_ns" \
})
})
#define DB_SETTINGS_NUM
(sizeof(DB_SETTING_KEYS) / sizeof(char*))
#define DB_SETTINGS_NUM
3
// Settings indices
// Settings indices
enum
{
enum
{
...
@@ -52,15 +48,14 @@ enum {
...
@@ -52,15 +48,14 @@ enum {
struct
db_settings
{
struct
db_settings
{
int
v
[
DB_SETTINGS_NUM
];
int
v
[
DB_SETTINGS_NUM
];
db_settings
()
:
v
{
ROOT_ACCESS_APPS_AND_ADB
,
MULTIUSER_MODE_OWNER_ONLY
,
NAMESPACE_MODE_REQUESTER
}
{}
};
};
#define DEFAULT_DB_SETTINGS \
(struct db_settings) { .v = { \
ROOT_ACCESS_APPS_AND_ADB, \
MULTIUSER_MODE_OWNER_ONLY, \
NAMESPACE_MODE_REQUESTER, \
}}
/**************
/**************
* DB Strings *
* DB Strings *
**************/
**************/
...
@@ -70,7 +65,7 @@ NAMESPACE_MODE_REQUESTER, \
...
@@ -70,7 +65,7 @@ NAMESPACE_MODE_REQUESTER, \
"requester", \
"requester", \
})
})
#define DB_STRING_NUM
(sizeof(DB_STRING_KEYS) / sizeof(char*))
#define DB_STRING_NUM
1
// Strings indices
// Strings indices
enum
{
enum
{
...
@@ -79,6 +74,10 @@ enum {
...
@@ -79,6 +74,10 @@ enum {
struct
db_strings
{
struct
db_strings
{
char
s
[
DB_STRING_NUM
][
128
];
char
s
[
DB_STRING_NUM
][
128
];
db_strings
()
{
for
(
int
i
=
0
;
i
<
DB_STRING_NUM
;
++
i
)
s
[
i
][
0
]
=
'\0'
;
}
};
};
/*************
/*************
...
@@ -97,19 +96,19 @@ struct su_access {
...
@@ -97,19 +96,19 @@ struct su_access {
int
notify
;
int
notify
;
};
};
#define DEFAULT_SU_ACCESS (s
truct s
u_access) { \
#define DEFAULT_SU_ACCESS (su_access) { \
.policy = QUERY, \
.policy = QUERY, \
.log = 1, \
.log = 1, \
.notify = 1 \
.notify = 1 \
}
}
#define SILENT_SU_ACCESS (s
truct s
u_access) { \
#define SILENT_SU_ACCESS (su_access) { \
.policy = ALLOW, \
.policy = ALLOW, \
.log = 0, \
.log = 0, \
.notify = 0 \
.notify = 0 \
}
}
#define NO_SU_ACCESS (s
truct s
u_access) { \
#define NO_SU_ACCESS (su_access) { \
.policy = DENY, \
.policy = DENY, \
.log = 0, \
.log = 0, \
.notify = 0 \
.notify = 0 \
...
@@ -126,8 +125,4 @@ int get_uid_policy(sqlite3 *db, int uid, struct su_access *su);
...
@@ -126,8 +125,4 @@ int get_uid_policy(sqlite3 *db, int uid, struct su_access *su);
int
validate_manager
(
char
*
alt_pkg
,
int
userid
,
struct
stat
*
st
);
int
validate_manager
(
char
*
alt_pkg
,
int
userid
,
struct
stat
*
st
);
int
exec_sql
(
const
char
*
sql
);
int
exec_sql
(
const
char
*
sql
);
#ifdef __cplusplus
}
#endif
#endif //DB_H
#endif //DB_H
native/jni/include/img.h
View file @
cda57dd4
#ifndef IMG_H
#ifndef IMG_H
#define IMG_H
#define IMG_H
#ifdef __cplusplus
extern
"C"
{
#endif
int
create_img
(
const
char
*
img
,
int
size
);
int
create_img
(
const
char
*
img
,
int
size
);
int
resize_img
(
const
char
*
img
,
int
size
);
int
resize_img
(
const
char
*
img
,
int
size
);
char
*
mount_image
(
const
char
*
img
,
const
char
*
target
);
char
*
mount_image
(
const
char
*
img
,
const
char
*
target
);
...
@@ -8,4 +12,8 @@ int umount_image(const char *target, const char *device);
...
@@ -8,4 +12,8 @@ int umount_image(const char *target, const char *device);
int
merge_img
(
const
char
*
source
,
const
char
*
target
);
int
merge_img
(
const
char
*
source
,
const
char
*
target
);
int
trim_img
(
const
char
*
img
,
const
char
*
mount
,
char
*
loop
);
int
trim_img
(
const
char
*
img
,
const
char
*
mount
,
char
*
loop
);
#ifdef __cplusplus
}
#endif
#endif //IMG_H
#endif //IMG_H
native/jni/include/magisk.h
View file @
cda57dd4
...
@@ -45,8 +45,8 @@ extern "C" {
...
@@ -45,8 +45,8 @@ extern "C" {
extern
char
*
argv0
;
/* For changing process name */
extern
char
*
argv0
;
/* For changing process name */
#define applet_names
((
char *[]) { "magisk", "su", "resetprop", "magiskhide", "imgtool", NULL })
#define applet_names
((const
char *[]) { "magisk", "su", "resetprop", "magiskhide", "imgtool", NULL })
#define init_applet
((
char *[]) { "magiskpolicy", "supolicy", NULL })
#define init_applet
((const
char *[]) { "magiskpolicy", "supolicy", NULL })
extern
int
(
*
applet_main
[])
(
int
,
char
*
[]),
(
*
init_applet_main
[])
(
int
,
char
*
[]);
extern
int
(
*
applet_main
[])
(
int
,
char
*
[]),
(
*
init_applet_main
[])
(
int
,
char
*
[]);
...
...
native/jni/include/resetprop.h
View file @
cda57dd4
/* resetprop.h - API for resetprop
/* resetprop.h - API for resetprop
*/
*/
#ifndef _RESETPROP_H_
#pragma once
#define _RESETPROP_H_
#ifdef __cplusplus
extern
"C"
{
#endif
int
prop_exist
(
const
char
*
name
);
int
prop_exist
(
const
char
*
name
);
int
setprop
(
const
char
*
name
,
const
char
*
value
);
int
setprop
(
const
char
*
name
,
const
char
*
value
,
const
bool
trigger
=
true
);
int
setprop2
(
const
char
*
name
,
const
char
*
value
,
const
int
trigger
);
char
*
getprop
(
const
char
*
name
,
bool
persist
=
false
);
char
*
getprop
(
const
char
*
name
);
void
getprop
(
void
(
*
callback
)(
const
char
*
,
const
char
*
,
void
*
),
void
*
cookie
,
bool
persist
=
false
);
char
*
getprop2
(
const
char
*
name
,
int
persist
);
int
deleteprop
(
const
char
*
name
,
bool
persist
=
false
);
int
deleteprop
(
const
char
*
name
);
int
load_prop_file
(
const
char
*
filename
,
const
bool
trigger
=
true
);
int
deleteprop2
(
const
char
*
name
,
const
int
persist
);
int
read_prop_file
(
const
char
*
filename
,
const
int
trigger
);
void
getprop_all
(
void
(
*
callback
)(
const
char
*
,
const
char
*
,
void
*
),
void
*
cookie
,
int
persist
);
#ifdef __cplusplus
}
#endif
#endif
native/jni/magiskhide/hide_utils.cpp
View file @
cda57dd4
...
@@ -51,7 +51,7 @@ void hide_sensitive_props() {
...
@@ -51,7 +51,7 @@ void hide_sensitive_props() {
value
=
getprop
(
prop_key
[
i
]);
value
=
getprop
(
prop_key
[
i
]);
if
(
value
)
{
if
(
value
)
{
if
(
strcmp
(
value
,
prop_value
[
i
])
!=
0
)
if
(
strcmp
(
value
,
prop_value
[
i
])
!=
0
)
setprop
2
(
prop_key
[
i
],
prop_value
[
i
],
0
);
setprop
(
prop_key
[
i
],
prop_value
[
i
],
false
);
free
(
value
);
free
(
value
);
}
}
}
}
...
@@ -133,10 +133,10 @@ static void kill_process(const char *name) {
...
@@ -133,10 +133,10 @@ static void kill_process(const char *name) {
void
clean_magisk_props
()
{
void
clean_magisk_props
()
{
LOGD
(
"hide_utils: Cleaning magisk props
\n
"
);
LOGD
(
"hide_utils: Cleaning magisk props
\n
"
);
getprop
_all
([](
const
char
*
name
,
auto
,
auto
)
->
void
{
getprop
([](
const
char
*
name
,
auto
,
auto
)
->
void
{
if
(
strstr
(
name
,
"magisk"
))
if
(
strstr
(
name
,
"magisk"
))
deleteprop
2
(
name
,
0
);
deleteprop
(
name
);
},
nullptr
,
0
);
},
nullptr
,
false
);
}
}
static
int
add_list
(
sqlite3
*
db
,
char
*
proc
)
{
static
int
add_list
(
sqlite3
*
db
,
char
*
proc
)
{
...
...
native/jni/magiskhide/magiskhide.cpp
View file @
cda57dd4
...
@@ -39,14 +39,14 @@ int launch_magiskhide() {
...
@@ -39,14 +39,14 @@ int launch_magiskhide() {
if
(
!
log_daemon_started
)
{
if
(
!
log_daemon_started
)
{
setprop
(
MAGISKHIDE_PROP
,
"0"
);
setprop
(
MAGISKHIDE_PROP
,
"0"
);
// Remove without actually removing persist props
// Remove without actually removing persist props
deleteprop
2
(
MAGISKHIDE_PROP
,
0
);
deleteprop
(
MAGISKHIDE_PROP
);
return
LOGCAT_DISABLED
;
return
LOGCAT_DISABLED
;
}
}
hide_enabled
=
1
;
hide_enabled
=
1
;
LOGI
(
"* Starting MagiskHide
\n
"
);
LOGI
(
"* Starting MagiskHide
\n
"
);
deleteprop
2
(
MAGISKHIDE_PROP
,
1
);
deleteprop
(
MAGISKHIDE_PROP
,
true
);
hide_sensitive_props
();
hide_sensitive_props
();
...
@@ -77,7 +77,7 @@ int stop_magiskhide() {
...
@@ -77,7 +77,7 @@ int stop_magiskhide() {
hide_enabled
=
0
;
hide_enabled
=
0
;
setprop
(
MAGISKHIDE_PROP
,
"0"
);
setprop
(
MAGISKHIDE_PROP
,
"0"
);
// Remove without actually removing persist props
// Remove without actually removing persist props
deleteprop
2
(
MAGISKHIDE_PROP
,
0
);
deleteprop
(
MAGISKHIDE_PROP
);
pthread_kill
(
proc_monitor_thread
,
TERM_THREAD
);
pthread_kill
(
proc_monitor_thread
,
TERM_THREAD
);
return
DAEMON_SUCCESS
;
return
DAEMON_SUCCESS
;
...
...
native/jni/magiskhide/magiskhide.h
View file @
cda57dd4
...
@@ -9,9 +9,7 @@
...
@@ -9,9 +9,7 @@
#define TERM_THREAD SIGUSR1
#define TERM_THREAD SIGUSR1
// Daemon entries
// Daemon entries
extern
"C"
{
int
launch_magiskhide
();
int
launch_magiskhide
();
}
int
stop_magiskhide
();
int
stop_magiskhide
();
int
add_list
(
int
client
);
int
add_list
(
int
client
);
int
rm_list
(
int
client
);
int
rm_list
(
int
client
);
...
...
native/jni/misc/applets.c
→
native/jni/misc/applets.c
pp
View file @
cda57dd4
File moved
native/jni/misc/img.c
→
native/jni/misc/img.c
pp
View file @
cda57dd4
/* img.c - All image related functions
/* img.c
pp
- All image related functions
*/
*/
#include <unistd.h>
#include <unistd.h>
...
...
native/jni/resetprop/resetprop.cpp
View file @
cda57dd4
...
@@ -112,9 +112,9 @@ static int init_resetprop() {
...
@@ -112,9 +112,9 @@ static int init_resetprop() {
return
0
;
return
0
;
}
}
static
void
print_props
(
int
persist
)
{
static
void
print_props
(
bool
persist
)
{
auto
prop_list
=
Array
<
prop_t
>
();
auto
prop_list
=
Array
<
prop_t
>
();
getprop
_all
(
collect_props
,
&
prop_list
,
persist
);
getprop
(
collect_props
,
&
prop_list
,
persist
);
prop_list
.
sort
();
prop_list
.
sort
();
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
);
...
@@ -129,12 +129,8 @@ int prop_exist(const char *name) {
...
@@ -129,12 +129,8 @@ int prop_exist(const char *name) {
return
__system_property_find
(
name
)
!=
nullptr
;
return
__system_property_find
(
name
)
!=
nullptr
;
}
}
char
*
getprop
(
const
char
*
name
)
{
return
getprop2
(
name
,
0
);
}
// Get prop by name, return string (should free manually!)
// Get prop by name, return string (should free manually!)
char
*
getprop
2
(
const
char
*
name
,
int
persist
)
{
char
*
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
);
...
@@ -157,7 +153,7 @@ char *getprop2(const char *name, int persist) {
...
@@ -157,7 +153,7 @@ char *getprop2(const char *name, int persist) {
}
}
}
}
void
getprop
_all
(
void
(
*
callback
)(
const
char
*
,
const
char
*
,
void
*
),
void
*
cookie
,
int
persist
)
{
void
getprop
(
void
(
*
callback
)(
const
char
*
,
const
char
*
,
void
*
),
void
*
cookie
,
bool
persist
)
{
if
(
init_resetprop
())
return
;
if
(
init_resetprop
())
return
;
read_cb_t
read_cb
(
callback
,
cookie
);
read_cb_t
read_cb
(
callback
,
cookie
);
__system_property_foreach
(
read_props
,
&
read_cb
);
__system_property_foreach
(
read_props
,
&
read_cb
);
...
@@ -167,11 +163,7 @@ void getprop_all(void (*callback)(const char *, const char *, void *), void *coo
...
@@ -167,11 +163,7 @@ void getprop_all(void (*callback)(const char *, const char *, void *), void *coo
}
}
}
}
int
setprop
(
const
char
*
name
,
const
char
*
value
)
{
int
setprop
(
const
char
*
name
,
const
char
*
value
,
const
bool
trigger
)
{
return
setprop2
(
name
,
value
,
1
);
}
int
setprop2
(
const
char
*
name
,
const
char
*
value
,
const
int
trigger
)
{
if
(
!
check_legal_property_name
(
name
))
if
(
!
check_legal_property_name
(
name
))
return
1
;
return
1
;
if
(
init_resetprop
())
if
(
init_resetprop
())
...
@@ -205,11 +197,7 @@ int setprop2(const char *name, const char *value, const int trigger) {
...
@@ -205,11 +197,7 @@ int setprop2(const char *name, const char *value, const int trigger) {
return
ret
;
return
ret
;
}
}
int
deleteprop
(
const
char
*
name
)
{
int
deleteprop
(
const
char
*
name
,
bool
persist
)
{
return
deleteprop2
(
name
,
1
);
}
int
deleteprop2
(
const
char
*
name
,
int
persist
)
{
if
(
!
check_legal_property_name
(
name
))
if
(
!
check_legal_property_name
(
name
))
return
1
;
return
1
;
if
(
init_resetprop
())
return
-
1
;
if
(
init_resetprop
())
return
-
1
;
...
@@ -221,7 +209,7 @@ int deleteprop2(const char *name, int persist) {
...
@@ -221,7 +209,7 @@ int deleteprop2(const char *name, int persist) {
return
__system_property_del
(
name
)
&&
!
(
persist
&&
strncmp
(
name
,
"persist."
,
8
)
==
0
);
return
__system_property_del
(
name
)
&&
!
(
persist
&&
strncmp
(
name
,
"persist."
,
8
)
==
0
);
}
}
int
read_prop_file
(
const
char
*
filename
,
const
int
trigger
)
{
int
load_prop_file
(
const
char
*
filename
,
const
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
=
fopen
(
filename
,
"r"
);
FILE
*
fp
=
fopen
(
filename
,
"r"
);
...
@@ -255,7 +243,7 @@ int read_prop_file(const char* filename, const int trigger) {
...
@@ -255,7 +243,7 @@ int read_prop_file(const char* filename, const int trigger) {
if
(
((
pch
==
nullptr
)
||
(
i
>=
(
pch
-
line
)))
||
(
pch
>=
line
+
read
-
1
)
)
continue
;
if
(
((
pch
==
nullptr
)
||
(
i
>=
(
pch
-
line
)))
||
(
pch
>=
line
+
read
-
1
)
)
continue
;
// Separate the string
// Separate the string
*
pch
=
'\0'
;
*
pch
=
'\0'
;
setprop
2
(
line
+
i
,
pch
+
1
,
trigger
);
setprop
(
line
+
i
,
pch
+
1
,
trigger
);
}
}
free
(
line
);
free
(
line
);
fclose
(
fp
);
fclose
(
fp
);
...
@@ -265,7 +253,7 @@ int read_prop_file(const char* filename, const int trigger) {
...
@@ -265,7 +253,7 @@ int read_prop_file(const char* filename, const int trigger) {
int
resetprop_main
(
int
argc
,
char
*
argv
[])
{
int
resetprop_main
(
int
argc
,
char
*
argv
[])
{
log_cb
.
d
=
[](
auto
fmt
,
auto
ap
)
->
int
{
return
verbose
?
vfprintf
(
stderr
,
fmt
,
ap
)
:
0
;
};
log_cb
.
d
=
[](
auto
fmt
,
auto
ap
)
->
int
{
return
verbose
?
vfprintf
(
stderr
,
fmt
,
ap
)
:
0
;
};
int
trigger
=
1
,
persist
=
0
;
bool
trigger
=
true
,
persist
=
false
;
char
*
argv0
=
argv
[
0
],
*
prop
;
char
*
argv0
=
argv
[
0
],
*
prop
;
--
argc
;
--
argc
;
...
@@ -277,9 +265,9 @@ int resetprop_main(int argc, char *argv[]) {
...
@@ -277,9 +265,9 @@ int resetprop_main(int argc, char *argv[]) {
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
)
{
return
re
ad_prop_file
(
argv
[
1
],
trigger
);
return
lo
ad_prop_file
(
argv
[
1
],
trigger
);
}
else
if
(
strcmp
(
argv
[
0
],
"--delete"
)
==
0
&&
argc
==
2
)
{
}
else
if
(
strcmp
(
argv
[
0
],
"--delete"
)
==
0
&&
argc
==
2
)
{
return
deleteprop
2
(
argv
[
1
],
persist
);
return
deleteprop
(
argv
[
1
],
persist
);
}
else
if
(
strcmp
(
argv
[
0
],
"--help"
)
==
0
)
{
}
else
if
(
strcmp
(
argv
[
0
],
"--help"
)
==
0
)
{
usage
(
argv0
);
usage
(
argv0
);
}
}
...
@@ -309,13 +297,13 @@ int resetprop_main(int argc, char *argv[]) {
...
@@ -309,13 +297,13 @@ int resetprop_main(int argc, char *argv[]) {
print_props
(
persist
);
print_props
(
persist
);
return
0
;
return
0
;
case
1
:
case
1
:
prop
=
getprop
2
(
argv
[
0
],
persist
);
prop
=
getprop
(
argv
[
0
],
persist
);
if
(
prop
==
nullptr
)
return
1
;
if
(
prop
==
nullptr
)
return
1
;
printf
(
"%s
\n
"
,
prop
);
printf
(
"%s
\n
"
,
prop
);
free
(
prop
);
free
(
prop
);
return
0
;
return
0
;
case
2
:
case
2
:
return
setprop
2
(
argv
[
0
],
argv
[
1
],
trigger
);
return
setprop
(
argv
[
0
],
argv
[
1
],
trigger
);
default:
default:
usage
(
argv0
);
usage
(
argv0
);
}
}
...
...
native/jni/su/connect.c
→
native/jni/su/connect.c
pp
View file @
cda57dd4
...
@@ -19,7 +19,7 @@
...
@@ -19,7 +19,7 @@
#define AM_PATH "/system/bin/app_process", "/system/bin", "com.android.commands.am.Am"
#define AM_PATH "/system/bin/app_process", "/system/bin", "com.android.commands.am.Am"
static
char
*
get_command
(
const
struct
su_request
*
to
)
{
static
c
onst
c
har
*
get_command
(
const
struct
su_request
*
to
)
{
if
(
to
->
command
[
0
])
if
(
to
->
command
[
0
])
return
to
->
command
;
return
to
->
command
;
if
(
to
->
shell
[
0
])
if
(
to
->
shell
[
0
])
...
@@ -27,7 +27,7 @@ static char *get_command(const struct su_request *to) {
...
@@ -27,7 +27,7 @@ static char *get_command(const struct su_request *to) {
return
DEFAULT_SHELL
;
return
DEFAULT_SHELL
;
}
}
static
void
silent_run
(
c
har
*
const
args
[])
{
static
void
silent_run
(
c
onst
char
*
args
[])
{
if
(
fork_dont_care
())
if
(
fork_dont_care
())
return
;
return
;
int
zero
=
open
(
"/dev/zero"
,
O_RDONLY
|
O_CLOEXEC
);
int
zero
=
open
(
"/dev/zero"
,
O_RDONLY
|
O_CLOEXEC
);
...
@@ -36,7 +36,7 @@ static void silent_run(char * const args[]) {
...
@@ -36,7 +36,7 @@ static void silent_run(char * const args[]) {
xdup2
(
null
,
1
);
xdup2
(
null
,
1
);
xdup2
(
null
,
2
);
xdup2
(
null
,
2
);
setenv
(
"CLASSPATH"
,
"/system/framework/am.jar"
,
1
);
setenv
(
"CLASSPATH"
,
"/system/framework/am.jar"
,
1
);
execv
(
args
[
0
],
args
);
execv
(
args
[
0
],
(
char
**
)
args
);
PLOGE
(
"exec am"
);
PLOGE
(
"exec am"
);
_exit
(
EXIT_FAILURE
);
_exit
(
EXIT_FAILURE
);
}
}
...
@@ -71,7 +71,7 @@ void app_log(struct su_context *ctx) {
...
@@ -71,7 +71,7 @@ void app_log(struct su_context *ctx) {
char
policy
[
2
];
char
policy
[
2
];
sprintf
(
policy
,
"%d"
,
ctx
->
info
->
access
.
policy
);
sprintf
(
policy
,
"%d"
,
ctx
->
info
->
access
.
policy
);
char
*
cmd
[]
=
{
c
onst
c
har
*
cmd
[]
=
{
AM_PATH
,
"broadcast"
,
AM_PATH
,
"broadcast"
,
"-a"
,
"android.intent.action.BOOT_COMPLETED"
,
"-a"
,
"android.intent.action.BOOT_COMPLETED"
,
"-p"
,
DB_STR
(
ctx
->
info
,
SU_MANAGER
),
"-p"
,
DB_STR
(
ctx
->
info
,
SU_MANAGER
),
...
@@ -84,7 +84,7 @@ void app_log(struct su_context *ctx) {
...
@@ -84,7 +84,7 @@ void app_log(struct su_context *ctx) {
"--ei"
,
"policy"
,
policy
,
"--ei"
,
"policy"
,
policy
,
"--es"
,
"command"
,
get_command
(
&
ctx
->
req
),
"--es"
,
"command"
,
get_command
(
&
ctx
->
req
),
"--ez"
,
"notify"
,
ctx
->
info
->
access
.
notify
?
"true"
:
"false"
,
"--ez"
,
"notify"
,
ctx
->
info
->
access
.
notify
?
"true"
:
"false"
,
NULL
nullptr
};
};
silent_run
(
cmd
);
silent_run
(
cmd
);
}
}
...
@@ -101,7 +101,7 @@ void app_notify(struct su_context *ctx) {
...
@@ -101,7 +101,7 @@ void app_notify(struct su_context *ctx) {
char
policy
[
2
];
char
policy
[
2
];
sprintf
(
policy
,
"%d"
,
ctx
->
info
->
access
.
policy
);
sprintf
(
policy
,
"%d"
,
ctx
->
info
->
access
.
policy
);
char
*
cmd
[]
=
{
c
onst
c
har
*
cmd
[]
=
{
AM_PATH
,
"broadcast"
,
AM_PATH
,
"broadcast"
,
"-a"
,
"android.intent.action.BOOT_COMPLETED"
,
"-a"
,
"android.intent.action.BOOT_COMPLETED"
,
"-p"
,
DB_STR
(
ctx
->
info
,
SU_MANAGER
),
"-p"
,
DB_STR
(
ctx
->
info
,
SU_MANAGER
),
...
@@ -110,7 +110,7 @@ void app_notify(struct su_context *ctx) {
...
@@ -110,7 +110,7 @@ void app_notify(struct su_context *ctx) {
"--es"
,
"action"
,
"notify"
,
"--es"
,
"action"
,
"notify"
,
"--ei"
,
"from.uid"
,
fromUid
,
"--ei"
,
"from.uid"
,
fromUid
,
"--ei"
,
"policy"
,
policy
,
"--ei"
,
"policy"
,
policy
,
NULL
nullptr
};
};
silent_run
(
cmd
);
silent_run
(
cmd
);
}
}
...
@@ -118,15 +118,15 @@ void app_notify(struct su_context *ctx) {
...
@@ -118,15 +118,15 @@ void app_notify(struct su_context *ctx) {
void
app_connect
(
const
char
*
socket
,
struct
su_info
*
info
)
{
void
app_connect
(
const
char
*
socket
,
struct
su_info
*
info
)
{
char
user
[
8
];
char
user
[
8
];
setup_user
(
user
,
info
);
setup_user
(
user
,
info
);
char
*
cmd
[]
=
{
c
onst
c
har
*
cmd
[]
=
{
AM_PATH
,
"broadcast"
,
AM_PATH
,
"broadcast"
,
"-a"
,
"android.intent.action.BOOT_COMPLETED"
,
"-a"
,
"android.intent.action.BOOT_COMPLETED"
,
"-p"
,
DB_STR
(
info
,
SU_MANAGER
),
"-p"
,
DB_STR
(
info
,
SU_MANAGER
),
"-f"
,
"0x00000020"
,
"-f"
,
"0x00000020"
,
"--user"
,
user
,
"--user"
,
user
,
"--es"
,
"action"
,
"request"
,
"--es"
,
"action"
,
"request"
,
"--es"
,
"socket"
,
(
char
*
)
socket
,
"--es"
,
"socket"
,
socket
,
NULL
nullptr
};
};
silent_run
(
cmd
);
silent_run
(
cmd
);
}
}
...
@@ -135,4 +135,3 @@ void socket_send_request(int fd, struct su_info *info) {
...
@@ -135,4 +135,3 @@ void socket_send_request(int fd, struct su_info *info) {
write_key_token
(
fd
,
"uid"
,
info
->
uid
);
write_key_token
(
fd
,
"uid"
,
info
->
uid
);
write_string_be
(
fd
,
"eof"
);
write_string_be
(
fd
,
"eof"
);
}
}
native/jni/su/pts.c
→
native/jni/su/pts.c
pp
View file @
cda57dd4
...
@@ -9,7 +9,6 @@
...
@@ -9,7 +9,6 @@
* helper functions to handle raw input mode and terminal window resizing
* helper functions to handle raw input mode and terminal window resizing
*/
*/
#define _GNU_SOURCE
#include <stdlib.h>
#include <stdlib.h>
#include <unistd.h>
#include <unistd.h>
#include <fcntl.h>
#include <fcntl.h>
...
...
native/jni/su/su.c
→
native/jni/su/su.c
pp
View file @
cda57dd4
...
@@ -8,7 +8,6 @@
...
@@ -8,7 +8,6 @@
/* su.c - The main function running in the daemon
/* su.c - The main function running in the daemon
*/
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include <string.h>
#include <string.h>
...
@@ -95,6 +94,12 @@ static void setup_sighandlers(void (*handler)(int)) {
...
@@ -95,6 +94,12 @@ static void setup_sighandlers(void (*handler)(int)) {
}
}
}
}
// Default values
su_req_base
::
su_req_base
()
:
uid
(
UID_ROOT
),
login
(
false
),
keepenv
(
false
),
mount_master
(
false
)
{}
su_request
::
su_request
()
:
shell
(
DEFAULT_SHELL
),
command
(
""
)
{}
/*
/*
* Connect daemon, send argc, argv, cwd, pts slave
* Connect daemon, send argc, argv, cwd, pts slave
*/
*/
...
@@ -112,15 +117,7 @@ int su_client_main(int argc, char *argv[]) {
...
@@ -112,15 +117,7 @@ int su_client_main(int argc, char *argv[]) {
{
NULL
,
0
,
NULL
,
0
},
{
NULL
,
0
,
NULL
,
0
},
};
};
struct
su_request
su_req
=
{
su_request
su_req
;
.
uid
=
UID_ROOT
,
.
login
=
0
,
.
keepenv
=
0
,
.
mount_master
=
0
,
.
shell
=
DEFAULT_SHELL
,
.
command
=
""
,
};
for
(
int
i
=
0
;
i
<
argc
;
i
++
)
{
for
(
int
i
=
0
;
i
<
argc
;
i
++
)
{
// Replace -cn with -z, -mm with -M for supporting getopt_long
// Replace -cn with -z, -mm with -M for supporting getopt_long
...
@@ -140,11 +137,11 @@ int su_client_main(int argc, char *argv[]) {
...
@@ -140,11 +137,11 @@ int su_client_main(int argc, char *argv[]) {
usage
(
EXIT_SUCCESS
);
usage
(
EXIT_SUCCESS
);
break
;
break
;
case
'l'
:
case
'l'
:
su_req
.
login
=
1
;
su_req
.
login
=
true
;
break
;
break
;
case
'm'
:
case
'm'
:
case
'p'
:
case
'p'
:
su_req
.
keepenv
=
1
;
su_req
.
keepenv
=
true
;
break
;
break
;
case
's'
:
case
's'
:
su_req
.
shell
=
optarg
;
su_req
.
shell
=
optarg
;
...
@@ -159,7 +156,7 @@ int su_client_main(int argc, char *argv[]) {
...
@@ -159,7 +156,7 @@ int su_client_main(int argc, char *argv[]) {
// Do nothing, placed here for legacy support :)
// Do nothing, placed here for legacy support :)
break
;
break
;
case
'M'
:
case
'M'
:
su_req
.
mount_master
=
1
;
su_req
.
mount_master
=
true
;
break
;
break
;
default
:
default
:
/* Bionic getopt_long doesn't terminate its error output by newline */
/* Bionic getopt_long doesn't terminate its error output by newline */
...
@@ -169,7 +166,7 @@ int su_client_main(int argc, char *argv[]) {
...
@@ -169,7 +166,7 @@ int su_client_main(int argc, char *argv[]) {
}
}
if
(
optind
<
argc
&&
strcmp
(
argv
[
optind
],
"-"
)
==
0
)
{
if
(
optind
<
argc
&&
strcmp
(
argv
[
optind
],
"-"
)
==
0
)
{
su_req
.
login
=
1
;
su_req
.
login
=
true
;
optind
++
;
optind
++
;
}
}
/* username or uid */
/* username or uid */
...
@@ -200,7 +197,7 @@ int su_client_main(int argc, char *argv[]) {
...
@@ -200,7 +197,7 @@ int su_client_main(int argc, char *argv[]) {
}
}
// Send su_request
// Send su_request
xwrite
(
fd
,
&
su_req
,
4
*
sizeof
(
unsigned
));
xwrite
(
fd
,
&
su_req
,
sizeof
(
su_req_base
));
write_string
(
fd
,
su_req
.
shell
);
write_string
(
fd
,
su_req
.
shell
);
write_string
(
fd
,
su_req
.
command
);
write_string
(
fd
,
su_req
.
command
);
...
...
native/jni/su/su.h
View file @
cda57dd4
...
@@ -17,9 +17,9 @@
...
@@ -17,9 +17,9 @@
#define ATTY_OUT 2
#define ATTY_OUT 2
#define ATTY_ERR 4
#define ATTY_ERR 4
struct
su_info
{
class
su_info
{
public
:
unsigned
uid
;
/* Unique key to find su_info */
unsigned
uid
;
/* Unique key to find su_info */
pthread_mutex_t
lock
;
/* Internal lock */
int
count
;
/* Just a count for debugging purpose */
int
count
;
/* Just a count for debugging purpose */
/* These values should be guarded with internal lock */
/* These values should be guarded with internal lock */
...
@@ -31,19 +31,33 @@ struct su_info {
...
@@ -31,19 +31,33 @@ struct su_info {
/* These should be guarded with global cache lock */
/* These should be guarded with global cache lock */
int
ref
;
int
ref
;
int
life
;
int
life
;
su_info
(
unsigned
uid
);
~
su_info
();
void
lock
();
void
unlock
();
private
:
pthread_mutex_t
_lock
;
/* Internal lock */
};
};
#define DB_SET(i, e) (i)->dbs.v[e]
#define DB_SET(i, e) (i)->dbs.v[e]
#define DB_STR(i, e) (i)->str.s[e]
#define DB_STR(i, e) (i)->str.s[e]
struct
su_req
uest
{
struct
su_req
_base
{
unsigned
uid
;
unsigned
uid
;
unsigned
login
;
bool
login
;
unsigned
keepenv
;
bool
keepenv
;
unsigned
mount_master
;
bool
mount_master
;
char
*
shell
;
protected
:
char
*
command
;
su_req_base
();
};
}
__attribute__
((
packed
));
struct
su_request
:
public
su_req_base
{
const
char
*
shell
;
const
char
*
command
;
su_request
();
}
__attribute__
((
packed
));
struct
su_context
{
struct
su_context
{
struct
su_info
*
info
;
struct
su_info
*
info
;
...
...
native/jni/su/su_daemon.c
→
native/jni/su/su_daemon.c
pp
View file @
cda57dd4
/* su_daemon.c - The entrypoint for su, connect to daemon and send correct info
*/
#define _GNU_SOURCE
#include <unistd.h>
#include <unistd.h>
#include <pthread.h>
#include <pthread.h>
#include <stdlib.h>
#include <stdlib.h>
...
@@ -25,32 +20,45 @@
...
@@ -25,32 +20,45 @@
#define TIMEOUT 3
#define TIMEOUT 3
#define LOCK_CACHE() pthread_mutex_lock(&cache_lock)
#define LOCK_CACHE() pthread_mutex_lock(&cache_lock)
#define LOCK_INFO() pthread_mutex_lock(&info->lock)
#define UNLOCK_CACHE() pthread_mutex_unlock(&cache_lock)
#define UNLOCK_CACHE() pthread_mutex_unlock(&cache_lock)
#define UNLOCK_INFO() pthread_mutex_unlock(&info->lock)
static
pthread_mutex_t
cache_lock
=
PTHREAD_MUTEX_INITIALIZER
;
static
pthread_mutex_t
cache_lock
=
PTHREAD_MUTEX_INITIALIZER
;
static
struct
su_info
*
cache
;
static
su_info
*
cache
;
su_info
::
su_info
(
unsigned
uid
)
:
uid
(
uid
),
access
(
DEFAULT_SU_ACCESS
),
_lock
(
PTHREAD_MUTEX_INITIALIZER
),
count
(
0
),
ref
(
0
),
life
(
0
),
mgr_st
({})
{}
su_info
::~
su_info
()
{
pthread_mutex_destroy
(
&
_lock
);
}
void
su_info
::
lock
()
{
pthread_mutex_lock
(
&
_lock
);
}
void
su_info
::
unlock
()
{
pthread_mutex_unlock
(
&
_lock
);
}
static
void
*
info_collector
(
void
*
node
)
{
static
void
*
info_collector
(
void
*
node
)
{
s
truct
su_info
*
info
=
node
;
s
u_info
*
info
=
(
su_info
*
)
node
;
while
(
1
)
{
while
(
1
)
{
sleep
(
1
);
sleep
(
1
);
if
(
info
->
life
)
{
if
(
info
->
life
)
{
LOCK_CACHE
();
LOCK_CACHE
();
if
(
--
info
->
life
==
0
&&
cache
&&
info
->
uid
==
cache
->
uid
)
if
(
--
info
->
life
==
0
&&
cache
&&
info
->
uid
==
cache
->
uid
)
cache
=
NULL
;
cache
=
nullptr
;
UNLOCK_CACHE
();
UNLOCK_CACHE
();
}
}
if
(
!
info
->
life
&&
!
info
->
ref
)
{
if
(
!
info
->
life
&&
!
info
->
ref
)
{
pthread_mutex_destroy
(
&
info
->
lock
);
delete
info
;
free
(
info
);
return
nullptr
;
return
NULL
;
}
}
}
}
}
}
static
void
database_check
(
s
truct
s
u_info
*
info
)
{
static
void
database_check
(
su_info
*
info
)
{
int
uid
=
info
->
uid
;
int
uid
=
info
->
uid
;
sqlite3
*
db
=
get_magiskdb
();
sqlite3
*
db
=
get_magiskdb
();
if
(
db
)
{
if
(
db
)
{
...
@@ -84,20 +92,16 @@ static void database_check(struct su_info *info) {
...
@@ -84,20 +92,16 @@ static void database_check(struct su_info *info) {
}
}
static
struct
su_info
*
get_su_info
(
unsigned
uid
)
{
static
struct
su_info
*
get_su_info
(
unsigned
uid
)
{
s
truct
s
u_info
*
info
;
su_info
*
info
;
int
cache_miss
=
0
;
bool
cache_miss
=
false
;
LOCK_CACHE
();
LOCK_CACHE
();
if
(
cache
&&
cache
->
uid
==
uid
)
{
if
(
cache
&&
cache
->
uid
==
uid
)
{
info
=
cache
;
info
=
cache
;
}
else
{
}
else
{
cache_miss
=
1
;
cache_miss
=
true
;
info
=
xcalloc
(
1
,
sizeof
(
*
info
));
info
=
new
su_info
(
uid
);
info
->
uid
=
uid
;
info
->
dbs
=
DEFAULT_DB_SETTINGS
;
info
->
access
=
DEFAULT_SU_ACCESS
;
pthread_mutex_init
(
&
info
->
lock
,
NULL
);
cache
=
info
;
cache
=
info
;
}
}
...
@@ -108,7 +112,7 @@ static struct su_info *get_su_info(unsigned uid) {
...
@@ -108,7 +112,7 @@ static struct su_info *get_su_info(unsigned uid) {
// Start a thread to maintain the cache
// Start a thread to maintain the cache
if
(
cache_miss
)
{
if
(
cache_miss
)
{
pthread_t
thread
;
pthread_t
thread
;
xpthread_create
(
&
thread
,
NULL
,
info_collector
,
info
);
xpthread_create
(
&
thread
,
nullptr
,
info_collector
,
info
);
pthread_detach
(
thread
);
pthread_detach
(
thread
);
}
}
...
@@ -117,7 +121,7 @@ static struct su_info *get_su_info(unsigned uid) {
...
@@ -117,7 +121,7 @@ static struct su_info *get_su_info(unsigned uid) {
LOGD
(
"su: request from uid=[%d] (#%d)
\n
"
,
info
->
uid
,
++
info
->
count
);
LOGD
(
"su: request from uid=[%d] (#%d)
\n
"
,
info
->
uid
,
++
info
->
count
);
// Lock before the policy is determined
// Lock before the policy is determined
LOCK_INFO
();
info
->
lock
();
if
(
info
->
access
.
policy
==
QUERY
)
{
if
(
info
->
access
.
policy
==
QUERY
)
{
// Not cached, get data from database
// Not cached, get data from database
...
@@ -173,14 +177,14 @@ static struct su_info *get_su_info(unsigned uid) {
...
@@ -173,14 +177,14 @@ static struct su_info *get_su_info(unsigned uid) {
}
else
{
}
else
{
socket_send_request
(
fd
,
info
);
socket_send_request
(
fd
,
info
);
int
ret
=
read_int_be
(
fd
);
int
ret
=
read_int_be
(
fd
);
info
->
access
.
policy
=
ret
<
0
?
DENY
:
ret
;
info
->
access
.
policy
=
ret
<
0
?
DENY
:
static_cast
<
policy_t
>
(
ret
)
;
close
(
fd
);
close
(
fd
);
}
}
close
(
sockfd
);
close
(
sockfd
);
}
}
// Unlock
// Unlock
UNLOCK_INFO
();
info
->
unlock
();
return
info
;
return
info
;
}
}
...
@@ -224,7 +228,7 @@ static void set_identity(unsigned uid) {
...
@@ -224,7 +228,7 @@ static void set_identity(unsigned uid) {
void
su_daemon_handler
(
int
client
,
struct
ucred
*
credential
)
{
void
su_daemon_handler
(
int
client
,
struct
ucred
*
credential
)
{
LOGD
(
"su: request from client: %d
\n
"
,
client
);
LOGD
(
"su: request from client: %d
\n
"
,
client
);
s
truct
s
u_info
*
info
=
get_su_info
(
credential
->
uid
);
su_info
*
info
=
get_su_info
(
credential
->
uid
);
// Fail fast
// Fail fast
if
(
info
->
access
.
policy
==
DENY
&&
DB_STR
(
info
,
SU_MANAGER
)[
0
]
==
'\0'
)
{
if
(
info
->
access
.
policy
==
DENY
&&
DB_STR
(
info
,
SU_MANAGER
)[
0
]
==
'\0'
)
{
...
@@ -289,7 +293,7 @@ void su_daemon_handler(int client, struct ucred *credential) {
...
@@ -289,7 +293,7 @@ void su_daemon_handler(int client, struct ucred *credential) {
}
}
// Read su_request
// Read su_request
xxread
(
client
,
&
ctx
.
req
,
4
*
sizeof
(
unsigned
));
xxread
(
client
,
&
ctx
.
req
,
sizeof
(
su_req_base
));
ctx
.
req
.
shell
=
read_string
(
client
);
ctx
.
req
.
shell
=
read_string
(
client
);
ctx
.
req
.
command
=
read_string
(
client
);
ctx
.
req
.
command
=
read_string
(
client
);
...
@@ -367,7 +371,7 @@ void su_daemon_handler(int client, struct ucred *credential) {
...
@@ -367,7 +371,7 @@ void su_daemon_handler(int client, struct ucred *credential) {
app_notify
(
&
ctx
);
app_notify
(
&
ctx
);
if
(
info
->
access
.
policy
==
ALLOW
)
{
if
(
info
->
access
.
policy
==
ALLOW
)
{
c
har
*
argv
[]
=
{
NULL
,
NULL
,
NULL
,
NULL
};
c
onst
char
*
argv
[]
=
{
nullptr
,
nullptr
,
nullptr
,
nullptr
};
argv
[
0
]
=
ctx
.
req
.
login
?
"-"
:
ctx
.
req
.
shell
;
argv
[
0
]
=
ctx
.
req
.
login
?
"-"
:
ctx
.
req
.
shell
;
...
@@ -381,7 +385,7 @@ void su_daemon_handler(int client, struct ucred *credential) {
...
@@ -381,7 +385,7 @@ void su_daemon_handler(int client, struct ucred *credential) {
populate_environment
(
&
ctx
.
req
);
populate_environment
(
&
ctx
.
req
);
set_identity
(
ctx
.
req
.
uid
);
set_identity
(
ctx
.
req
.
uid
);
execvp
(
ctx
.
req
.
shell
,
argv
);
execvp
(
ctx
.
req
.
shell
,
(
char
**
)
argv
);
fprintf
(
stderr
,
"Cannot execute %s: %s
\n
"
,
ctx
.
req
.
shell
,
strerror
(
errno
));
fprintf
(
stderr
,
"Cannot execute %s: %s
\n
"
,
ctx
.
req
.
shell
,
strerror
(
errno
));
PLOGE
(
"exec"
);
PLOGE
(
"exec"
);
exit
(
EXIT_FAILURE
);
exit
(
EXIT_FAILURE
);
...
@@ -391,4 +395,3 @@ void su_daemon_handler(int client, struct ucred *credential) {
...
@@ -391,4 +395,3 @@ void su_daemon_handler(int client, struct ucred *credential) {
exit
(
EXIT_FAILURE
);
exit
(
EXIT_FAILURE
);
}
}
}
}
native/jni/utils/Android.mk
View file @
cda57dd4
...
@@ -9,7 +9,6 @@ LOCAL_SRC_FILES := \
...
@@ -9,7 +9,6 @@ LOCAL_SRC_FILES := \
selinux.cpp \
selinux.cpp \
logging.cpp \
logging.cpp \
xwrap.cpp \
xwrap.cpp \
vector.c \
vector.c
legacy.c
include $(BUILD_STATIC_LIBRARY)
include $(BUILD_STATIC_LIBRARY)
native/jni/utils/include/array.h
View file @
cda57dd4
...
@@ -66,6 +66,15 @@ public:
...
@@ -66,6 +66,15 @@ public:
T
*
_node
;
T
*
_node
;
};
};
T
&
operator
=
(
const
T
&
a
)
{
_size
=
a
.
_size
;
_capacity
=
a
.
_capacity
;
_data
=
new
T
[
_capacity
];
for
(
int
i
=
0
;
i
<
_size
;
++
i
)
_data
[
i
]
=
(
T
&&
)
a
[
i
];
return
*
this
;
}
iterator
begin
()
const
{
return
iterator
(
_data
);
}
iterator
begin
()
const
{
return
iterator
(
_data
);
}
iterator
end
()
const
{
return
iterator
(
_data
+
_size
);
}
iterator
end
()
const
{
return
iterator
(
_data
+
_size
);
}
...
@@ -149,7 +158,8 @@ private:
...
@@ -149,7 +158,8 @@ private:
_capacity
*=
2
;
_capacity
*=
2
;
T
*
temp
=
_data
;
T
*
temp
=
_data
;
_data
=
new
T
[
_capacity
];
_data
=
new
T
[
_capacity
];
for
(
int
i
=
0
;
i
<
_size
;
++
i
)
_data
[
i
]
=
(
T
&&
)
temp
[
i
];
for
(
int
i
=
0
;
i
<
_size
;
++
i
)
_data
[
i
]
=
(
T
&&
)
temp
[
i
];
delete
[]
temp
;
delete
[]
temp
;
}
}
};
};
...
...
native/jni/utils/include/selinux.h
View file @
cda57dd4
...
@@ -4,7 +4,6 @@
...
@@ -4,7 +4,6 @@
extern
"C"
{
extern
"C"
{
#endif
#endif
extern
void
(
*
freecon
)(
char
*
con
);
extern
void
(
*
freecon
)(
char
*
con
);
extern
int
(
*
setcon
)(
const
char
*
con
);
extern
int
(
*
setcon
)(
const
char
*
con
);
extern
int
(
*
getfilecon
)(
const
char
*
path
,
char
**
con
);
extern
int
(
*
getfilecon
)(
const
char
*
path
,
char
**
con
);
...
...
native/jni/utils/include/utils.h
View file @
cda57dd4
...
@@ -18,8 +18,6 @@ int file_to_array(const char* filename, Array<char *> &arr);
...
@@ -18,8 +18,6 @@ int file_to_array(const char* filename, Array<char *> &arr);
extern
"C"
{
extern
"C"
{
#endif
#endif
#include "vector.h"
#define UID_SHELL (get_shell_uid())
#define UID_SHELL (get_shell_uid())
#define UID_ROOT 0
#define UID_ROOT 0
#define UID_SYSTEM (get_system_uid())
#define UID_SYSTEM (get_system_uid())
...
@@ -86,8 +84,6 @@ int xpoll(struct pollfd *fds, nfds_t nfds, int timeout);
...
@@ -86,8 +84,6 @@ int xpoll(struct pollfd *fds, nfds_t nfds, int timeout);
unsigned
get_shell_uid
();
unsigned
get_shell_uid
();
unsigned
get_system_uid
();
unsigned
get_system_uid
();
unsigned
get_radio_uid
();
unsigned
get_radio_uid
();
int
file_to_vector
(
const
char
*
filename
,
struct
vector
*
v
);
int
vector_to_file
(
const
char
*
filename
,
struct
vector
*
v
);
ssize_t
fdgets
(
char
*
buf
,
size_t
size
,
int
fd
);
ssize_t
fdgets
(
char
*
buf
,
size_t
size
,
int
fd
);
int
is_num
(
const
char
*
s
);
int
is_num
(
const
char
*
s
);
int
exec_array
(
int
err
,
int
*
fd
,
void
(
*
cb
)(
void
),
const
char
*
argv
[]);
int
exec_array
(
int
err
,
int
*
fd
,
void
(
*
cb
)(
void
),
const
char
*
argv
[]);
...
...
native/jni/utils/legacy.c
deleted
100644 → 0
View file @
4351de50
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "utils.h"
#include "logging.h"
/* All the string should be freed manually!! */
int
file_to_vector
(
const
char
*
filename
,
struct
vector
*
v
)
{
if
(
access
(
filename
,
R_OK
)
!=
0
)
return
1
;
char
*
line
=
NULL
;
size_t
len
=
0
;
ssize_t
read
;
FILE
*
fp
=
xfopen
(
filename
,
"r"
);
if
(
fp
==
NULL
)
return
1
;
while
((
read
=
getline
(
&
line
,
&
len
,
fp
))
!=
-
1
)
{
// Remove end newline
if
(
line
[
read
-
1
]
==
'\n'
)
line
[
read
-
1
]
=
'\0'
;
vec_push_back
(
v
,
line
);
line
=
NULL
;
}
fclose
(
fp
);
return
0
;
}
int
vector_to_file
(
const
char
*
filename
,
struct
vector
*
v
)
{
FILE
*
fp
=
xfopen
(
filename
,
"w"
);
if
(
fp
==
NULL
)
return
1
;
char
*
line
;
vec_for_each
(
v
,
line
)
{
fprintf
(
fp
,
"%s
\n
"
,
line
);
}
fclose
(
fp
);
return
0
;
}
\ No newline at end of file
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