Make log pipe a FIFO instead of anonymous pipe

This commit is contained in:
topjohnwu 2023-10-30 03:14:25 -07:00
parent a177846044
commit a6e50d3648
6 changed files with 76 additions and 29 deletions

View File

@ -17,6 +17,24 @@ pub struct MagiskD {
is_emulator: bool, is_emulator: bool,
} }
impl MagiskD {
pub fn is_emulator(&self) -> bool {
self.is_emulator
}
}
mod cxx_extern {
use base::libc::c_char;
extern "C" {
pub fn get_magisk_tmp() -> *const c_char;
}
}
pub fn get_magisk_tmp() -> &'static Utf8CStr {
unsafe { Utf8CStr::from_ptr(cxx_extern::get_magisk_tmp()).unwrap_unchecked() }
}
pub fn daemon_entry() { pub fn daemon_entry() {
let mut qemu = get_prop(cstr!("ro.kernel.qemu"), false); let mut qemu = get_prop(cstr!("ro.kernel.qemu"), false);
if qemu.is_empty() { if qemu.is_empty() {
@ -43,12 +61,6 @@ pub fn get_magiskd() -> &'static MagiskD {
unsafe { MAGISKD.get().unwrap_unchecked() } unsafe { MAGISKD.get().unwrap_unchecked() }
} }
impl MagiskD {
pub fn is_emulator(&self) -> bool {
self.is_emulator
}
}
pub fn find_apk_path(pkg: &[u8], data: &mut [u8]) -> usize { pub fn find_apk_path(pkg: &[u8], data: &mut [u8]) -> usize {
use WalkResult::*; use WalkResult::*;
fn inner(pkg: &[u8], buf: &mut dyn Utf8CStrBuf) -> io::Result<usize> { fn inner(pkg: &[u8], buf: &mut dyn Utf8CStrBuf) -> io::Result<usize> {

View File

@ -3,7 +3,7 @@ use std::ffi::{c_char, c_void};
use std::fmt::Write as FmtWrite; use std::fmt::Write as FmtWrite;
use std::fs::File; use std::fs::File;
use std::io::{IoSlice, Read, Write}; use std::io::{IoSlice, Read, Write};
use std::os::fd::{AsRawFd, FromRawFd, RawFd}; use std::os::fd::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
use std::ptr::null_mut; use std::ptr::null_mut;
use std::{fs, io}; use std::{fs, io};
@ -12,15 +12,15 @@ use num_derive::{FromPrimitive, ToPrimitive};
use num_traits::FromPrimitive; use num_traits::FromPrimitive;
use base::libc::{ use base::libc::{
clock_gettime, getpid, gettid, localtime_r, pipe2, pthread_sigmask, sigaddset, sigset_t, clock_gettime, getpid, gettid, localtime_r, pthread_sigmask, sigaddset, sigset_t, sigtimedwait,
sigtimedwait, timespec, tm, CLOCK_REALTIME, O_CLOEXEC, PIPE_BUF, SIGPIPE, SIG_BLOCK, timespec, tm, CLOCK_REALTIME, O_CLOEXEC, O_RDWR, O_WRONLY, PIPE_BUF, SIGPIPE, SIG_BLOCK,
SIG_SETMASK, SIG_SETMASK,
}; };
use base::*; use base::*;
use crate::daemon::{MagiskD, MAGISKD}; use crate::daemon::{get_magisk_tmp, MagiskD, MAGISKD};
use crate::logging::LogFile::{Actual, Buffer}; use crate::logging::LogFile::{Actual, Buffer};
use crate::LOGFILE; use crate::{LOGFILE, LOG_PIPE};
#[allow(dead_code, non_camel_case_types)] #[allow(dead_code, non_camel_case_types)]
#[derive(FromPrimitive, ToPrimitive)] #[derive(FromPrimitive, ToPrimitive)]
@ -59,9 +59,7 @@ fn level_to_prio(level: LogLevel) -> i32 {
pub fn android_logging() { pub fn android_logging() {
fn android_log_write(level: LogLevel, msg: &Utf8CStr) { fn android_log_write(level: LogLevel, msg: &Utf8CStr) {
unsafe { write_android_log(level_to_prio(level), msg);
__android_log_write(level_to_prio(level), raw_cstr!("Magisk"), msg.as_ptr());
}
} }
let logger = Logger { let logger = Logger {
@ -76,9 +74,7 @@ pub fn android_logging() {
pub fn magisk_logging() { pub fn magisk_logging() {
fn magisk_log_write(level: LogLevel, msg: &Utf8CStr) { fn magisk_log_write(level: LogLevel, msg: &Utf8CStr) {
unsafe { write_android_log(level_to_prio(level), msg);
__android_log_write(level_to_prio(level), raw_cstr!("Magisk"), msg.as_ptr());
}
magisk_log_to_pipe(level_to_prio(level), msg); magisk_log_to_pipe(level_to_prio(level), msg);
} }
@ -94,9 +90,7 @@ pub fn magisk_logging() {
pub fn zygisk_logging() { pub fn zygisk_logging() {
fn zygisk_log_write(level: LogLevel, msg: &Utf8CStr) { fn zygisk_log_write(level: LogLevel, msg: &Utf8CStr) {
unsafe { write_android_log(level_to_prio(level), msg);
__android_log_write(level_to_prio(level), raw_cstr!("Magisk"), msg.as_ptr());
}
zygisk_log_to_pipe(level_to_prio(level), msg); zygisk_log_to_pipe(level_to_prio(level), msg);
} }
@ -119,6 +113,19 @@ struct LogMeta {
tid: i32, tid: i32,
} }
fn print_log_error(msg: &str, e: io::Error) {
let mut buf = Utf8CStrBufArr::default();
buf.write_fmt(format_args_nl!("Error in {}: {}", msg, e))
.ok();
write_android_log(level_to_prio(LogLevel::Error), &buf);
}
fn write_android_log(prio: i32, msg: &Utf8CStr) {
unsafe {
__android_log_write(prio, raw_cstr!("Magisk"), msg.as_ptr());
}
}
const MAX_MSG_LEN: usize = PIPE_BUF - std::mem::size_of::<LogMeta>(); const MAX_MSG_LEN: usize = PIPE_BUF - std::mem::size_of::<LogMeta>();
fn write_log_to_pipe(logd: &mut File, prio: i32, msg: &Utf8CStr) -> io::Result<usize> { fn write_log_to_pipe(logd: &mut File, prio: i32, msg: &Utf8CStr) -> io::Result<usize> {
@ -154,7 +161,8 @@ fn magisk_log_to_pipe(prio: i32, msg: &Utf8CStr) {
let result = write_log_to_pipe(logd, prio, msg); let result = write_log_to_pipe(logd, prio, msg);
// If any error occurs, shut down the logd pipe // If any error occurs, shut down the logd pipe
if result.is_err() { if let Err(e) = result {
print_log_error("magisk_log", e);
*logd_ref = None; *logd_ref = None;
} }
} }
@ -179,6 +187,8 @@ fn zygisk_log_to_pipe(prio: i32, msg: &Utf8CStr) {
} }
let result = write_log_to_pipe(&mut logd, prio, msg); let result = write_log_to_pipe(&mut logd, prio, msg);
// Make sure the file descriptor is not closed after out of scope
logd.into_raw_fd();
// Consume SIGPIPE if exists, then restore mask // Consume SIGPIPE if exists, then restore mask
unsafe { unsafe {
@ -189,7 +199,8 @@ fn zygisk_log_to_pipe(prio: i32, msg: &Utf8CStr) {
} }
// If any error occurs, shut down the logd pipe // If any error occurs, shut down the logd pipe
if result.is_err() { if let Err(e) = result {
print_log_error("zygisk_log", e);
unsafe { unsafe {
zygisk_close_logd(); zygisk_close_logd();
} }
@ -318,13 +329,19 @@ extern "C" fn logfile_writer(arg: *mut c_void) -> *mut c_void {
impl MagiskD { impl MagiskD {
pub fn start_log_daemon(&self) { pub fn start_log_daemon(&self) {
let mut fds: [i32; 2] = [0; 2]; let mut buf = Utf8CStrBufArr::default();
let path = FsPathBuf::new(&mut buf)
.join(get_magisk_tmp())
.join(LOG_PIPE!());
unsafe { unsafe {
if pipe2(fds.as_mut_ptr(), O_CLOEXEC) == 0 { libc::mkfifo(path.as_ptr(), 0o200);
let logd = self.logd.lock().unwrap(); libc::chown(path.as_ptr(), 0, 0);
*logd.borrow_mut() = Some(File::from_raw_fd(fds[1])); let read = libc::open(path.as_ptr(), O_RDWR | O_CLOEXEC);
new_daemon_thread(logfile_writer, fds[0] as *mut c_void); let write = libc::open(path.as_ptr(), O_WRONLY | O_CLOEXEC);
} let logd = self.logd.lock().unwrap();
*logd.borrow_mut() = Some(File::from_raw_fd(write));
new_daemon_thread(logfile_writer, read as *mut c_void);
} }
} }

View File

@ -131,4 +131,7 @@ void restore_tmpcon() {
for (dirent *entry; (entry = xreaddir(dir.get()));) for (dirent *entry; (entry = xreaddir(dir.get()));)
setfilecon_at(dfd, entry->d_name, SYSTEM_CON); setfilecon_at(dfd, entry->d_name, SYSTEM_CON);
string logd = MAGISKTMP + "/" LOG_PIPE;
setfilecon(logd.data(), MAGISK_FILE_CON);
} }

View File

@ -6,3 +6,17 @@ macro_rules! LOGFILE {
"/cache/magisk.log" "/cache/magisk.log"
}; };
} }
#[macro_export]
macro_rules! INTLROOT {
() => {
".magisk"
};
}
#[macro_export]
macro_rules! LOG_PIPE {
() => {
concat!($crate::INTLROOT!(), "/log")
};
}

View File

@ -71,7 +71,7 @@ extern int app_process_32;
extern int app_process_64; extern int app_process_64;
extern std::vector<module_info> *module_list; extern std::vector<module_info> *module_list;
const char *get_magisk_tmp(); extern "C" const char *get_magisk_tmp();
int connect_daemon(int req, bool create = false); int connect_daemon(int req, bool create = false);
// Poll control // Poll control

View File

@ -26,6 +26,7 @@ extern std::string MAGISKTMP;
#define SELINUXMOCK INTLROOT "/selinux" #define SELINUXMOCK INTLROOT "/selinux"
#define MAIN_CONFIG INTLROOT "/config" #define MAIN_CONFIG INTLROOT "/config"
#define MAIN_SOCKET INTLROOT "/socket" #define MAIN_SOCKET INTLROOT "/socket"
#define LOG_PIPE INTLROOT "/log"
constexpr const char *applet_names[] = { "su", "resetprop", nullptr }; constexpr const char *applet_names[] = { "su", "resetprop", nullptr };