Use FIFO for su request communication

Fix #3159
This commit is contained in:
topjohnwu
2020-09-10 00:38:29 -07:00
parent 5022f00a55
commit 434efec860
6 changed files with 66 additions and 78 deletions

View File

@ -91,7 +91,7 @@ static shared_ptr<su_info> get_su_info(unsigned uid) {
info = cached;
}
auto g = info->lock();
mutex_guard lock = info->lock();
if (info->access.policy == QUERY) {
// Not cached, get data from database
@ -130,7 +130,7 @@ static shared_ptr<su_info> get_su_info(unsigned uid) {
return info;
// If still not determined, check if manager exists
if (info->str[SU_MANAGER][0] == '\0') {
if (info->str[SU_MANAGER].empty()) {
info->access = NO_SU_ACCESS;
return info;
}
@ -139,13 +139,10 @@ static shared_ptr<su_info> get_su_info(unsigned uid) {
}
// If still not determined, ask manager
char socket_name[32];
gen_rand_str(socket_name, sizeof(socket_name));
int fd = app_socket(socket_name, info);
int fd = app_request(info);
if (fd < 0) {
info->access.policy = DENY;
} else {
socket_send_request(fd, info);
int ret = read_int_be(fd);
info->access.policy = ret < 0 ? DENY : static_cast<policy_t>(ret);
close(fd);
@ -154,11 +151,8 @@ static shared_ptr<su_info> get_su_info(unsigned uid) {
return info;
}
// Set effective uid back to root, otherwise setres[ug]id will fail if uid isn't root
static void set_identity(unsigned uid) {
/*
* Set effective uid back to root, otherwise setres[ug]id will fail
* if uid isn't root.
*/
if (seteuid(0)) {
PLOGE("seteuid (root)");
}
@ -196,7 +190,16 @@ void su_daemon_handler(int client, struct ucred *credential) {
write_int(client, DENY);
close(client);
return;
} else if (int child = xfork(); child) {
}
// Fork a child root process
//
// The child process will need to setsid, open a pseudo-terminal
// if needed, and eventually exec shell.
// The parent process will wait for the result and
// send the return code back to our client.
if (int child = xfork(); child) {
ctx.info.reset();
// Wait result
@ -214,12 +217,6 @@ void su_daemon_handler(int client, struct ucred *credential) {
return;
}
/* The child process will need to setsid, open a pseudo-terminal
* if needed, and will eventually run exec.
* The parent process will wait for the result and
* send the return code back to our client
*/
LOGD("su: fork handler\n");
// Abort upon any error occurred