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
84ca8e1f
Commit
84ca8e1f
authored
Oct 28, 2017
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Support changing requester in DB
parent
6b7b71b1
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
147 additions
and
169 deletions
+147
-169
activity.c
activity.c
+33
-55
db.c
db.c
+72
-23
su.c
su.c
+6
-19
su.h
su.h
+5
-9
su_daemon.c
su_daemon.c
+25
-58
su_socket.c
su_socket.c
+6
-5
No files found.
activity.c
View file @
84ca8e1f
...
@@ -18,9 +18,8 @@
...
@@ -18,9 +18,8 @@
#include "su.h"
#include "su.h"
/* intent actions */
/* intent actions */
#define ACTION_REQUEST "start", "-n", REQUESTOR "/" REQUESTOR_PREFIX ".RequestActivity"
#define ACTION_REQUEST "%s/" REQUESTOR_PREFIX ".RequestActivity"
#define ACTION_NOTIFY "start", "-n", REQUESTOR "/" REQUESTOR_PREFIX ".NotifyActivity"
#define ACTION_RESULT "%s/" REQUESTOR_PREFIX ".SuReceiver"
#define ACTION_RESULT "broadcast", "-n", REQUESTOR "/" REQUESTOR_PREFIX ".SuReceiver"
#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"
...
@@ -73,30 +72,20 @@ void app_send_result(struct su_context *ctx, policy_t policy) {
...
@@ -73,30 +72,20 @@ void app_send_result(struct su_context *ctx, policy_t policy) {
char
user
[
16
];
char
user
[
16
];
int
notify
=
setup_user
(
ctx
,
user
);
int
notify
=
setup_user
(
ctx
,
user
);
char
activity
[
128
];
sprintf
(
activity
,
ACTION_RESULT
,
ctx
->
path
.
pkg_name
);
// Send notice to manager, enable logging
// Send notice to manager, enable logging
char
*
result_command
[]
=
{
char
*
result_command
[]
=
{
AM_PATH
,
AM_PATH
,
"broadcast"
,
"-n"
,
ACTION_RESULT
,
activity
,
"--user"
,
"--user"
,
user
,
user
,
"--ei"
,
"mode"
,
"0"
,
"--ei"
,
"--ei"
,
"from.uid"
,
fromUid
,
"mode"
,
"--ei"
,
"to.uid"
,
toUid
,
"0"
,
"--ei"
,
"pid"
,
pid
,
"--ei"
,
"--es"
,
"command"
,
get_command
(
&
ctx
->
to
),
"from.uid"
,
"--es"
,
"action"
,
policy
==
ALLOW
?
"allow"
:
"deny"
,
fromUid
,
"--ei"
,
"to.uid"
,
toUid
,
"--ei"
,
"pid"
,
pid
,
"--es"
,
"command"
,
get_command
(
&
ctx
->
to
),
"--es"
,
"action"
,
policy
==
ALLOW
?
"allow"
:
"deny"
,
NULL
NULL
};
};
silent_run
(
result_command
);
silent_run
(
result_command
);
...
@@ -105,19 +94,12 @@ void app_send_result(struct su_context *ctx, policy_t policy) {
...
@@ -105,19 +94,12 @@ void app_send_result(struct su_context *ctx, policy_t policy) {
if
(
notify
)
{
if
(
notify
)
{
sprintf
(
user
,
"%d"
,
notify
);
sprintf
(
user
,
"%d"
,
notify
);
char
*
notify_command
[]
=
{
char
*
notify_command
[]
=
{
AM_PATH
,
AM_PATH
,
"broadcast"
,
"-n"
,
ACTION_RESULT
,
activity
,
"--user"
,
"--user"
,
user
,
user
,
"--ei"
,
"mode"
,
"1"
,
"--ei"
,
"--ei"
,
"from.uid"
,
fromUid
,
"mode"
,
"--es"
,
"action"
,
policy
==
ALLOW
?
"allow"
:
"deny"
,
"1"
,
"--ei"
,
"from.uid"
,
fromUid
,
"--es"
,
"action"
,
policy
==
ALLOW
?
"allow"
:
"deny"
,
NULL
NULL
};
};
silent_run
(
notify_command
);
silent_run
(
notify_command
);
...
@@ -128,17 +110,15 @@ void app_send_request(struct su_context *ctx) {
...
@@ -128,17 +110,15 @@ void app_send_request(struct su_context *ctx) {
char
user
[
16
];
char
user
[
16
];
int
notify
=
setup_user
(
ctx
,
user
);
int
notify
=
setup_user
(
ctx
,
user
);
char
activity
[
128
];
sprintf
(
activity
,
ACTION_REQUEST
,
ctx
->
path
.
pkg_name
);
char
*
request_command
[]
=
{
char
*
request_command
[]
=
{
AM_PATH
,
AM_PATH
,
"start"
,
"-n"
,
ACTION_REQUEST
,
activity
,
"--user"
,
"--user"
,
user
,
user
,
"--es"
,
"socket"
,
ctx
->
path
.
sock_path
,
"--es"
,
"--ez"
,
"timeout"
,
notify
?
"false"
:
"true"
,
"socket"
,
ctx
->
path
.
sock_path
,
"--ez"
,
"timeout"
,
notify
?
"false"
:
"true"
,
NULL
NULL
};
};
silent_run
(
request_command
);
silent_run
(
request_command
);
...
@@ -146,14 +126,12 @@ void app_send_request(struct su_context *ctx) {
...
@@ -146,14 +126,12 @@ void app_send_request(struct su_context *ctx) {
// Send notice to user to tell them root is managed by owner
// Send notice to user to tell them root is managed by owner
if
(
notify
)
{
if
(
notify
)
{
sprintf
(
user
,
"%d"
,
notify
);
sprintf
(
user
,
"%d"
,
notify
);
sprintf
(
activity
,
ACTION_RESULT
,
ctx
->
path
.
pkg_name
);
char
*
notify_command
[]
=
{
char
*
notify_command
[]
=
{
AM_PATH
,
AM_PATH
,
"broadcast"
,
"-n"
,
ACTION_RESULT
,
activity
,
"--user"
,
"--user"
,
user
,
user
,
"--ei"
,
"mode"
,
"2"
,
"--ei"
,
"mode"
,
"2"
,
NULL
NULL
};
};
silent_run
(
notify_command
);
silent_run
(
notify_command
);
...
...
db.c
View file @
84ca8e1f
...
@@ -58,60 +58,109 @@ static int settings_callback(void *v, int argc, char **argv, char **azColName) {
...
@@ -58,60 +58,109 @@ static int settings_callback(void *v, int argc, char **argv, char **azColName) {
return
0
;
return
0
;
}
}
static
int
strings_callback
(
void
*
v
,
int
argc
,
char
**
argv
,
char
**
azColName
)
{
struct
su_context
*
ctx
=
(
struct
su_context
*
)
v
;
char
*
entry
,
*
target
,
*
value
;
for
(
int
i
=
0
;
i
<
argc
;
++
i
)
{
if
(
strcmp
(
azColName
[
i
],
"key"
)
==
0
)
{
if
(
strcmp
(
argv
[
i
],
REQUESTER_ENTRY
)
==
0
)
target
=
ctx
->
path
.
pkg_name
;
entry
=
argv
[
i
];
}
else
if
(
strcmp
(
azColName
[
i
],
"value"
)
==
0
)
{
value
=
argv
[
i
];
}
}
LOGD
(
"su_db: query %s=[%s]
\n
"
,
entry
,
value
);
strcpy
(
target
,
value
);
return
0
;
}
#define BASE_FMT "/data/user%s/%d"
#define USE_MULTI(info) (info->uid / 100000 != 0 && info->multiuser_mode == MULTIUSER_MODE_USER)
void
database_check
(
struct
su_context
*
ctx
)
{
void
database_check
(
struct
su_context
*
ctx
)
{
sqlite3
*
db
=
NULL
;
sqlite3
*
db
=
NULL
;
int
ret
;
int
ret
;
char
query
[
512
],
*
err
=
NULL
;
char
buffer
[
PATH_MAX
],
*
err
=
NULL
;
// Set default values
// Set default values
ctx
->
info
->
root_access
=
ROOT_ACCESS_APPS_AND_ADB
;
ctx
->
info
->
root_access
=
ROOT_ACCESS_APPS_AND_ADB
;
ctx
->
info
->
multiuser_mode
=
MULTIUSER_MODE_OWNER_ONLY
;
ctx
->
info
->
multiuser_mode
=
MULTIUSER_MODE_OWNER_ONLY
;
ctx
->
info
->
mnt_ns
=
NAMESPACE_MODE_REQUESTER
;
ctx
->
info
->
mnt_ns
=
NAMESPACE_MODE_REQUESTER
;
ctx
->
info
->
policy
=
QUERY
;
strcpy
(
ctx
->
path
.
pkg_name
,
"???"
);
/* bad string so it doesn't exist */
// Populate paths
sprintf
(
ctx
->
path
.
base_path
,
BASE_FMT
,
"_de"
,
0
);
if
(
access
(
ctx
->
path
.
base_path
,
R_OK
)
==
-
1
)
sprintf
(
ctx
->
path
.
base_path
,
BASE_FMT
,
""
,
0
);
sprintf
(
ctx
->
path
.
multiuser_path
,
BASE_FMT
,
"_de"
,
ctx
->
info
->
uid
/
100000
);
if
(
access
(
ctx
->
path
.
multiuser_path
,
R_OK
)
==
-
1
)
sprintf
(
ctx
->
path
.
multiuser_path
,
BASE_FMT
,
""
,
ctx
->
info
->
uid
/
100000
);
// Open database
// Open database
ret
=
sqlite3_open_v2
(
ctx
->
path
.
base_db
,
&
db
,
SQLITE_OPEN_READONLY
,
NULL
);
sprintf
(
buffer
,
"%s/magisk.db"
,
ctx
->
path
.
base_path
);
LOGD
(
"su_db: open %s"
,
buffer
);
ret
=
sqlite3_open_v2
(
buffer
,
&
db
,
SQLITE_OPEN_READONLY
,
NULL
);
if
(
ret
)
{
if
(
ret
)
{
LOGD
(
"sqlite3 open failure: %s
\n
"
,
sqlite3_errstr
(
ret
));
LOGD
(
"sqlite3 open failure: %s
\n
"
,
sqlite3_errstr
(
ret
));
sqlite3_close
(
db
);
sqlite3_close
(
db
);
return
;
goto
stat_requester
;
}
}
// Check multiuser mode settings
// Check multiuser mode settings
snprintf
(
query
,
sizeof
(
query
),
"SELECT key, value FROM settings WHERE key='%s'"
,
MULTIUSER_MODE_ENTRY
);
sprintf
(
buffer
,
"SELECT key, value FROM settings WHERE key='%s'"
,
MULTIUSER_MODE_ENTRY
);
sqlite3_exec
(
db
,
query
,
settings_callback
,
ctx
,
&
err
);
sqlite3_exec
(
db
,
buffer
,
settings_callback
,
ctx
,
&
err
);
if
(
err
!=
NULL
)
LOGE
(
"sqlite3_exec: %s
\n
"
,
err
);
err
=
NULL
;
err
=
NULL
;
if
(
ctx
->
info
->
uid
/
100000
!=
0
&&
ctx
->
info
->
multiuser_mode
==
MULTIUSER_MODE_USER
)
{
// Open database based on multiuser settings
if
(
USE_MULTI
(
ctx
->
info
))
{
sqlite3_close
(
db
);
sqlite3_close
(
db
);
sprintf
(
buffer
,
"%s/magisk.db"
,
ctx
->
path
.
multiuser_path
);
// Open database
LOGD
(
"su_db: open %s"
,
buffer
);
ret
=
sqlite3_open_v2
(
ctx
->
path
.
multiuser_db
,
&
db
,
SQLITE_OPEN_READONLY
,
NULL
);
ret
=
sqlite3_open_v2
(
buffer
,
&
db
,
SQLITE_OPEN_READONLY
,
NULL
);
if
(
ret
)
{
if
(
ret
)
{
LOGD
(
"sqlite3 open failure: %s
\n
"
,
sqlite3_errstr
(
ret
));
LOGD
(
"sqlite3 open failure: %s
\n
"
,
sqlite3_errstr
(
ret
));
sqlite3_close
(
db
);
sqlite3_close
(
db
);
return
;
goto
stat_requester
;
}
}
}
}
//
Query for policy
//
Read PKG name from DB
s
nprintf
(
query
,
sizeof
(
query
),
"SELECT policy, until FROM policies WHERE uid=%d"
,
ctx
->
info
->
uid
%
100000
);
s
trcpy
(
buffer
,
"SELECT key, value FROM strings"
);
sqlite3_exec
(
db
,
query
,
policy
_callback
,
ctx
,
&
err
);
sqlite3_exec
(
db
,
buffer
,
strings
_callback
,
ctx
,
&
err
);
if
(
err
!=
NULL
)
{
if
(
err
!=
NULL
)
LOGE
(
"sqlite3_exec: %s
\n
"
,
err
);
LOGE
(
"sqlite3_exec: %s
\n
"
,
err
);
return
;
err
=
NULL
;
}
// Query for policy
sprintf
(
buffer
,
"SELECT policy, until FROM policies WHERE uid=%d"
,
ctx
->
info
->
uid
%
100000
);
sqlite3_exec
(
db
,
buffer
,
policy_callback
,
ctx
,
&
err
);
if
(
err
!=
NULL
)
LOGE
(
"sqlite3_exec: %s
\n
"
,
err
);
err
=
NULL
;
err
=
NULL
;
// Query for settings
// Query for settings
s
nprintf
(
query
,
sizeof
(
query
)
,
"SELECT key, value FROM settings WHERE key!='%s'"
,
MULTIUSER_MODE_ENTRY
);
s
printf
(
buffer
,
"SELECT key, value FROM settings WHERE key!='%s'"
,
MULTIUSER_MODE_ENTRY
);
sqlite3_exec
(
db
,
query
,
settings_callback
,
ctx
,
&
err
);
sqlite3_exec
(
db
,
buffer
,
settings_callback
,
ctx
,
&
err
);
if
(
err
!=
NULL
)
{
if
(
err
!=
NULL
)
LOGE
(
"sqlite3_exec: %s
\n
"
,
err
);
LOGE
(
"sqlite3_exec: %s
\n
"
,
err
);
return
;
}
sqlite3_close
(
db
);
sqlite3_close
(
db
);
stat_requester:
// We prefer the orignal name
sprintf
(
buffer
,
"%s/%s"
,
USE_MULTI
(
ctx
->
info
)
?
ctx
->
path
.
multiuser_path
:
ctx
->
path
.
base_path
,
JAVA_PACKAGE_NAME
);
if
(
stat
(
buffer
,
&
ctx
->
st
)
==
-
1
)
{
sprintf
(
buffer
,
"%s/%s"
,
USE_MULTI
(
ctx
->
info
)
?
ctx
->
path
.
multiuser_path
:
ctx
->
path
.
base_path
,
ctx
->
path
.
pkg_name
);
if
(
stat
(
buffer
,
&
ctx
->
st
)
==
-
1
)
{
LOGE
(
"su: cannot find requester"
);
ctx
->
info
->
policy
=
DENY
;
ctx
->
notify
=
0
;
}
}
else
{
strcpy
(
ctx
->
path
.
pkg_name
,
JAVA_PACKAGE_NAME
);
}
}
}
su.c
View file @
84ca8e1f
...
@@ -162,9 +162,9 @@ static void cleanup_signal(int sig) {
...
@@ -162,9 +162,9 @@ static void cleanup_signal(int sig) {
__attribute__
((
noreturn
))
void
exit2
(
int
status
)
{
__attribute__
((
noreturn
))
void
exit2
(
int
status
)
{
// Handle the pipe, or the daemon will get stuck
// Handle the pipe, or the daemon will get stuck
if
(
su_ctx
->
info
->
policy
==
QUERY
)
{
if
(
su_ctx
->
info
->
policy
==
QUERY
)
{
xwrite
(
pipefd
[
1
],
&
su_ctx
->
info
->
policy
,
sizeof
(
su_ctx
->
info
->
policy
));
xwrite
(
su_ctx
->
pipefd
[
1
],
&
su_ctx
->
info
->
policy
,
sizeof
(
su_ctx
->
info
->
policy
));
close
(
pipefd
[
0
]);
close
(
su_ctx
->
pipefd
[
0
]);
close
(
pipefd
[
1
]);
close
(
su_ctx
->
pipefd
[
1
]);
}
}
exit
(
status
);
exit
(
status
);
}
}
...
@@ -352,19 +352,6 @@ int su_daemon_main(int argc, char **argv) {
...
@@ -352,19 +352,6 @@ int su_daemon_main(int argc, char **argv) {
// New request or no db exist, notify user for response
// New request or no db exist, notify user for response
if
(
su_ctx
->
info
->
policy
==
QUERY
)
{
if
(
su_ctx
->
info
->
policy
==
QUERY
)
{
mkdir
(
REQUESTOR_CACHE_PATH
,
0770
);
if
(
chown
(
REQUESTOR_CACHE_PATH
,
su_ctx
->
st
.
st_uid
,
su_ctx
->
st
.
st_gid
))
PLOGE
(
"chown (%s, %u, %u)"
,
REQUESTOR_CACHE_PATH
,
su_ctx
->
st
.
st_uid
,
su_ctx
->
st
.
st_gid
);
if
(
setgroups
(
0
,
NULL
))
PLOGE
(
"setgroups"
);
if
(
setegid
(
su_ctx
->
st
.
st_gid
))
PLOGE
(
"setegid (%u)"
,
su_ctx
->
st
.
st_gid
);
if
(
seteuid
(
su_ctx
->
st
.
st_uid
))
PLOGE
(
"seteuid (%u)"
,
su_ctx
->
st
.
st_uid
);
socket_serv_fd
=
socket_create_temp
(
su_ctx
->
path
.
sock_path
,
sizeof
(
su_ctx
->
path
.
sock_path
));
socket_serv_fd
=
socket_create_temp
(
su_ctx
->
path
.
sock_path
,
sizeof
(
su_ctx
->
path
.
sock_path
));
setup_sighandlers
(
cleanup_signal
);
setup_sighandlers
(
cleanup_signal
);
...
@@ -387,9 +374,9 @@ int su_daemon_main(int argc, char **argv) {
...
@@ -387,9 +374,9 @@ int su_daemon_main(int argc, char **argv) {
su_ctx
->
info
->
policy
=
DENY
;
su_ctx
->
info
->
policy
=
DENY
;
// Report the policy to main daemon
// Report the policy to main daemon
xwrite
(
pipefd
[
1
],
&
su_ctx
->
info
->
policy
,
sizeof
(
su_ctx
->
info
->
policy
));
xwrite
(
su_ctx
->
pipefd
[
1
],
&
su_ctx
->
info
->
policy
,
sizeof
(
su_ctx
->
info
->
policy
));
close
(
pipefd
[
0
]);
close
(
su_ctx
->
pipefd
[
0
]);
close
(
pipefd
[
1
]);
close
(
su_ctx
->
pipefd
[
1
]);
}
}
if
(
su_ctx
->
info
->
policy
==
ALLOW
)
if
(
su_ctx
->
info
->
policy
==
ALLOW
)
...
...
su.h
View file @
84ca8e1f
...
@@ -31,17 +31,14 @@
...
@@ -31,17 +31,14 @@
#define NAMESPACE_MODE_REQUESTER 1
#define NAMESPACE_MODE_REQUESTER 1
#define NAMESPACE_MODE_ISOLATE 2
#define NAMESPACE_MODE_ISOLATE 2
// DB entry for requester
#define REQUESTER_ENTRY "requester"
// DO NOT CHANGE LINE BELOW, java package name will always be the same
// DO NOT CHANGE LINE BELOW, java package name will always be the same
#define JAVA_PACKAGE_NAME "com.topjohnwu.magisk"
#define JAVA_PACKAGE_NAME "com.topjohnwu.magisk"
// If --rename-manifest-package is used in AAPT, this
// must be changed to correspond to the new APK package name
// See the two Android.mk files for more details.
#define REQUESTOR JAVA_PACKAGE_NAME
// This is used if wrapping the fragment classes and activities
// This is used if wrapping the fragment classes and activities
// with classes in another package.
// with classes in another package.
#define REQUESTOR_PREFIX JAVA_PACKAGE_NAME ".superuser"
#define REQUESTOR_PREFIX JAVA_PACKAGE_NAME ".superuser"
#define REQUESTOR_CACHE_PATH "/dev/" REQUESTOR
#define DEFAULT_SHELL "/system/bin/sh"
#define DEFAULT_SHELL "/system/bin/sh"
...
@@ -80,9 +77,8 @@ struct su_request {
...
@@ -80,9 +77,8 @@ struct su_request {
struct
su_path
{
struct
su_path
{
char
base_path
[
PATH_MAX
];
char
base_path
[
PATH_MAX
];
char
base_db
[
PATH_MAX
];
char
multiuser_path
[
PATH_MAX
];
char
multiuser_path
[
PATH_MAX
];
char
multiuser_db
[
PATH_MAX
];
char
pkg_name
[
PATH_MAX
];
char
sock_path
[
PATH_MAX
];
char
sock_path
[
PATH_MAX
];
};
};
...
@@ -95,10 +91,10 @@ struct su_context {
...
@@ -95,10 +91,10 @@ struct su_context {
mode_t
umask
;
mode_t
umask
;
char
*
cwd
;
char
*
cwd
;
struct
stat
st
;
struct
stat
st
;
int
pipefd
[
2
];
};
};
extern
struct
su_context
*
su_ctx
;
extern
struct
su_context
*
su_ctx
;
extern
int
pipefd
[
2
];
// su.c
// su.c
...
...
su_daemon.c
View file @
84ca8e1f
...
@@ -90,28 +90,6 @@ static void *collector(void *args) {
...
@@ -90,28 +90,6 @@ static void *collector(void *args) {
}
}
}
}
#define BASE_FMT "/data/user%s/%d/" REQUESTOR
#define DB_FMT BASE_FMT "/databases/su.db"
#define CAT_PATH(dest, fmt, ...) snprintf(dest, sizeof(dest), fmt, __VA_ARGS__)
static
void
populate_paths
(
struct
su_context
*
ctx
)
{
CAT_PATH
(
ctx
->
path
.
base_path
,
BASE_FMT
,
"_de"
,
0
);
if
(
access
(
ctx
->
path
.
base_path
,
R_OK
)
==
-
1
)
CAT_PATH
(
ctx
->
path
.
base_path
,
BASE_FMT
,
""
,
0
);
CAT_PATH
(
ctx
->
path
.
base_db
,
DB_FMT
,
"_de"
,
0
);
if
(
access
(
ctx
->
path
.
base_db
,
R_OK
)
==
-
1
)
CAT_PATH
(
ctx
->
path
.
base_db
,
DB_FMT
,
""
,
0
);
CAT_PATH
(
ctx
->
path
.
multiuser_path
,
BASE_FMT
,
"_de"
,
ctx
->
info
->
uid
/
100000
);
if
(
access
(
ctx
->
path
.
multiuser_path
,
R_OK
)
==
-
1
)
CAT_PATH
(
ctx
->
path
.
multiuser_path
,
BASE_FMT
,
""
,
ctx
->
info
->
uid
/
100000
);
CAT_PATH
(
ctx
->
path
.
multiuser_db
,
DB_FMT
,
"_de"
,
ctx
->
info
->
uid
/
100000
);
if
(
access
(
ctx
->
path
.
multiuser_db
,
R_OK
)
==
-
1
)
CAT_PATH
(
ctx
->
path
.
multiuser_db
,
DB_FMT
,
""
,
ctx
->
info
->
uid
/
100000
);
}
void
su_daemon_receiver
(
int
client
)
{
void
su_daemon_receiver
(
int
client
)
{
LOGD
(
"su: request from client: %d
\n
"
,
client
);
LOGD
(
"su: request from client: %d
\n
"
,
client
);
...
@@ -170,16 +148,6 @@ void su_daemon_receiver(int client) {
...
@@ -170,16 +148,6 @@ void su_daemon_receiver(int client) {
.
umask
=
022
,
.
umask
=
022
,
.
notify
=
new_request
,
.
notify
=
new_request
,
};
};
su_ctx
=
&
ctx
;
populate_paths
(
su_ctx
);
// Check main Magisk Manager
xstat
(
su_ctx
->
path
.
base_path
,
&
su_ctx
->
st
);
if
(
su_ctx
->
st
.
st_gid
!=
su_ctx
->
st
.
st_uid
)
{
LOGE
(
"Bad uid/gid %d/%d for Superuser Requestor application"
,
su_ctx
->
st
.
st_uid
,
su_ctx
->
st
.
st_gid
);
info
->
policy
=
DENY
;
}
// Lock before the policy is determined
// Lock before the policy is determined
LOCK_UID
();
LOCK_UID
();
...
@@ -187,41 +155,38 @@ void su_daemon_receiver(int client) {
...
@@ -187,41 +155,38 @@ void su_daemon_receiver(int client) {
// Not cached, do the checks
// Not cached, do the checks
if
(
info
->
policy
==
QUERY
)
{
if
(
info
->
policy
==
QUERY
)
{
// Get data from database
// Get data from database
database_check
(
su_ctx
);
database_check
(
&
ctx
);
if
(
su_ctx
->
info
->
multiuser_mode
==
MULTIUSER_MODE_USER
)
{
// Check the user installed Magisk Manager
xstat
(
su_ctx
->
path
.
multiuser_path
,
&
su_ctx
->
st
);
if
(
su_ctx
->
st
.
st_gid
!=
su_ctx
->
st
.
st_uid
)
{
LOGE
(
"Bad uid/gid %d/%d for Superuser Requestor application"
,
su_ctx
->
st
.
st_uid
,
su_ctx
->
st
.
st_gid
);
info
->
policy
=
DENY
;
}
}
// Handle multiuser denies
// Handle multiuser denies
if
(
su_ctx
->
info
->
uid
/
100000
&&
if
(
info
->
uid
/
100000
&&
su_ctx
->
info
->
multiuser_mode
==
MULTIUSER_MODE_OWNER_ONLY
)
{
info
->
multiuser_mode
==
MULTIUSER_MODE_OWNER_ONLY
)
{
info
->
policy
=
DENY
;
info
->
policy
=
DENY
;
su_ctx
->
notify
=
0
;
ctx
.
notify
=
0
;
}
}
// always allow if this is Magisk Manager
// Check requester
if
(
info
->
policy
==
QUERY
&&
(
info
->
uid
%
100000
)
==
(
su_ctx
->
st
.
st_uid
%
100000
))
{
if
(
info
->
policy
==
QUERY
)
{
info
->
policy
=
ALLOW
;
if
(
ctx
.
st
.
st_gid
!=
ctx
.
st
.
st_uid
)
{
info
->
root_access
=
ROOT_ACCESS_APPS_AND_ADB
;
LOGE
(
"Bad uid/gid %d/%d for Superuser Requestor"
,
ctx
.
st
.
st_uid
,
ctx
.
st
.
st_gid
);
su_ctx
->
notify
=
0
;
info
->
policy
=
DENY
;
ctx
.
notify
=
0
;
}
else
if
((
info
->
uid
%
100000
)
==
(
ctx
.
st
.
st_uid
%
100000
))
{
info
->
policy
=
ALLOW
;
info
->
root_access
=
ROOT_ACCESS_APPS_AND_ADB
;
ctx
.
notify
=
0
;
}
}
}
// always allow if it's root
// always allow if it's root
if
(
info
->
uid
==
UID_ROOT
)
{
if
(
info
->
uid
==
UID_ROOT
)
{
info
->
policy
=
ALLOW
;
info
->
policy
=
ALLOW
;
info
->
root_access
=
ROOT_ACCESS_APPS_AND_ADB
;
info
->
root_access
=
ROOT_ACCESS_APPS_AND_ADB
;
su_ctx
->
notify
=
0
;
ctx
.
notify
=
0
;
}
}
// If still not determined, open a pipe and wait for results
// If still not determined, open a pipe and wait for results
if
(
info
->
policy
==
QUERY
)
if
(
info
->
policy
==
QUERY
)
xpipe2
(
pipefd
,
O_CLOEXEC
);
xpipe2
(
ctx
.
pipefd
,
O_CLOEXEC
);
}
}
// Fork a new process, the child process will need to setsid,
// Fork a new process, the child process will need to setsid,
...
@@ -235,9 +200,9 @@ void su_daemon_receiver(int client) {
...
@@ -235,9 +200,9 @@ void su_daemon_receiver(int client) {
if
(
child
)
{
if
(
child
)
{
// Wait for results
// Wait for results
if
(
info
->
policy
==
QUERY
)
{
if
(
info
->
policy
==
QUERY
)
{
xxread
(
pipefd
[
0
],
&
info
->
policy
,
sizeof
(
info
->
policy
));
xxread
(
ctx
.
pipefd
[
0
],
&
info
->
policy
,
sizeof
(
info
->
policy
));
close
(
pipefd
[
0
]);
close
(
ctx
.
pipefd
[
0
]);
close
(
pipefd
[
1
]);
close
(
ctx
.
pipefd
[
1
]);
}
}
// The policy is determined, unlock
// The policy is determined, unlock
...
@@ -308,8 +273,8 @@ void su_daemon_receiver(int client) {
...
@@ -308,8 +273,8 @@ void su_daemon_receiver(int client) {
}
}
// Get cwd
// Get cwd
su_ctx
->
cwd
=
read_string
(
client
);
ctx
.
cwd
=
read_string
(
client
);
LOGD
(
"su: cwd=[%s]
\n
"
,
su_ctx
->
cwd
);
LOGD
(
"su: cwd=[%s]
\n
"
,
ctx
.
cwd
);
// Get pts_slave
// Get pts_slave
char
*
pts_slave
=
read_string
(
client
);
char
*
pts_slave
=
read_string
(
client
);
...
@@ -330,7 +295,7 @@ void su_daemon_receiver(int client) {
...
@@ -330,7 +295,7 @@ void su_daemon_receiver(int client) {
xstat
(
pts_slave
,
&
stbuf
);
xstat
(
pts_slave
,
&
stbuf
);
//If caller is not root, ensure the owner of pts_slave is the caller
//If caller is not root, ensure the owner of pts_slave is the caller
if
(
stbuf
.
st_uid
!=
credential
.
uid
&&
credential
.
uid
!=
0
)
{
if
(
stbuf
.
st_uid
!=
info
->
uid
&&
info
->
uid
!=
0
)
{
LOGE
(
"su: Wrong permission of pts_slave"
);
LOGE
(
"su: Wrong permission of pts_slave"
);
exit2
(
1
);
exit2
(
1
);
}
}
...
@@ -363,6 +328,8 @@ void su_daemon_receiver(int client) {
...
@@ -363,6 +328,8 @@ void su_daemon_receiver(int client) {
close
(
ptsfd
);
close
(
ptsfd
);
// Give main the reference
su_ctx
=
&
ctx
;
su_daemon_main
(
argc
,
argv
);
su_daemon_main
(
argc
,
argv
);
}
}
...
...
su_socket.c
View file @
84ca8e1f
...
@@ -29,21 +29,22 @@ int socket_create_temp(char *path, size_t len) {
...
@@ -29,21 +29,22 @@ int socket_create_temp(char *path, size_t len) {
memset
(
&
sun
,
0
,
sizeof
(
sun
));
memset
(
&
sun
,
0
,
sizeof
(
sun
));
sun
.
sun_family
=
AF_LOCAL
;
sun
.
sun_family
=
AF_LOCAL
;
snprintf
(
path
,
len
,
"
%s/.socket%d"
,
REQUESTOR_CACHE_PATH
,
(
int
)
syscall
(
SYS_gettid
));
snprintf
(
path
,
len
,
"
/dev/.socket%d"
,
(
int
)
syscall
(
SYS_gettid
));
s
nprintf
(
sun
.
sun_path
,
sizeof
(
sun
.
sun_path
),
"%s"
,
path
);
s
trcpy
(
sun
.
sun_path
,
path
);
/*
/*
* Delete the socket to protect from situations when
* Delete the socket to protect from situations when
* something bad occured previously and the kernel reused pid from that process.
* something bad occured previously and the kernel reused pid from that process.
* Small probability, isn't it.
* Small probability, isn't it.
*/
*/
unlink
(
sun
.
sun_
path
);
unlink
(
path
);
xbind
(
fd
,
(
struct
sockaddr
*
)
&
sun
,
sizeof
(
sun
));
xbind
(
fd
,
(
struct
sockaddr
*
)
&
sun
,
sizeof
(
sun
));
xlisten
(
fd
,
1
);
xlisten
(
fd
,
1
);
// Set context to su_device, so apps can access it
// Set attributes so requester can access it
setfilecon
(
sun
.
sun_path
,
"u:object_r:su_device:s0"
);
setfilecon
(
path
,
"u:object_r:su_device:s0"
);
chown
(
path
,
su_ctx
->
st
.
st_uid
,
su_ctx
->
st
.
st_gid
);
return
fd
;
return
fd
;
}
}
...
...
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