From a3df721b845f288a731916fc7777efeefb033af7 Mon Sep 17 00:00:00 2001 From: weishu Date: Wed, 8 May 2024 21:17:24 +0800 Subject: [PATCH] Revert "su: allocate new pty (#1693)" This reverts commit 935dc18faace4dfdda79d3f00bf1ed2632a94628. --- userspace/ksud/src/cli.rs | 4 +- userspace/ksud/src/defs.rs | 2 - userspace/ksud/src/init_event.rs | 6 - userspace/ksud/src/main.rs | 2 - userspace/ksud/src/mount.rs | 19 --- userspace/ksud/src/pty.rs | 195 ------------------------------- userspace/ksud/src/su.rs | 10 -- 7 files changed, 2 insertions(+), 236 deletions(-) delete mode 100644 userspace/ksud/src/pty.rs diff --git a/userspace/ksud/src/cli.rs b/userspace/ksud/src/cli.rs index b3954bd1..cd96a360 100644 --- a/userspace/ksud/src/cli.rs +++ b/userspace/ksud/src/cli.rs @@ -1,6 +1,6 @@ use anyhow::{Ok, Result}; use clap::Parser; -use std::path::{Path, PathBuf}; +use std::path::PathBuf; #[cfg(target_os = "android")] use android_logger::Config; @@ -283,7 +283,7 @@ pub fn run() -> Result<()> { // the kernel executes su with argv[0] = "su" and replace it with us let arg0 = std::env::args().next().unwrap_or_default(); - if Path::new(&arg0).file_name().and_then(|f| f.to_str()) == Some("su") { + if arg0 == "su" || arg0 == "/system/bin/su" { return crate::su::root_shell(); } diff --git a/userspace/ksud/src/defs.rs b/userspace/ksud/src/defs.rs index bcde7712..c4b9fc3f 100644 --- a/userspace/ksud/src/defs.rs +++ b/userspace/ksud/src/defs.rs @@ -43,5 +43,3 @@ pub const VERSION_NAME: &str = include_str!(concat!(env!("OUT_DIR"), "/VERSION_N pub const KSU_BACKUP_DIR: &str = WORKING_DIR; pub const KSU_BACKUP_FILE_PREFIX: &str = "ksu_backup_"; pub const BACKUP_FILENAME: &str = "stock_image.sha1"; - -pub const PTS_NAME: &str = "pts"; diff --git a/userspace/ksud/src/init_event.rs b/userspace/ksud/src/init_event.rs index f2334d1b..7107ff74 100644 --- a/userspace/ksud/src/init_event.rs +++ b/userspace/ksud/src/init_event.rs @@ -2,7 +2,6 @@ use anyhow::{bail, Context, Result}; use log::{info, warn}; use std::{collections::HashMap, path::Path}; -use crate::defs::PTS_NAME; use crate::module::prune_modules; use crate::{ assets, defs, ksucalls, mount, restorecon, @@ -194,11 +193,6 @@ pub fn on_post_data_fs() -> Result<()> { // mount temp dir if let Err(e) = mount::mount_tmpfs(utils::get_tmp_path()) { warn!("do temp dir mount failed: {}", e); - } else { - let pts_dir = format!("{}/{PTS_NAME}", utils::get_tmp_path()); - if let Err(e) = mount::mount_devpts(pts_dir) { - warn!("do devpts mount failed: {}", e); - } } // exec modules post-fs-data scripts diff --git a/userspace/ksud/src/main.rs b/userspace/ksud/src/main.rs index b22de948..3b517205 100644 --- a/userspace/ksud/src/main.rs +++ b/userspace/ksud/src/main.rs @@ -9,8 +9,6 @@ mod ksucalls; mod module; mod mount; mod profile; -#[cfg(any(target_os = "linux", target_os = "android"))] -mod pty; mod restorecon; mod sepolicy; mod su; diff --git a/userspace/ksud/src/mount.rs b/userspace/ksud/src/mount.rs index 8eb0eb20..11be898b 100644 --- a/userspace/ksud/src/mount.rs +++ b/userspace/ksud/src/mount.rs @@ -1,5 +1,4 @@ use anyhow::{anyhow, bail, Ok, Result}; -use std::fs::create_dir; #[cfg(any(target_os = "linux", target_os = "android"))] use anyhow::Context; @@ -182,19 +181,6 @@ pub fn mount_tmpfs(dest: impl AsRef) -> Result<()> { Ok(()) } -#[cfg(any(target_os = "linux", target_os = "android"))] -pub fn mount_devpts(dest: impl AsRef) -> Result<()> { - create_dir(dest.as_ref())?; - mount( - KSU_OVERLAY_SOURCE, - dest.as_ref(), - "devpts", - MountFlags::empty(), - "newinstance", - )?; - Ok(()) -} - #[cfg(any(target_os = "linux", target_os = "android"))] pub fn bind_mount(from: impl AsRef, to: impl AsRef) -> Result<()> { info!( @@ -339,8 +325,3 @@ pub fn mount_overlay( pub fn mount_tmpfs(_dest: impl AsRef) -> Result<()> { unimplemented!() } - -#[cfg(not(any(target_os = "linux", target_os = "android")))] -pub fn mount_devpts(_dest: impl AsRef) -> Result<()> { - unimplemented!() -} diff --git a/userspace/ksud/src/pty.rs b/userspace/ksud/src/pty.rs deleted file mode 100644 index 1a9258d2..00000000 --- a/userspace/ksud/src/pty.rs +++ /dev/null @@ -1,195 +0,0 @@ -use std::ffi::c_int; -use std::fs::File; -use std::io::{stderr, stdin, stdout, Error, ErrorKind, Read, Write}; -use std::mem::MaybeUninit; -use std::os::fd::{AsFd, AsRawFd, OwnedFd, RawFd}; -use std::process::exit; -use std::ptr::null_mut; -use std::thread; - -use anyhow::{bail, Ok, Result}; -use libc::{ - fork, pthread_sigmask, sigaddset, sigemptyset, sigset_t, sigwait, waitpid, winsize, SIGWINCH, - SIG_BLOCK, SIG_UNBLOCK, TIOCGWINSZ, TIOCSWINSZ, -}; -use rustix::fs::{open, Mode, OFlags}; -use rustix::io::dup; -use rustix::ioctl::{ioctl, Getter, ReadOpcode}; -use rustix::process::setsid; -use rustix::pty::{grantpt, unlockpt}; -use rustix::stdio::{dup2_stderr, dup2_stdin, dup2_stdout}; -use rustix::termios::{isatty, tcgetattr, tcsetattr, OptionalActions, Termios}; - -use crate::defs::PTS_NAME; -use crate::utils::get_tmp_path; - -// https://github.com/topjohnwu/Magisk/blob/5627053b7481618adfdf8fa3569b48275589915b/native/src/core/su/pts.cpp - -fn get_pty_num(fd: F) -> Result { - Ok(unsafe { - let tiocgptn = Getter::, u32>::new(); - ioctl(fd, tiocgptn)? - }) -} - -static mut OLD_STDIN: Option = None; - -fn watch_sigwinch_async(slave: RawFd) { - let mut winch = MaybeUninit::::uninit(); - unsafe { - sigemptyset(winch.as_mut_ptr()); - sigaddset(winch.as_mut_ptr(), SIGWINCH); - pthread_sigmask(SIG_BLOCK, winch.as_mut_ptr(), null_mut()); - } - - thread::spawn(move || unsafe { - let mut winch = MaybeUninit::::uninit(); - sigemptyset(winch.as_mut_ptr()); - sigaddset(winch.as_mut_ptr(), SIGWINCH); - pthread_sigmask(SIG_UNBLOCK, winch.as_mut_ptr(), null_mut()); - let mut sig: c_int = 0; - loop { - let mut w = MaybeUninit::::uninit(); - if libc::ioctl(1, TIOCGWINSZ, w.as_mut_ptr()) < 0 { - continue; - } - libc::ioctl(slave, TIOCSWINSZ, w.as_mut_ptr()); - if sigwait(winch.as_mut_ptr(), &mut sig) != 0 { - break; - } - } - }); -} - -fn set_stdin_raw() { - let mut termios = match tcgetattr(stdin()) { - Result::Ok(termios) => { - unsafe { - OLD_STDIN = Some(termios.clone()); - } - termios - } - Err(_) => return, - }; - - termios.make_raw(); - - if tcsetattr(stdin(), OptionalActions::Flush, &termios).is_err() { - let _ = tcsetattr(stdin(), OptionalActions::Drain, &termios); - } -} - -fn restore_stdin() { - let Some(termios) = (unsafe { OLD_STDIN.take() }) else { - return; - }; - - if tcsetattr(stdin(), OptionalActions::Flush, &termios).is_err() { - let _ = tcsetattr(stdin(), OptionalActions::Drain, &termios); - } -} - -fn pump(mut from: R, mut to: W) { - let mut buf = [0u8; 4096]; - loop { - match from.read(&mut buf) { - Result::Ok(len) => { - if len == 0 { - return; - } - if to.write_all(&buf[0..len]).is_err() { - return; - } - if to.flush().is_err() { - return; - } - } - Err(_) => { - return; - } - } - } -} - -fn pump_stdin_async(mut ptmx: File) { - set_stdin_raw(); - - thread::spawn(move || { - let mut stdin = stdin(); - pump(&mut stdin, &mut ptmx); - }); -} - -fn pump_stdout_blocking(mut ptmx: File) { - let mut stdout = stdout(); - pump(&mut ptmx, &mut stdout); - - restore_stdin(); -} - -fn create_transfer(ptmx: OwnedFd) -> Result<()> { - let pid = unsafe { fork() }; - match pid { - d if d < 0 => bail!("fork"), - 0 => return Ok(()), - _ => {} - } - - let ptmx_r = ptmx; - let ptmx_w = dup(&ptmx_r).unwrap(); - - let ptmx_r = File::from(ptmx_r); - let ptmx_w = File::from(ptmx_w); - - watch_sigwinch_async(ptmx_w.as_raw_fd()); - pump_stdin_async(ptmx_r); - pump_stdout_blocking(ptmx_w); - - let mut status: c_int = -1; - - unsafe { - loop { - if waitpid(pid, &mut status, 0) == -1 { - let last_os_error = Error::last_os_error(); - if last_os_error.kind() != ErrorKind::Interrupted { - continue; - } - } - break; - } - } - - exit(status) -} - -pub fn prepare_pty() -> Result<()> { - let tty_in = isatty(stdin()); - let tty_out = isatty(stdout()); - let tty_err = isatty(stderr()); - if !tty_in && !tty_out && !tty_err { - return Ok(()); - } - - let mut pts_path = format!("{}/{}", get_tmp_path(), PTS_NAME); - if !std::path::Path::new(&pts_path).exists() { - pts_path = "/dev/pts".to_string(); - } - let ptmx_path = format!("{}/ptmx", pts_path); - let ptmx_fd = open(ptmx_path, OFlags::RDWR, Mode::empty())?; - grantpt(&ptmx_fd)?; - unlockpt(&ptmx_fd)?; - let pty_num = get_pty_num(&ptmx_fd)?; - create_transfer(ptmx_fd)?; - setsid()?; - let pty_fd = open(format!("{pts_path}/{pty_num}"), OFlags::RDWR, Mode::empty())?; - if tty_in { - dup2_stdin(&pty_fd)?; - } - if tty_out { - dup2_stdout(&pty_fd)?; - } - if tty_err { - dup2_stderr(&pty_fd)?; - } - Ok(()) -} diff --git a/userspace/ksud/src/su.rs b/userspace/ksud/src/su.rs index d97eff49..b19bf7a2 100644 --- a/userspace/ksud/src/su.rs +++ b/userspace/ksud/src/su.rs @@ -11,8 +11,6 @@ use crate::{ utils::{self, umask}, }; -#[cfg(any(target_os = "linux", target_os = "android"))] -use crate::pty::prepare_pty; #[cfg(any(target_os = "linux", target_os = "android"))] use rustix::{ process::getuid, @@ -140,7 +138,6 @@ pub fn root_shell() -> Result<()> { "Specify a supplementary group. The first specified supplementary group is also used as a primary group if the option -g is not specified.", "GROUP", ); - opts.optflag("", "no-pty", "Do not allocate a new pseudo terminal."); // Replace -cn with -z, -mm with -M for supporting getopt_long let args = args @@ -268,13 +265,6 @@ pub fn root_shell() -> Result<()> { command = command.env("ENV", defs::KSURC_PATH); } - #[cfg(target_os = "android")] - if !matches.opt_present("no-pty") { - if let Err(e) = prepare_pty() { - log::error!("failed to prepare pty: {:?}", e); - } - } - // escape from the current cgroup and become session leader // WARNING!!! This cause some root shell hang forever! // command = command.process_group(0);