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
Show 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 @@
#include "su.h"
/* intent actions */
#define ACTION_REQUEST "start", "-n", REQUESTOR "/" REQUESTOR_PREFIX ".RequestActivity"
#define ACTION_NOTIFY "start", "-n", REQUESTOR "/" REQUESTOR_PREFIX ".NotifyActivity"
#define ACTION_RESULT "broadcast", "-n", REQUESTOR "/" REQUESTOR_PREFIX ".SuReceiver"
#define ACTION_REQUEST "%s/" REQUESTOR_PREFIX ".RequestActivity"
#define ACTION_RESULT "%s/" REQUESTOR_PREFIX ".SuReceiver"
#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) {
char
user
[
16
];
int
notify
=
setup_user
(
ctx
,
user
);
char
activity
[
128
];
sprintf
(
activity
,
ACTION_RESULT
,
ctx
->
path
.
pkg_name
);
// Send notice to manager, enable logging
char
*
result_command
[]
=
{
AM_PATH
,
ACTION_RESULT
,
"--user"
,
user
,
"--ei"
,
"mode"
,
"0"
,
"--ei"
,
"from.uid"
,
fromUid
,
"--ei"
,
"to.uid"
,
toUid
,
"--ei"
,
"pid"
,
pid
,
"--es"
,
"command"
,
get_command
(
&
ctx
->
to
),
"--es"
,
"action"
,
policy
==
ALLOW
?
"allow"
:
"deny"
,
AM_PATH
,
"broadcast"
,
"-n"
,
activity
,
"--user"
,
user
,
"--ei"
,
"mode"
,
"0"
,
"--ei"
,
"from.uid"
,
fromUid
,
"--ei"
,
"to.uid"
,
toUid
,
"--ei"
,
"pid"
,
pid
,
"--es"
,
"command"
,
get_command
(
&
ctx
->
to
),
"--es"
,
"action"
,
policy
==
ALLOW
?
"allow"
:
"deny"
,
NULL
};
silent_run
(
result_command
);
...
...
@@ -105,19 +94,12 @@ void app_send_result(struct su_context *ctx, policy_t policy) {
if
(
notify
)
{
sprintf
(
user
,
"%d"
,
notify
);
char
*
notify_command
[]
=
{
AM_PATH
,
ACTION_RESULT
,
"--user"
,
user
,
"--ei"
,
"mode"
,
"1"
,
"--ei"
,
"from.uid"
,
fromUid
,
"--es"
,
"action"
,
policy
==
ALLOW
?
"allow"
:
"deny"
,
AM_PATH
,
"broadcast"
,
"-n"
,
activity
,
"--user"
,
user
,
"--ei"
,
"mode"
,
"1"
,
"--ei"
,
"from.uid"
,
fromUid
,
"--es"
,
"action"
,
policy
==
ALLOW
?
"allow"
:
"deny"
,
NULL
};
silent_run
(
notify_command
);
...
...
@@ -128,17 +110,15 @@ void app_send_request(struct su_context *ctx) {
char
user
[
16
];
int
notify
=
setup_user
(
ctx
,
user
);
char
activity
[
128
];
sprintf
(
activity
,
ACTION_REQUEST
,
ctx
->
path
.
pkg_name
);
char
*
request_command
[]
=
{
AM_PATH
,
ACTION_REQUEST
,
"--user"
,
user
,
"--es"
,
"socket"
,
ctx
->
path
.
sock_path
,
"--ez"
,
"timeout"
,
notify
?
"false"
:
"true"
,
AM_PATH
,
"start"
,
"-n"
,
activity
,
"--user"
,
user
,
"--es"
,
"socket"
,
ctx
->
path
.
sock_path
,
"--ez"
,
"timeout"
,
notify
?
"false"
:
"true"
,
NULL
};
silent_run
(
request_command
);
...
...
@@ -146,14 +126,12 @@ void app_send_request(struct su_context *ctx) {
// Send notice to user to tell them root is managed by owner
if
(
notify
)
{
sprintf
(
user
,
"%d"
,
notify
);
sprintf
(
activity
,
ACTION_RESULT
,
ctx
->
path
.
pkg_name
);
char
*
notify_command
[]
=
{
AM_PATH
,
ACTION_RESULT
,
"--user"
,
user
,
"--ei"
,
"mode"
,
"2"
,
AM_PATH
,
"broadcast"
,
"-n"
,
activity
,
"--user"
,
user
,
"--ei"
,
"mode"
,
"2"
,
NULL
};
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) {
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
)
{
sqlite3
*
db
=
NULL
;
int
ret
;
char
query
[
512
],
*
err
=
NULL
;
char
buffer
[
PATH_MAX
],
*
err
=
NULL
;
// Set default values
ctx
->
info
->
root_access
=
ROOT_ACCESS_APPS_AND_ADB
;
ctx
->
info
->
multiuser_mode
=
MULTIUSER_MODE_OWNER_ONLY
;
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
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
)
{
LOGD
(
"sqlite3 open failure: %s
\n
"
,
sqlite3_errstr
(
ret
));
sqlite3_close
(
db
);
return
;
goto
stat_requester
;
}
// Check multiuser mode settings
snprintf
(
query
,
sizeof
(
query
),
"SELECT key, value FROM settings WHERE key='%s'"
,
MULTIUSER_MODE_ENTRY
);
sqlite3_exec
(
db
,
query
,
settings_callback
,
ctx
,
&
err
);
sprintf
(
buffer
,
"SELECT key, value FROM settings WHERE key='%s'"
,
MULTIUSER_MODE_ENTRY
);
sqlite3_exec
(
db
,
buffer
,
settings_callback
,
ctx
,
&
err
);
if
(
err
!=
NULL
)
LOGE
(
"sqlite3_exec: %s
\n
"
,
err
);
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
);
// Open database
ret
=
sqlite3_open_v2
(
ctx
->
path
.
multiuser_db
,
&
db
,
SQLITE_OPEN_READONLY
,
NULL
);
sprintf
(
buffer
,
"%s/magisk.db"
,
ctx
->
path
.
multiuser_path
);
LOGD
(
"su_db: open %s"
,
buffer
);
ret
=
sqlite3_open_v2
(
buffer
,
&
db
,
SQLITE_OPEN_READONLY
,
NULL
);
if
(
ret
)
{
LOGD
(
"sqlite3 open failure: %s
\n
"
,
sqlite3_errstr
(
ret
));
sqlite3_close
(
db
);
return
;
goto
stat_requester
;
}
}
//
Query for policy
s
nprintf
(
query
,
sizeof
(
query
),
"SELECT policy, until FROM policies WHERE uid=%d"
,
ctx
->
info
->
uid
%
100000
);
sqlite3_exec
(
db
,
query
,
policy
_callback
,
ctx
,
&
err
);
if
(
err
!=
NULL
)
{
//
Read PKG name from DB
s
trcpy
(
buffer
,
"SELECT key, value FROM strings"
);
sqlite3_exec
(
db
,
buffer
,
strings
_callback
,
ctx
,
&
err
);
if
(
err
!=
NULL
)
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
;
// Query for settings
s
nprintf
(
query
,
sizeof
(
query
)
,
"SELECT key, value FROM settings WHERE key!='%s'"
,
MULTIUSER_MODE_ENTRY
);
sqlite3_exec
(
db
,
query
,
settings_callback
,
ctx
,
&
err
);
if
(
err
!=
NULL
)
{
s
printf
(
buffer
,
"SELECT key, value FROM settings WHERE key!='%s'"
,
MULTIUSER_MODE_ENTRY
);
sqlite3_exec
(
db
,
buffer
,
settings_callback
,
ctx
,
&
err
);
if
(
err
!=
NULL
)
LOGE
(
"sqlite3_exec: %s
\n
"
,
err
);
return
;
}
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) {
__attribute__
((
noreturn
))
void
exit2
(
int
status
)
{
// Handle the pipe, or the daemon will get stuck
if
(
su_ctx
->
info
->
policy
==
QUERY
)
{
xwrite
(
pipefd
[
1
],
&
su_ctx
->
info
->
policy
,
sizeof
(
su_ctx
->
info
->
policy
));
close
(
pipefd
[
0
]);
close
(
pipefd
[
1
]);
xwrite
(
su_ctx
->
pipefd
[
1
],
&
su_ctx
->
info
->
policy
,
sizeof
(
su_ctx
->
info
->
policy
));
close
(
su_ctx
->
pipefd
[
0
]);
close
(
su_ctx
->
pipefd
[
1
]);
}
exit
(
status
);
}
...
...
@@ -352,19 +352,6 @@ int su_daemon_main(int argc, char **argv) {
// New request or no db exist, notify user for response
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
));
setup_sighandlers
(
cleanup_signal
);
...
...
@@ -387,9 +374,9 @@ int su_daemon_main(int argc, char **argv) {
su_ctx
->
info
->
policy
=
DENY
;
// Report the policy to main daemon
xwrite
(
pipefd
[
1
],
&
su_ctx
->
info
->
policy
,
sizeof
(
su_ctx
->
info
->
policy
));
close
(
pipefd
[
0
]);
close
(
pipefd
[
1
]);
xwrite
(
su_ctx
->
pipefd
[
1
],
&
su_ctx
->
info
->
policy
,
sizeof
(
su_ctx
->
info
->
policy
));
close
(
su_ctx
->
pipefd
[
0
]);
close
(
su_ctx
->
pipefd
[
1
]);
}
if
(
su_ctx
->
info
->
policy
==
ALLOW
)
...
...
su.h
View file @
84ca8e1f
...
...
@@ -31,17 +31,14 @@
#define NAMESPACE_MODE_REQUESTER 1
#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
#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
// with classes in another package.
#define REQUESTOR_PREFIX JAVA_PACKAGE_NAME ".superuser"
#define REQUESTOR_CACHE_PATH "/dev/" REQUESTOR
#define DEFAULT_SHELL "/system/bin/sh"
...
...
@@ -80,9 +77,8 @@ struct su_request {
struct
su_path
{
char
base_path
[
PATH_MAX
];
char
base_db
[
PATH_MAX
];
char
multiuser_path
[
PATH_MAX
];
char
multiuser_db
[
PATH_MAX
];
char
pkg_name
[
PATH_MAX
];
char
sock_path
[
PATH_MAX
];
};
...
...
@@ -95,10 +91,10 @@ struct su_context {
mode_t
umask
;
char
*
cwd
;
struct
stat
st
;
int
pipefd
[
2
];
};
extern
struct
su_context
*
su_ctx
;
extern
int
pipefd
[
2
];
// su.c
...
...
su_daemon.c
View file @
84ca8e1f
...
...
@@ -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
)
{
LOGD
(
"su: request from client: %d
\n
"
,
client
);
...
...
@@ -170,16 +148,6 @@ void su_daemon_receiver(int client) {
.
umask
=
022
,
.
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_UID
();
...
...
@@ -187,41 +155,38 @@ void su_daemon_receiver(int client) {
// Not cached, do the checks
if
(
info
->
policy
==
QUERY
)
{
// Get data from database
database_check
(
su_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
;
}
}
database_check
(
&
ctx
);
// Handle multiuser denies
if
(
su_ctx
->
info
->
uid
/
100000
&&
su_ctx
->
info
->
multiuser_mode
==
MULTIUSER_MODE_OWNER_ONLY
)
{
if
(
info
->
uid
/
100000
&&
info
->
multiuser_mode
==
MULTIUSER_MODE_OWNER_ONLY
)
{
info
->
policy
=
DENY
;
su_ctx
->
notify
=
0
;
ctx
.
notify
=
0
;
}
// always allow if this is Magisk Manager
if
(
info
->
policy
==
QUERY
&&
(
info
->
uid
%
100000
)
==
(
su_ctx
->
st
.
st_uid
%
100000
))
{
// Check requester
if
(
info
->
policy
==
QUERY
)
{
if
(
ctx
.
st
.
st_gid
!=
ctx
.
st
.
st_uid
)
{
LOGE
(
"Bad uid/gid %d/%d for Superuser Requestor"
,
ctx
.
st
.
st_uid
,
ctx
.
st
.
st_gid
);
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
;
su_ctx
->
notify
=
0
;
ctx
.
notify
=
0
;
}
}
// always allow if it's root
if
(
info
->
uid
==
UID_ROOT
)
{
info
->
policy
=
ALLOW
;
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
(
info
->
policy
==
QUERY
)
xpipe2
(
pipefd
,
O_CLOEXEC
);
xpipe2
(
ctx
.
pipefd
,
O_CLOEXEC
);
}
// Fork a new process, the child process will need to setsid,
...
...
@@ -235,9 +200,9 @@ void su_daemon_receiver(int client) {
if
(
child
)
{
// Wait for results
if
(
info
->
policy
==
QUERY
)
{
xxread
(
pipefd
[
0
],
&
info
->
policy
,
sizeof
(
info
->
policy
));
close
(
pipefd
[
0
]);
close
(
pipefd
[
1
]);
xxread
(
ctx
.
pipefd
[
0
],
&
info
->
policy
,
sizeof
(
info
->
policy
));
close
(
ctx
.
pipefd
[
0
]);
close
(
ctx
.
pipefd
[
1
]);
}
// The policy is determined, unlock
...
...
@@ -308,8 +273,8 @@ void su_daemon_receiver(int client) {
}
// Get cwd
su_ctx
->
cwd
=
read_string
(
client
);
LOGD
(
"su: cwd=[%s]
\n
"
,
su_ctx
->
cwd
);
ctx
.
cwd
=
read_string
(
client
);
LOGD
(
"su: cwd=[%s]
\n
"
,
ctx
.
cwd
);
// Get pts_slave
char
*
pts_slave
=
read_string
(
client
);
...
...
@@ -330,7 +295,7 @@ void su_daemon_receiver(int client) {
xstat
(
pts_slave
,
&
stbuf
);
//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"
);
exit2
(
1
);
}
...
...
@@ -363,6 +328,8 @@ void su_daemon_receiver(int client) {
close
(
ptsfd
);
// Give main the reference
su_ctx
=
&
ctx
;
su_daemon_main
(
argc
,
argv
);
}
...
...
su_socket.c
View file @
84ca8e1f
...
...
@@ -29,21 +29,22 @@ int socket_create_temp(char *path, size_t len) {
memset
(
&
sun
,
0
,
sizeof
(
sun
));
sun
.
sun_family
=
AF_LOCAL
;
snprintf
(
path
,
len
,
"
%s/.socket%d"
,
REQUESTOR_CACHE_PATH
,
(
int
)
syscall
(
SYS_gettid
));
s
nprintf
(
sun
.
sun_path
,
sizeof
(
sun
.
sun_path
),
"%s"
,
path
);
snprintf
(
path
,
len
,
"
/dev/.socket%d"
,
(
int
)
syscall
(
SYS_gettid
));
s
trcpy
(
sun
.
sun_path
,
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
(
path
);
xbind
(
fd
,
(
struct
sockaddr
*
)
&
sun
,
sizeof
(
sun
));
xlisten
(
fd
,
1
);
// Set context to su_device, so apps can access it
setfilecon
(
sun
.
sun_path
,
"u:object_r:su_device:s0"
);
// Set attributes so requester can access it
setfilecon
(
path
,
"u:object_r:su_device:s0"
);
chown
(
path
,
su_ctx
->
st
.
st_uid
,
su_ctx
->
st
.
st_gid
);
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