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
c8990b0f
Commit
c8990b0f
authored
Feb 07, 2022
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Rewrite UID tracking
parent
7dced4b9
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
140 additions
and
99 deletions
+140
-99
xwrap.cpp
native/jni/utils/xwrap.cpp
+8
-0
xwrap.hpp
native/jni/utils/xwrap.hpp
+4
-3
utils.cpp
native/jni/zygisk/deny/utils.cpp
+128
-96
No files found.
native/jni/utils/xwrap.cpp
View file @
c8990b0f
...
@@ -288,6 +288,14 @@ int xfstat(int fd, struct stat *buf) {
...
@@ -288,6 +288,14 @@ int xfstat(int fd, struct stat *buf) {
return
ret
;
return
ret
;
}
}
int
xfstatat
(
int
dirfd
,
const
char
*
pathname
,
struct
stat
*
buf
,
int
flags
)
{
int
ret
=
fstatat
(
dirfd
,
pathname
,
buf
,
flags
);
if
(
ret
<
0
)
{
PLOGE
(
"fstatat %s"
,
pathname
);
}
return
ret
;
}
int
xdup
(
int
fd
)
{
int
xdup
(
int
fd
)
{
int
ret
=
dup
(
fd
);
int
ret
=
dup
(
fd
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
...
...
native/jni/utils/xwrap.hpp
View file @
c8990b0f
...
@@ -26,9 +26,9 @@ int xbind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
...
@@ -26,9 +26,9 @@ int xbind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
int
xconnect
(
int
sockfd
,
const
struct
sockaddr
*
addr
,
socklen_t
addrlen
);
int
xconnect
(
int
sockfd
,
const
struct
sockaddr
*
addr
,
socklen_t
addrlen
);
int
xlisten
(
int
sockfd
,
int
backlog
);
int
xlisten
(
int
sockfd
,
int
backlog
);
int
xaccept4
(
int
sockfd
,
struct
sockaddr
*
addr
,
socklen_t
*
addrlen
,
int
flags
);
int
xaccept4
(
int
sockfd
,
struct
sockaddr
*
addr
,
socklen_t
*
addrlen
,
int
flags
);
extern
"C"
void
*
xmalloc
(
size_t
size
);
void
*
xmalloc
(
size_t
size
);
extern
"C"
void
*
xcalloc
(
size_t
nmemb
,
size_t
size
);
void
*
xcalloc
(
size_t
nmemb
,
size_t
size
);
extern
"C"
void
*
xrealloc
(
void
*
ptr
,
size_t
size
);
void
*
xrealloc
(
void
*
ptr
,
size_t
size
);
ssize_t
xsendmsg
(
int
sockfd
,
const
struct
msghdr
*
msg
,
int
flags
);
ssize_t
xsendmsg
(
int
sockfd
,
const
struct
msghdr
*
msg
,
int
flags
);
ssize_t
xrecvmsg
(
int
sockfd
,
struct
msghdr
*
msg
,
int
flags
);
ssize_t
xrecvmsg
(
int
sockfd
,
struct
msghdr
*
msg
,
int
flags
);
int
xpthread_create
(
pthread_t
*
thread
,
const
pthread_attr_t
*
attr
,
int
xpthread_create
(
pthread_t
*
thread
,
const
pthread_attr_t
*
attr
,
...
@@ -37,6 +37,7 @@ int xaccess(const char *path, int mode);
...
@@ -37,6 +37,7 @@ int xaccess(const char *path, int mode);
int
xstat
(
const
char
*
pathname
,
struct
stat
*
buf
);
int
xstat
(
const
char
*
pathname
,
struct
stat
*
buf
);
int
xlstat
(
const
char
*
pathname
,
struct
stat
*
buf
);
int
xlstat
(
const
char
*
pathname
,
struct
stat
*
buf
);
int
xfstat
(
int
fd
,
struct
stat
*
buf
);
int
xfstat
(
int
fd
,
struct
stat
*
buf
);
int
xfstatat
(
int
dirfd
,
const
char
*
pathname
,
struct
stat
*
buf
,
int
flags
);
int
xdup
(
int
fd
);
int
xdup
(
int
fd
);
int
xdup2
(
int
oldfd
,
int
newfd
);
int
xdup2
(
int
oldfd
,
int
newfd
);
int
xdup3
(
int
oldfd
,
int
newfd
,
int
flags
);
int
xdup3
(
int
oldfd
,
int
newfd
,
int
flags
);
...
...
native/jni/zygisk/deny/utils.cpp
View file @
c8990b0f
...
@@ -14,24 +14,74 @@
...
@@ -14,24 +14,74 @@
using
namespace
std
;
using
namespace
std
;
#define FIRST_APP_UID 10000
struct
app_id_bitset
:
public
dynamic_bitset_impl
{
slot_bits
::
reference
operator
[]
(
size_t
pos
)
{
return
pos
<
FIRST_APP_UID
?
get
(
0
)
:
get
(
pos
-
FIRST_APP_UID
);
}
bool
operator
[]
(
size_t
pos
)
const
{
return
pos
<
FIRST_APP_UID
||
get
(
pos
-
FIRST_APP_UID
);
}
};
// For the following data structures:
// If package name == ISOLATED_MAGIC, or app ID == -1, it means isolated service
// List of all discovered app IDs
static
app_id_bitset
*
app_ids_seen_
;
#define app_ids_seen (*app_ids_seen_)
// Package name -> list of process names
// Package name -> list of process names
using
str_set
=
set
<
string
,
StringCmp
>
;
static
map
<
string
,
set
<
string
,
StringCmp
>
,
StringCmp
>
*
pkg_to_procs_
;
static
map
<
string
,
str_set
,
StringCmp
>
*
deny_map_
;
#define pkg_to_procs (*pkg_to_procs_)
#define deny_map (*deny_map_)
// app ID -> list of p
rocess name
// app ID -> list of p
kg names (string_view points to a pkg_to_procs key)
static
map
<
int
,
vector
<
string_view
>>
*
app_id_proc_map
;
static
map
<
int
,
set
<
string_view
>>
*
app_id_to_pkgs_
;
static
int
inotify_fd
=
-
1
;
#define app_id_to_pkgs (*app_id_to_pkgs_)
// Locks the
variabl
es above
// Locks the
data structur
es above
static
pthread_mutex_t
data_lock
=
PTHREAD_MUTEX_INITIALIZER
;
static
pthread_mutex_t
data_lock
=
PTHREAD_MUTEX_INITIALIZER
;
atomic
<
bool
>
denylist_enforced
=
false
;
atomic
<
bool
>
denylist_enforced
=
false
;
#define do_kill (zygisk_enabled && denylist_enforced)
#define do_kill (zygisk_enabled && denylist_enforced)
static
void
rebuild_map
()
{
static
void
rescan_apps
()
{
app_id_proc_map
->
clear
();
LOGD
(
"denylist: rescanning apps
\n
"
);
app_id_to_pkgs
.
clear
();
auto
data_dir
=
xopen_dir
(
APP_DATA_DIR
);
if
(
!
data_dir
)
return
;
dirent
*
entry
;
while
((
entry
=
xreaddir
(
data_dir
.
get
())))
{
// For each user
int
dfd
=
xopenat
(
dirfd
(
data_dir
.
get
()),
entry
->
d_name
,
O_RDONLY
);
if
(
auto
dir
=
xopen_dir
(
dfd
))
{
while
((
entry
=
xreaddir
(
dir
.
get
())))
{
// For each package
struct
stat
st
{};
xfstatat
(
dfd
,
entry
->
d_name
,
&
st
,
0
);
int
app_id
=
to_app_id
(
st
.
st_uid
);
if
(
app_id_to_pkgs
.
contains
(
app_id
))
{
// This app ID has been handled
continue
;
}
app_ids_seen
[
app_id
]
=
true
;
if
(
auto
it
=
pkg_to_procs
.
find
(
entry
->
d_name
);
it
!=
pkg_to_procs
.
end
())
{
app_id_to_pkgs
[
app_id
].
insert
(
it
->
first
);
}
}
}
else
{
close
(
dfd
);
}
}
if
(
auto
it
=
pkg_to_procs
.
find
(
ISOLATED_MAGIC
);
it
!=
pkg_to_procs
.
end
())
{
app_id_to_pkgs
[
-
1
].
insert
(
it
->
first
);
}
}
static
void
update_pkg_uid
(
const
string
&
pkg
,
bool
remove
)
{
string
data_path
(
APP_DATA_DIR
);
string
data_path
(
APP_DATA_DIR
);
size_t
len
=
data_path
.
length
();
size_t
len
=
data_path
.
length
();
...
@@ -45,28 +95,27 @@ static void rebuild_map() {
...
@@ -45,28 +95,27 @@ static void rebuild_map() {
return
;
return
;
}
}
for
(
const
auto
&
[
pkg
,
procs
]
:
deny_map
)
{
// Find package data folder to get its app ID
int
app_id
=
-
1
;
for
(
const
auto
&
user_id
:
users
)
{
if
(
pkg
!=
ISOLATED_MAGIC
)
{
data_path
.
resize
(
len
);
// Traverse the filesystem to find app ID
data_path
+=
'/'
;
for
(
const
auto
&
user_id
:
users
)
{
data_path
+=
user_id
;
data_path
.
resize
(
len
);
data_path
+=
'/'
;
data_path
+=
'/'
;
data_path
+=
pkg
;
data_path
+=
user_id
;
struct
stat
st
{};
data_path
+=
'/'
;
if
(
stat
(
data_path
.
data
(),
&
st
)
!=
0
)
{
data_path
+=
pkg
;
int
app_id
=
to_app_id
(
st
.
st_uid
);
struct
stat
st
{};
if
(
remove
)
{
if
(
stat
(
data_path
.
data
(),
&
st
)
!=
0
)
{
if
(
auto
it
=
app_id_to_pkgs
.
find
(
app_id
);
it
!=
app_id_to_pkgs
.
end
())
{
app_id
=
to_app_id
(
st
.
st_uid
);
it
->
second
.
erase
(
pkg
);
break
;
if
(
it
->
second
.
empty
())
{
app_id_to_pkgs
.
erase
(
it
);
}
}
}
}
else
{
app_id_to_pkgs
[
app_id
].
insert
(
pkg
);
}
}
if
(
app_id
<
0
)
break
;
continue
;
}
for
(
const
auto
&
proc
:
procs
)
{
(
*
app_id_proc_map
)[
app_id
].
emplace_back
(
proc
);
}
}
}
}
}
}
...
@@ -75,7 +124,7 @@ static void rebuild_map() {
...
@@ -75,7 +124,7 @@ static void rebuild_map() {
static
DIR
*
procfp
;
static
DIR
*
procfp
;
template
<
class
F
>
template
<
class
F
>
static
void
crawl_procfs
(
F
&
&
fn
)
{
static
void
crawl_procfs
(
const
F
&
fn
)
{
rewinddir
(
procfp
);
rewinddir
(
procfp
);
dirent
*
dp
;
dirent
*
dp
;
int
pid
;
int
pid
;
...
@@ -149,71 +198,47 @@ static bool validate(const char *pkg, const char *proc) {
...
@@ -149,71 +198,47 @@ static bool validate(const char *pkg, const char *proc) {
return
pkg_valid
&&
proc_valid
;
return
pkg_valid
&&
proc_valid
;
}
}
static
bool
add_hide_set
(
const
char
*
pkg
,
const
char
*
proc
)
{
static
auto
add_hide_set
(
const
char
*
pkg
,
const
char
*
proc
)
{
auto
p
=
deny_map
[
pkg
].
emplace
(
proc
);
auto
p
=
pkg_to_procs
[
pkg
].
emplace
(
proc
);
if
(
!
p
.
second
)
if
(
!
p
.
second
)
return
false
;
return
p
;
LOGI
(
"denylist add: [%s/%s]
\n
"
,
pkg
,
proc
);
LOGI
(
"denylist add: [%s/%s]
\n
"
,
pkg
,
proc
);
if
(
!
do_kill
)
if
(
!
do_kill
)
return
true
;
return
p
;
if
(
str_eql
(
pkg
,
ISOLATED_MAGIC
))
{
if
(
str_eql
(
pkg
,
ISOLATED_MAGIC
))
{
// Kill all matching isolated processes
// Kill all matching isolated processes
kill_process
<&
str_starts
>
(
proc
,
true
);
kill_process
<&
str_starts
>
(
proc
,
true
);
}
else
{
}
else
{
kill_process
(
proc
);
kill_process
(
proc
);
}
}
return
true
;
return
p
;
}
}
static
void
clear_data
()
{
static
void
clear_data
()
{
delete
deny_map_
;
delete
app_ids_seen_
;
delete
app_id_proc_map
;
delete
pkg_to_procs_
;
deny_map_
=
nullptr
;
delete
app_id_to_pkgs_
;
app_id_proc_map
=
nullptr
;
app_ids_seen_
=
nullptr
;
unregister_poll
(
inotify_fd
,
true
);
pkg_to_procs_
=
nullptr
;
inotify_fd
=
-
1
;
app_id_to_pkgs_
=
nullptr
;
}
static
void
inotify_handler
(
pollfd
*
pfd
)
{
union
{
inotify_event
event
;
char
buf
[
512
];
}
u
{};
read
(
pfd
->
fd
,
u
.
buf
,
sizeof
(
u
.
buf
));
if
(
u
.
event
.
name
==
"packages.xml"
sv
)
{
cached_manager_app_id
=
-
1
;
exec_task
([]
{
mutex_guard
lock
(
data_lock
);
rebuild_map
();
});
}
}
}
static
bool
ensure_data
()
{
static
bool
ensure_data
()
{
if
(
app_id
_proc_map
)
if
(
app_id
s_seen_
)
return
true
;
return
true
;
LOGI
(
"denylist: initializing internal data structures
\n
"
);
LOGI
(
"denylist: initializing internal data structures
\n
"
);
default_new
(
deny_map
_
);
default_new
(
pkg_to_procs
_
);
char
*
err
=
db_exec
(
"SELECT * FROM denylist"
,
[](
db_row
&
row
)
->
bool
{
char
*
err
=
db_exec
(
"SELECT * FROM denylist"
,
[](
db_row
&
row
)
->
bool
{
add_hide_set
(
row
[
"package_name"
].
data
(),
row
[
"process"
].
data
());
add_hide_set
(
row
[
"package_name"
].
data
(),
row
[
"process"
].
data
());
return
true
;
return
true
;
});
});
db_err_cmd
(
err
,
goto
error
);
db_err_cmd
(
err
,
goto
error
);
default_new
(
app_id_proc_map
);
default_new
(
app_ids_seen_
);
rebuild_map
();
default_new
(
app_id_to_pkgs_
);
rescan_apps
();
inotify_fd
=
xinotify_init1
(
IN_CLOEXEC
);
if
(
inotify_fd
<
0
)
{
goto
error
;
}
else
{
// Monitor packages.xml
inotify_add_watch
(
inotify_fd
,
"/data/system"
,
IN_CLOSE_WRITE
);
pollfd
inotify_pfd
=
{
inotify_fd
,
POLLIN
,
0
};
register_poll
(
&
inotify_pfd
,
inotify_handler
);
}
return
true
;
return
true
;
...
@@ -233,9 +258,10 @@ static int add_list(const char *pkg, const char *proc) {
...
@@ -233,9 +258,10 @@ static int add_list(const char *pkg, const char *proc) {
mutex_guard
lock
(
data_lock
);
mutex_guard
lock
(
data_lock
);
if
(
!
ensure_data
())
if
(
!
ensure_data
())
return
DAEMON_ERROR
;
return
DAEMON_ERROR
;
if
(
!
add_hide_set
(
pkg
,
proc
))
auto
p
=
add_hide_set
(
pkg
,
proc
);
if
(
!
p
.
second
)
return
DENYLIST_ITEM_EXIST
;
return
DENYLIST_ITEM_EXIST
;
rebuild_map
(
);
update_pkg_uid
(
*
p
.
first
,
false
);
}
}
// Add to database
// Add to database
...
@@ -261,23 +287,25 @@ static int rm_list(const char *pkg, const char *proc) {
...
@@ -261,23 +287,25 @@ static int rm_list(const char *pkg, const char *proc) {
bool
remove
=
false
;
bool
remove
=
false
;
if
(
proc
[
0
]
==
'\0'
)
{
auto
it
=
pkg_to_procs
.
find
(
pkg
);
if
(
deny_map
.
erase
(
pkg
)
!=
0
)
{
if
(
it
!=
pkg_to_procs
.
end
())
{
if
(
proc
[
0
]
==
'\0'
)
{
update_pkg_uid
(
it
->
first
,
true
);
pkg_to_procs
.
erase
(
it
);
remove
=
true
;
remove
=
true
;
LOGI
(
"denylist rm: [%s]
\n
"
,
pkg
);
LOGI
(
"denylist rm: [%s]
\n
"
,
pkg
);
}
}
else
if
(
it
->
second
.
erase
(
proc
)
!=
0
)
{
}
else
{
remove
=
true
;
auto
it
=
deny_map
.
find
(
pkg
);
LOGI
(
"denylist rm: [%s/%s]
\n
"
,
pkg
,
proc
);
if
(
it
!=
deny_map
.
end
())
{
if
(
it
->
second
.
empty
())
{
if
(
it
->
second
.
erase
(
proc
)
!=
0
)
{
update_pkg_uid
(
it
->
first
,
true
);
remove
=
true
;
pkg_to_procs
.
erase
(
it
);
LOGI
(
"denylist rm: [%s/%s]
\n
"
,
pkg
,
proc
);
}
}
}
}
}
}
if
(
!
remove
)
if
(
!
remove
)
return
DENYLIST_ITEM_NOT_EXIST
;
return
DENYLIST_ITEM_NOT_EXIST
;
rebuild_map
();
}
}
char
sql
[
4096
];
char
sql
[
4096
];
...
@@ -307,7 +335,7 @@ void ls_list(int client) {
...
@@ -307,7 +335,7 @@ void ls_list(int client) {
write_int
(
client
,
DAEMON_SUCCESS
);
write_int
(
client
,
DAEMON_SUCCESS
);
for
(
const
auto
&
[
pkg
,
procs
]
:
deny_map
)
{
for
(
const
auto
&
[
pkg
,
procs
]
:
pkg_to_procs
)
{
for
(
const
auto
&
proc
:
procs
)
{
for
(
const
auto
&
proc
:
procs
)
{
write_int
(
client
,
pkg
.
size
()
+
proc
.
size
()
+
1
);
write_int
(
client
,
pkg
.
size
()
+
proc
.
size
()
+
1
);
xwrite
(
client
,
pkg
.
data
(),
pkg
.
size
());
xwrite
(
client
,
pkg
.
data
(),
pkg
.
size
());
...
@@ -374,9 +402,6 @@ int disable_deny() {
...
@@ -374,9 +402,6 @@ int disable_deny() {
if
(
denylist_enforced
)
{
if
(
denylist_enforced
)
{
denylist_enforced
=
false
;
denylist_enforced
=
false
;
LOGI
(
"* Disable DenyList
\n
"
);
LOGI
(
"* Disable DenyList
\n
"
);
mutex_guard
lock
(
data_lock
);
clear_data
();
}
}
update_deny_config
();
update_deny_config
();
return
DAEMON_SUCCESS
;
return
DAEMON_SUCCESS
;
...
@@ -399,21 +424,28 @@ bool is_deny_target(int uid, string_view process) {
...
@@ -399,21 +424,28 @@ bool is_deny_target(int uid, string_view process) {
int
app_id
=
to_app_id
(
uid
);
int
app_id
=
to_app_id
(
uid
);
if
(
app_id
>=
90000
)
{
if
(
app_id
>=
90000
)
{
// Isolated processes
// Isolated processes
auto
it
=
app_id_
proc_map
->
find
(
-
1
);
auto
it
=
app_id_
to_pkgs
.
find
(
-
1
);
if
(
it
==
app_id_
proc_map
->
end
())
if
(
it
==
app_id_
to_pkgs
.
end
())
return
false
;
return
false
;
for
(
const
auto
&
s
:
it
->
second
)
{
for
(
const
auto
&
pkg
:
it
->
second
)
{
if
(
str_starts
(
process
,
s
))
for
(
const
auto
&
s
:
pkg_to_procs
.
find
(
pkg
)
->
second
)
{
return
true
;
if
(
str_starts
(
process
,
s
))
return
true
;
}
}
}
}
else
{
}
else
{
auto
it
=
app_id_proc_map
->
find
(
app_id
);
if
(
!
app_ids_seen
[
app_id
])
{
if
(
it
==
app_id_proc_map
->
end
())
// Found new app ID
return
false
;
cached_manager_app_id
=
-
1
;
rescan_apps
();
}
for
(
const
auto
&
s
:
it
->
second
)
{
auto
it
=
app_id_to_pkgs
.
find
(
app_id
);
if
(
s
==
process
)
if
(
it
==
app_id_to_pkgs
.
end
())
return
false
;
for
(
const
auto
&
pkg
:
it
->
second
)
{
if
(
pkg_to_procs
.
find
(
pkg
)
->
second
.
count
(
process
))
return
true
;
return
true
;
}
}
}
}
...
...
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