From f1edc8443c31a77ae978d8288909485ea5dbd34a Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Thu, 2 Aug 2018 20:29:18 +0800 Subject: [PATCH] Make root shell always use dev_pts Close #433 --- native/jni/magiskpolicy/rules.c | 16 +++++------ native/jni/su/su_daemon.c | 50 +++++++++++---------------------- 2 files changed, 25 insertions(+), 41 deletions(-) diff --git a/native/jni/magiskpolicy/rules.c b/native/jni/magiskpolicy/rules.c index 01205143f..4ae3ab9e6 100644 --- a/native/jni/magiskpolicy/rules.c +++ b/native/jni/magiskpolicy/rules.c @@ -6,7 +6,6 @@ void allowSuClient(char *target) { return; sepol_allow(target, SEPOL_PROC_DOMAIN, "unix_stream_socket", "connectto"); 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, "fifo_file", ALL); 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, "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) { sepol_allowxperm(target, "devpts", "chr_file", "0x5400-0x54FF"); - if (sepol_exists("untrusted_app_devpts")) - sepol_allowxperm(target, "untrusted_app_devpts", "chr_file", "0x5400-0x54FF"); - if (sepol_exists("untrusted_app_25_devpts")) - 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"); + sepol_allowxperm(target, "untrusted_app_devpts", "chr_file", "0x5400-0x54FF"); + sepol_allowxperm(target, "untrusted_app_25_devpts", "chr_file", "0x5400-0x54FF"); + sepol_allowxperm(target, "untrusted_app_all_devpts", "chr_file", "0x5400-0x54FF"); } } diff --git a/native/jni/su/su_daemon.c b/native/jni/su/su_daemon.c index 48f98ff65..7b5b7c9d8 100644 --- a/native/jni/su/su_daemon.c +++ b/native/jni/su/su_daemon.c @@ -13,6 +13,7 @@ #include #include #include +#include #include "magisk.h" #include "daemon.h" @@ -200,9 +201,6 @@ static struct su_info *get_su_info(unsigned uid) { static void su_executor(int client) { LOGD("su: executor started\n"); - // ack - write_int(client, 0); - // Become session leader xsetsid(); @@ -249,9 +247,6 @@ static void su_executor(int client) { int errfd = recv_fd(client); int ptsfd = -1; - // We no longer need the access to socket in the child, close it - close(client); - if (pts_slave[0]) { LOGD("su: pts_slave=[%s]\n", pts_slave); // Check pts_slave file is owned by daemon_from_uid @@ -265,6 +260,9 @@ static void su_executor(int client) { 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 // fork() and setsid() so that it becomes // our controlling TTY and not the daemon's @@ -293,6 +291,10 @@ static void su_executor(int client) { close(ptsfd); + // ack and close + write_int(client, 0); + close(client); + // Run the actual main 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 */ int su_client_main(int argc, char *argv[]) { - char buffer[PATH_MAX]; + char pts_slave[PATH_MAX]; int ptmx, socketfd; // Connect to client @@ -394,40 +396,20 @@ int su_client_main(int argc, char *argv[]) { if (atty) { // We need a PTY. Get one. - ptmx = pts_open(buffer, sizeof(buffer)); + ptmx = pts_open(pts_slave, sizeof(pts_slave)); } else { - buffer[0] = '\0'; + pts_slave[0] = '\0'; } // Send the pts_slave path to the daemon - write_string(socketfd, buffer); + write_string(socketfd, pts_slave); // Send stdin - if (atty & ATTY_IN) { - // Using PTY - send_fd(socketfd, -1); - } else { - send_fd(socketfd, STDIN_FILENO); - } - + send_fd(socketfd, (atty & ATTY_IN) ? -1 : STDIN_FILENO); // Send stdout - if (atty & ATTY_OUT) { - // Forward SIGWINCH - watch_sigwinch_async(STDOUT_FILENO, ptmx); - - // Using PTY - send_fd(socketfd, -1); - } else { - send_fd(socketfd, STDOUT_FILENO); - } - + send_fd(socketfd, (atty & ATTY_OUT) ? -1 : STDOUT_FILENO); // Send stderr - if (atty & ATTY_ERR) { - // Using PTY - send_fd(socketfd, -1); - } else { - send_fd(socketfd, STDERR_FILENO); - } + send_fd(socketfd, (atty & ATTY_ERR) ? -1 : STDERR_FILENO); // Wait for acknowledgement from daemon if (read_int(socketfd)) { @@ -441,6 +423,8 @@ int su_client_main(int argc, char *argv[]) { pump_stdin_async(ptmx); } if (atty & ATTY_OUT) { + // Forward SIGWINCH + watch_sigwinch_async(STDOUT_FILENO, ptmx); pump_stdout_blocking(ptmx); }