Make root shell always use dev_pts

Close #433
This commit is contained in:
topjohnwu 2018-08-02 20:29:18 +08:00
parent d9564bd04c
commit f1edc8443c
2 changed files with 25 additions and 41 deletions

View File

@ -6,7 +6,6 @@ void allowSuClient(char *target) {
return; return;
sepol_allow(target, SEPOL_PROC_DOMAIN, "unix_stream_socket", "connectto"); sepol_allow(target, SEPOL_PROC_DOMAIN, "unix_stream_socket", "connectto");
sepol_allow(target, SEPOL_PROC_DOMAIN, "unix_stream_socket", "getopt"); sepol_allow(target, SEPOL_PROC_DOMAIN, "unix_stream_socket", "getopt");
sepol_allow(target, "devpts", "chr_file", "ioctl");
sepol_allow(SEPOL_PROC_DOMAIN, target, "fd", "use"); sepol_allow(SEPOL_PROC_DOMAIN, target, "fd", "use");
sepol_allow(SEPOL_PROC_DOMAIN, target, "fifo_file", ALL); sepol_allow(SEPOL_PROC_DOMAIN, target, "fifo_file", ALL);
sepol_allow(target, SEPOL_PROC_DOMAIN, "process", "sigchld"); sepol_allow(target, SEPOL_PROC_DOMAIN, "process", "sigchld");
@ -17,15 +16,16 @@ void allowSuClient(char *target) {
sepol_allow(target, SEPOL_FILE_DOMAIN, "file", ALL); sepol_allow(target, SEPOL_FILE_DOMAIN, "file", ALL);
sepol_allow(target, SEPOL_FILE_DOMAIN, "dir", ALL); sepol_allow(target, SEPOL_FILE_DOMAIN, "dir", ALL);
// Fix several terminal apps running root shell // Allow termios ioctl
sepol_allow(target, "devpts", "chr_file", "ioctl");
sepol_allow(target, "untrusted_app_devpts", "chr_file", "ioctl");
sepol_allow(target, "untrusted_app_25_devpts", "chr_file", "ioctl");
sepol_allow(target, "untrusted_app_all_devpts", "chr_file", "ioctl");
if (policydb->policyvers >= POLICYDB_VERSION_XPERMS_IOCTL) { if (policydb->policyvers >= POLICYDB_VERSION_XPERMS_IOCTL) {
sepol_allowxperm(target, "devpts", "chr_file", "0x5400-0x54FF"); sepol_allowxperm(target, "devpts", "chr_file", "0x5400-0x54FF");
if (sepol_exists("untrusted_app_devpts")) sepol_allowxperm(target, "untrusted_app_devpts", "chr_file", "0x5400-0x54FF");
sepol_allowxperm(target, "untrusted_app_devpts", "chr_file", "0x5400-0x54FF"); sepol_allowxperm(target, "untrusted_app_25_devpts", "chr_file", "0x5400-0x54FF");
if (sepol_exists("untrusted_app_25_devpts")) sepol_allowxperm(target, "untrusted_app_all_devpts", "chr_file", "0x5400-0x54FF");
sepol_allowxperm(target, "untrusted_app_25_devpts", "chr_file", "0x5400-0x54FF");
if (sepol_exists("untrusted_app_all_devpts"))
sepol_allowxperm(target, "untrusted_app_all_devpts", "chr_file", "0x5400-0x54FF");
} }
} }

View File

@ -13,6 +13,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <selinux/selinux.h>
#include "magisk.h" #include "magisk.h"
#include "daemon.h" #include "daemon.h"
@ -200,9 +201,6 @@ static struct su_info *get_su_info(unsigned uid) {
static void su_executor(int client) { static void su_executor(int client) {
LOGD("su: executor started\n"); LOGD("su: executor started\n");
// ack
write_int(client, 0);
// Become session leader // Become session leader
xsetsid(); xsetsid();
@ -249,9 +247,6 @@ static void su_executor(int client) {
int errfd = recv_fd(client); int errfd = recv_fd(client);
int ptsfd = -1; int ptsfd = -1;
// We no longer need the access to socket in the child, close it
close(client);
if (pts_slave[0]) { if (pts_slave[0]) {
LOGD("su: pts_slave=[%s]\n", pts_slave); LOGD("su: pts_slave=[%s]\n", pts_slave);
// Check pts_slave file is owned by daemon_from_uid // Check pts_slave file is owned by daemon_from_uid
@ -265,6 +260,9 @@ static void su_executor(int client) {
exit2(1); exit2(1);
} }
// Set our pts_slave to devpts, same restriction as adb shell
lsetfilecon(pts_slave, "u:object_r:devpts:s0");
// Opening the TTY has to occur after the // Opening the TTY has to occur after the
// fork() and setsid() so that it becomes // fork() and setsid() so that it becomes
// our controlling TTY and not the daemon's // our controlling TTY and not the daemon's
@ -293,6 +291,10 @@ static void su_executor(int client) {
close(ptsfd); close(ptsfd);
// ack and close
write_int(client, 0);
close(client);
// Run the actual main // Run the actual main
su_daemon_main(argc, argv); su_daemon_main(argc, argv);
} }
@ -369,7 +371,7 @@ void su_daemon_receiver(int client, struct ucred *credential) {
* Connect daemon, send argc, argv, cwd, pts slave * Connect daemon, send argc, argv, cwd, pts slave
*/ */
int su_client_main(int argc, char *argv[]) { int su_client_main(int argc, char *argv[]) {
char buffer[PATH_MAX]; char pts_slave[PATH_MAX];
int ptmx, socketfd; int ptmx, socketfd;
// Connect to client // Connect to client
@ -394,40 +396,20 @@ int su_client_main(int argc, char *argv[]) {
if (atty) { if (atty) {
// We need a PTY. Get one. // We need a PTY. Get one.
ptmx = pts_open(buffer, sizeof(buffer)); ptmx = pts_open(pts_slave, sizeof(pts_slave));
} else { } else {
buffer[0] = '\0'; pts_slave[0] = '\0';
} }
// Send the pts_slave path to the daemon // Send the pts_slave path to the daemon
write_string(socketfd, buffer); write_string(socketfd, pts_slave);
// Send stdin // Send stdin
if (atty & ATTY_IN) { send_fd(socketfd, (atty & ATTY_IN) ? -1 : STDIN_FILENO);
// Using PTY
send_fd(socketfd, -1);
} else {
send_fd(socketfd, STDIN_FILENO);
}
// Send stdout // Send stdout
if (atty & ATTY_OUT) { send_fd(socketfd, (atty & ATTY_OUT) ? -1 : STDOUT_FILENO);
// Forward SIGWINCH
watch_sigwinch_async(STDOUT_FILENO, ptmx);
// Using PTY
send_fd(socketfd, -1);
} else {
send_fd(socketfd, STDOUT_FILENO);
}
// Send stderr // Send stderr
if (atty & ATTY_ERR) { send_fd(socketfd, (atty & ATTY_ERR) ? -1 : STDERR_FILENO);
// Using PTY
send_fd(socketfd, -1);
} else {
send_fd(socketfd, STDERR_FILENO);
}
// Wait for acknowledgement from daemon // Wait for acknowledgement from daemon
if (read_int(socketfd)) { if (read_int(socketfd)) {
@ -441,6 +423,8 @@ int su_client_main(int argc, char *argv[]) {
pump_stdin_async(ptmx); pump_stdin_async(ptmx);
} }
if (atty & ATTY_OUT) { if (atty & ATTY_OUT) {
// Forward SIGWINCH
watch_sigwinch_async(STDOUT_FILENO, ptmx);
pump_stdout_blocking(ptmx); pump_stdout_blocking(ptmx);
} }