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
e3a4a165
Commit
e3a4a165
authored
Jan 23, 2017
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Adapt su to Magisk
parent
ef1d1303
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
33 additions
and
96 deletions
+33
-96
daemon.c
daemon.c
+12
-24
db.c
db.c
+13
-34
su.c
su.c
+1
-22
su.h
su.h
+7
-16
No files found.
daemon.c
View file @
e3a4a165
...
...
@@ -445,7 +445,7 @@ static int daemon_accept(int fd) {
}
int
run_daemon
()
{
if
(
getuid
()
!=
0
||
getgid
()
!=
0
)
{
if
(
getuid
()
!=
AID_ROOT
||
getgid
()
!=
AID_ROOT
)
{
PLOGE
(
"daemon requires root. uid/gid not root"
);
return
-
1
;
}
...
...
@@ -455,13 +455,19 @@ int run_daemon() {
break
;
case
-
1
:
PLOGE
(
"fork"
);
return
1
;
return
-
1
;
default:
return
0
;
}
if
(
setsid
()
<
0
||
setcon
(
"u:r:su_daemon:s0"
)
<
0
)
return
1
;
if
(
setsid
()
<
0
)
{
PLOGE
(
"setsid"
);
return
-
1
;
}
if
(
setcon
(
"u:r:su_daemon:s0"
)
<
0
)
{
PLOGE
(
"setcon"
);
return
-
1
;
}
int
fd
;
struct
sockaddr_un
sun
;
...
...
@@ -478,32 +484,17 @@ int run_daemon() {
memset
(
&
sun
,
0
,
sizeof
(
sun
));
sun
.
sun_family
=
AF_LOCAL
;
s
printf
(
sun
.
sun_path
,
"%s/server"
,
REQUESTOR_DAEMON_PATH
);
s
trcpy
(
sun
.
sun_path
,
REQUESTOR_DAEMON_PATH
);
/*
* Delete the socket to protect from situations when
* something bad occured previously and the kernel reused pid from that process.
* Small probability, isn't it.
*/
unlink
(
sun
.
sun_path
);
unlink
(
REQUESTOR_DAEMON_PATH
);
int
previous_umask
=
umask
(
027
);
mkdir
(
REQUESTOR_DAEMON_PATH
,
0777
);
memset
(
sun
.
sun_path
,
0
,
sizeof
(
sun
.
sun_path
));
memcpy
(
sun
.
sun_path
,
"
\0
"
"SUPERUSER"
,
strlen
(
"SUPERUSER"
)
+
1
);
if
(
bind
(
fd
,
(
struct
sockaddr
*
)
&
sun
,
sizeof
(
sun
))
<
0
)
{
PLOGE
(
"daemon bind"
);
goto
err
;
}
chmod
(
REQUESTOR_DAEMON_PATH
,
0755
);
chmod
(
sun
.
sun_path
,
0777
);
umask
(
previous_umask
);
if
(
listen
(
fd
,
10
)
<
0
)
{
PLOGE
(
"daemon listen"
);
goto
err
;
...
...
@@ -600,10 +591,7 @@ int connect_daemon(int argc, char *argv[], int ppid) {
memset
(
&
sun
,
0
,
sizeof
(
sun
));
sun
.
sun_family
=
AF_LOCAL
;
sprintf
(
sun
.
sun_path
,
"%s/server"
,
REQUESTOR_DAEMON_PATH
);
memset
(
sun
.
sun_path
,
0
,
sizeof
(
sun
.
sun_path
));
memcpy
(
sun
.
sun_path
,
"
\0
"
"SUPERUSER"
,
strlen
(
"SUPERUSER"
)
+
1
);
strcpy
(
sun
.
sun_path
,
REQUESTOR_DAEMON_PATH
);
if
(
0
!=
connect
(
socketfd
,
(
struct
sockaddr
*
)
&
sun
,
sizeof
(
sun
)))
{
PLOGE
(
"connect"
);
...
...
db.c
View file @
e3a4a165
...
...
@@ -29,50 +29,30 @@ struct callback_data_t {
static
int
database_callback
(
void
*
v
,
int
argc
,
char
**
argv
,
char
**
azColName
){
struct
callback_data_t
*
data
=
(
struct
callback_data_t
*
)
v
;
int
command_match
=
0
;
policy_t
policy
=
DENY
;
policy_t
policy
=
INTERACTIVE
;
int
i
;
time_t
until
=
0
;
for
(
i
=
0
;
i
<
argc
;
i
++
)
{
if
(
strcmp
(
azColName
[
i
],
"policy"
)
==
0
)
{
if
(
argv
[
i
]
==
NULL
)
{
policy
=
DENY
;
}
if
(
strcmp
(
argv
[
i
],
"allow"
)
==
0
)
{
policy
=
ALLOW
;
}
else
if
(
strcmp
(
argv
[
i
],
"interactive"
)
==
0
)
{
policy
=
INTERACTIVE
;
}
else
{
policy
=
DENY
;
}
if
(
argv
[
i
]
!=
NULL
)
{
policy
=
atoi
(
argv
[
i
]);
}
else
if
(
strcmp
(
azColName
[
i
],
"command"
)
==
0
)
{
// null or empty command means to match all commands (whitelist all from uid)
command_match
=
argv
[
i
]
==
NULL
||
strlen
(
argv
[
i
])
==
0
||
strcmp
(
argv
[
i
],
get_command
(
&
(
data
->
ctx
->
to
)))
==
0
;
}
else
if
(
strcmp
(
azColName
[
i
],
"until"
)
==
0
)
{
if
(
argv
[
i
]
!=
NULL
)
{
until
=
ato
i
(
argv
[
i
]);
until
=
ato
l
(
argv
[
i
]);
}
}
}
// check for command match
if
(
command_match
)
{
// also make sure this policy has not expired
if
(
until
==
0
||
until
>
time
(
NULL
))
{
if
(
policy
==
DENY
)
{
data
->
policy
=
DENY
;
return
-
1
;
}
}
else
if
(
policy
==
ALLOW
&&
(
until
==
0
||
until
>
time
(
NULL
)))
{
data
->
policy
=
ALLOW
;
// even though we allow, continue, so we can see if there's another policy
// that denies...
}
}
return
0
;
}
...
...
@@ -81,7 +61,7 @@ policy_t database_check(struct su_context *ctx) {
sqlite3
*
db
=
NULL
;
char
query
[
512
];
snprintf
(
query
,
sizeof
(
query
),
"select policy, until
, command from uid_policy
where uid=%d"
,
ctx
->
from
.
uid
);
snprintf
(
query
,
sizeof
(
query
),
"select policy, until
from policies
where uid=%d"
,
ctx
->
from
.
uid
);
int
ret
=
sqlite3_open_v2
(
ctx
->
user
.
database_path
,
&
db
,
SQLITE_OPEN_READONLY
,
NULL
);
if
(
ret
)
{
LOGE
(
"sqlite3 open failure: %d"
,
ret
);
...
...
@@ -89,7 +69,6 @@ policy_t database_check(struct su_context *ctx) {
return
INTERACTIVE
;
}
int
result
;
char
*
err
=
NULL
;
struct
callback_data_t
data
;
data
.
ctx
=
ctx
;
...
...
su.c
View file @
e3a4a165
...
...
@@ -425,9 +425,6 @@ static int socket_send_request(int fd, const struct su_context *ctx) {
write_token
(
fd
,
"from.uid"
,
ctx
->
from
.
uid
);
write_token
(
fd
,
"to.uid"
,
ctx
->
to
.
uid
);
write_string_data
(
fd
,
"from.bin"
,
ctx
->
from
.
bin
);
write_string_data
(
fd
,
"bind.from"
,
ctx
->
bind
.
from
);
write_string_data
(
fd
,
"bind.to"
,
ctx
->
bind
.
to
);
write_string_data
(
fd
,
"init"
,
ctx
->
init
);
// TODO: Fix issue where not using -c does not result a in a command
write_string_data
(
fd
,
"command"
,
get_command
(
&
ctx
->
to
));
write_token
(
fd
,
"eof"
,
PROTO_VERSION
);
...
...
@@ -510,12 +507,6 @@ static __attribute__ ((noreturn)) void allow(struct su_context *ctx) {
if
(
send_to_app
)
send_result
(
ctx
,
ALLOW
);
// if(ctx->bind.from[0] && ctx->bind.to[0])
// allow_bind(ctx);
// if(ctx->init[0])
// allow_init(ctx);
char
*
binary
;
argc
=
ctx
->
to
.
optind
;
if
(
ctx
->
to
.
command
)
{
...
...
@@ -712,11 +703,6 @@ int su_main_nodaemon(int argc, char **argv) {
.
database_path
=
REQUESTOR_DATA_PATH
REQUESTOR_DATABASE_PATH
,
.
base_path
=
REQUESTOR_DATA_PATH
REQUESTOR
},
.
bind
=
{
.
from
=
""
,
.
to
=
""
,
},
.
init
=
""
,
};
struct
stat
st
;
int
c
,
socket_serv_fd
,
fd
;
...
...
@@ -756,7 +742,7 @@ int su_main_nodaemon(int argc, char **argv) {
printf
(
"%d
\n
"
,
VERSION_CODE
);
exit
(
EXIT_SUCCESS
);
case
'v'
:
printf
(
"%s
cm-su topjohnwu
\n
"
,
VERSION
);
printf
(
"%s
\n
"
,
VERSION
);
exit
(
EXIT_SUCCESS
);
case
'u'
:
switch
(
get_multiuser_mode
())
{
...
...
@@ -851,12 +837,6 @@ int su_main_nodaemon(int argc, char **argv) {
allow
(
&
ctx
);
}
// autogrant shell at this point
if
(
ctx
.
from
.
uid
==
AID_SHELL
)
{
LOGD
(
"Allowing shell."
);
allow
(
&
ctx
);
}
// deny if this is a non owner request and owner mode only
if
(
ctx
.
user
.
multiuser_mode
==
MULTIUSER_MODE_OWNER_ONLY
&&
ctx
.
user
.
android_user_id
!=
0
)
{
deny
(
&
ctx
);
...
...
@@ -883,7 +863,6 @@ int su_main_nodaemon(int argc, char **argv) {
deny
(
&
ctx
);
}
//TODO: Ignore database check for init and bind?
dballow
=
database_check
(
&
ctx
);
switch
(
dballow
)
{
case
INTERACTIVE
:
...
...
su.h
View file @
e3a4a165
...
...
@@ -46,29 +46,28 @@
#define CM_ROOT_ACCESS_APPS_AND_ADB 3
// DO NOT CHANGE LINE BELOW, java package name will always be the same
#define JAVA_PACKAGE_NAME "com.
koushikdutta.superuser
"
#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.
#ifndef REQUESTOR
#define REQUESTOR
"me.phh.superuser"
#define REQUESTOR
JAVA_PACKAGE_NAME
#endif
// This is used if wrapping the fragment classes and activities
// with classes in another package. CM requirement.
#ifndef REQUESTOR_PREFIX
#define REQUESTOR_PREFIX JAVA_PACKAGE_NAME
#define REQUESTOR_PREFIX JAVA_PACKAGE_NAME
".superuser"
#endif
#define REQUESTOR_DATA_PATH "/data/data/"
#define REQUESTOR_FILES_PATH REQUESTOR_DATA_PATH REQUESTOR "/files"
#define REQUESTOR_USER_PATH "/data/user/"
#define REQUESTOR_CACHE_PATH "/dev/" REQUESTOR
#define REQUESTOR_DAEMON_PATH REQUESTOR_CACHE_PATH ".daemon"
#define REQUESTOR_DAEMON_PATH "\0MAGISKSU"
// there's no guarantee that the db or files are actually created named as such by
// SQLiteOpenHelper, etc. Though that is the behavior as of current.
// it is up to the Android application to symlink as appropriate.
#define REQUESTOR_DATABASE_PATH REQUESTOR "/databases/su.
sqlite
"
#define REQUESTOR_DATABASE_PATH REQUESTOR "/databases/su.
db
"
#define REQUESTOR_MULTIUSER_MODE REQUESTOR_FILES_PATH "/multiuser_mode"
#define DEFAULT_SHELL "/system/bin/sh"
...
...
@@ -77,10 +76,9 @@
#define str(a) #a
#ifndef VERSION_CODE
#define VERSION_CODE 1
7
#define VERSION_CODE 1
#endif
#define VERSION xstr(VERSION_CODE) " " REQUESTOR
// #define VERSION REQUESTOR " topjohnwu r1"
#define VERSION "MAGISKSU:" xstr(VERSION_CODE)
#define PROTO_VERSION 1
...
...
@@ -123,17 +121,10 @@ struct su_user_info {
char
database_path
[
PATH_MAX
];
};
struct
su_bind
{
const
char
*
from
;
const
char
*
to
;
};
struct
su_context
{
struct
su_initiator
from
;
struct
su_request
to
;
struct
su_user_info
user
;
struct
su_bind
bind
;
const
char
*
init
;
mode_t
umask
;
char
sock_path
[
PATH_MAX
];
};
...
...
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