mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-11-24 02:25:28 +00:00
Implement magiskinit logging in Rust
This commit is contained in:
parent
0d84f80b3c
commit
b136aba1e2
12
native/src/Cargo.lock
generated
12
native/src/Cargo.lock
generated
@ -13,9 +13,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.0.73"
|
version = "1.0.79"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
|
checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
@ -47,9 +47,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.127"
|
version = "0.2.142"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "505e71a4706fa491e9b1b55f51b95d4037d0821ee40131190475f692b35b009b"
|
checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "magisk"
|
name = "magisk"
|
||||||
@ -112,6 +112,6 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.2"
|
version = "1.0.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "15c61ba63f9235225a22310255a29b806b907c9b8c964bcbd0a2c70f3f2deea7"
|
checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4"
|
||||||
|
@ -53,20 +53,20 @@ pub fn __xopen_fd_impl(path: &CStr, flags: i32, mode: mode_t) -> Option<OwnedFd>
|
|||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! open_fd {
|
macro_rules! open_fd {
|
||||||
($path:expr, $flags:expr) => {
|
($path:expr, $flags:expr) => {
|
||||||
crate::__open_fd_impl($path, $flags, 0)
|
$crate::__open_fd_impl($path, $flags, 0)
|
||||||
};
|
};
|
||||||
($path:expr, $flags:expr, $mode:expr) => {
|
($path:expr, $flags:expr, $mode:expr) => {
|
||||||
crate::__open_fd_impl($path, $flags, $mode)
|
$crate::__open_fd_impl($path, $flags, $mode)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! xopen_fd {
|
macro_rules! xopen_fd {
|
||||||
($path:expr, $flags:expr) => {
|
($path:expr, $flags:expr) => {
|
||||||
crate::__xopen_fd_impl($path, $flags, 0)
|
$crate::__xopen_fd_impl($path, $flags, 0)
|
||||||
};
|
};
|
||||||
($path:expr, $flags:expr, $mode:expr) => {
|
($path:expr, $flags:expr, $mode:expr) => {
|
||||||
crate::__xopen_fd_impl($path, $flags, $mode)
|
$crate::__xopen_fd_impl($path, $flags, $mode)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,13 @@ use std::ffi::CStr;
|
|||||||
use std::fmt::Arguments;
|
use std::fmt::Arguments;
|
||||||
use std::{fmt, slice};
|
use std::{fmt, slice};
|
||||||
|
|
||||||
|
pub fn copy_str(dest: &mut [u8], src: &[u8]) -> usize {
|
||||||
|
let len = min(src.len(), dest.len() - 1);
|
||||||
|
dest[..len].copy_from_slice(&src[..len]);
|
||||||
|
dest[len] = b'\0';
|
||||||
|
len
|
||||||
|
}
|
||||||
|
|
||||||
struct BufFmtWriter<'a> {
|
struct BufFmtWriter<'a> {
|
||||||
buf: &'a mut [u8],
|
buf: &'a mut [u8],
|
||||||
used: usize,
|
used: usize,
|
||||||
@ -21,12 +28,7 @@ impl<'a> fmt::Write for BufFmtWriter<'a> {
|
|||||||
// Silent truncate
|
// Silent truncate
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
let remain = &mut self.buf[self.used..];
|
self.used += copy_str(&mut self.buf[self.used..], s.as_bytes());
|
||||||
let s_bytes = s.as_bytes();
|
|
||||||
let copied = min(s_bytes.len(), remain.len() - 1);
|
|
||||||
remain[..copied].copy_from_slice(&s_bytes[..copied]);
|
|
||||||
self.used += copied;
|
|
||||||
self.buf[self.used] = b'\0';
|
|
||||||
// Silent truncate
|
// Silent truncate
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -107,6 +109,13 @@ macro_rules! cstr {
|
|||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! str_ptr {
|
||||||
|
($s:literal) => {{
|
||||||
|
cstr!($s).as_ptr()
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
pub fn ptr_to_str<'a, T>(ptr: *const T) -> &'a str {
|
pub fn ptr_to_str<'a, T>(ptr: *const T) -> &'a str {
|
||||||
if ptr.is_null() {
|
if ptr.is_null() {
|
||||||
"(null)"
|
"(null)"
|
||||||
|
@ -117,55 +117,6 @@ static bool check_key_combo() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static FILE *kmsg;
|
|
||||||
extern "C" void klog_write(const char *msg, int len) {
|
|
||||||
fprintf(kmsg, "%.*s", len, msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int klog_with_rs(LogLevel level, const char *fmt, va_list ap) {
|
|
||||||
char buf[4096];
|
|
||||||
strscpy(buf, "magiskinit: ", sizeof(buf));
|
|
||||||
int len = vssprintf(buf + 12, sizeof(buf) - 12, fmt, ap) + 12;
|
|
||||||
log_with_rs(level, rust::Str(buf, len));
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setup_klog() {
|
|
||||||
// Shut down first 3 fds
|
|
||||||
int fd;
|
|
||||||
if (access("/dev/null", W_OK) == 0) {
|
|
||||||
fd = xopen("/dev/null", O_RDWR | O_CLOEXEC);
|
|
||||||
} else {
|
|
||||||
mknod("/null", S_IFCHR | 0666, makedev(1, 3));
|
|
||||||
fd = xopen("/null", O_RDWR | O_CLOEXEC);
|
|
||||||
unlink("/null");
|
|
||||||
}
|
|
||||||
xdup3(fd, STDIN_FILENO, O_CLOEXEC);
|
|
||||||
xdup3(fd, STDOUT_FILENO, O_CLOEXEC);
|
|
||||||
xdup3(fd, STDERR_FILENO, O_CLOEXEC);
|
|
||||||
if (fd > STDERR_FILENO)
|
|
||||||
close(fd);
|
|
||||||
|
|
||||||
if (access("/dev/kmsg", W_OK) == 0) {
|
|
||||||
fd = xopen("/dev/kmsg", O_WRONLY | O_CLOEXEC);
|
|
||||||
} else {
|
|
||||||
mknod("/kmsg", S_IFCHR | 0666, makedev(1, 11));
|
|
||||||
fd = xopen("/kmsg", O_WRONLY | O_CLOEXEC);
|
|
||||||
unlink("/kmsg");
|
|
||||||
}
|
|
||||||
|
|
||||||
kmsg = fdopen(fd, "w");
|
|
||||||
setbuf(kmsg, nullptr);
|
|
||||||
rust::setup_klog();
|
|
||||||
cpp_logger = klog_with_rs;
|
|
||||||
|
|
||||||
// Disable kmsg rate limiting
|
|
||||||
if (FILE *rate = fopen("/proc/sys/kernel/printk_devkmsg", "w")) {
|
|
||||||
fprintf(rate, "on\n");
|
|
||||||
fclose(rate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void BootConfig::set(const kv_pairs &kv) {
|
void BootConfig::set(const kv_pairs &kv) {
|
||||||
for (const auto &[key, value] : kv) {
|
for (const auto &[key, value] : kv) {
|
||||||
if (key == "androidboot.slot_suffix") {
|
if (key == "androidboot.slot_suffix") {
|
||||||
@ -231,7 +182,7 @@ void load_kernel_info(BootConfig *config) {
|
|||||||
mount_list.emplace_back("/sys");
|
mount_list.emplace_back("/sys");
|
||||||
|
|
||||||
// Log to kernel
|
// Log to kernel
|
||||||
setup_klog();
|
rust::setup_klog();
|
||||||
|
|
||||||
config->set(parse_cmdline(full_read("/proc/cmdline")));
|
config->set(parse_cmdline(full_read("/proc/cmdline")));
|
||||||
config->set(parse_bootconfig(full_read("/proc/bootconfig")));
|
config->set(parse_bootconfig(full_read("/proc/bootconfig")));
|
||||||
|
@ -90,6 +90,7 @@ int main(int argc, char *argv[]) {
|
|||||||
BootConfig config{};
|
BootConfig config{};
|
||||||
|
|
||||||
if (argc > 1 && argv[1] == "selinux_setup"sv) {
|
if (argc > 1 && argv[1] == "selinux_setup"sv) {
|
||||||
|
rust::setup_klog();
|
||||||
init = new SecondStageInit(argv);
|
init = new SecondStageInit(argv);
|
||||||
} else {
|
} else {
|
||||||
// This will also mount /sys and /proc
|
// This will also mount /sys and /proc
|
||||||
|
@ -28,7 +28,6 @@ int magisk_proxy_main(int argc, char *argv[]);
|
|||||||
bool unxz(int fd, const uint8_t *buf, size_t size);
|
bool unxz(int fd, const uint8_t *buf, size_t size);
|
||||||
void load_kernel_info(BootConfig *config);
|
void load_kernel_info(BootConfig *config);
|
||||||
bool check_two_stage();
|
bool check_two_stage();
|
||||||
void setup_klog();
|
|
||||||
const char *backup_init();
|
const char *backup_init();
|
||||||
void restore_ramdisk_init();
|
void restore_ramdisk_init();
|
||||||
int dump_preload(const char *path, mode_t mode);
|
int dump_preload(const char *path, mode_t mode);
|
||||||
@ -87,7 +86,6 @@ private:
|
|||||||
bool prepare();
|
bool prepare();
|
||||||
public:
|
public:
|
||||||
SecondStageInit(char *argv[]) : MagiskInit(argv) {
|
SecondStageInit(char *argv[]) : MagiskInit(argv) {
|
||||||
setup_klog();
|
|
||||||
LOGD("%s\n", __FUNCTION__);
|
LOGD("%s\n", __FUNCTION__);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,27 +1,69 @@
|
|||||||
use base::ffi::LogLevel;
|
|
||||||
use base::*;
|
|
||||||
use std::fmt::Arguments;
|
use std::fmt::Arguments;
|
||||||
|
use std::fs;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::Write;
|
||||||
|
use std::sync::OnceLock;
|
||||||
|
|
||||||
extern "C" {
|
use base::ffi::LogLevel;
|
||||||
fn klog_write(msg: *const u8, len: i32);
|
use base::libc::{
|
||||||
}
|
close, makedev, mknod, open, syscall, unlink, SYS_dup3, O_CLOEXEC, O_RDWR, STDERR_FILENO,
|
||||||
|
STDIN_FILENO, STDOUT_FILENO, S_IFCHR,
|
||||||
|
};
|
||||||
|
use base::*;
|
||||||
|
|
||||||
|
static KMSG: OnceLock<File> = OnceLock::new();
|
||||||
|
|
||||||
pub fn setup_klog() {
|
pub fn setup_klog() {
|
||||||
const PREFIX: &[u8; 12] = b"magiskinit: ";
|
// Shut down first 3 fds
|
||||||
const PFX_LEN: usize = PREFIX.len();
|
unsafe {
|
||||||
|
let mut fd = open(str_ptr!("/dev/null"), O_RDWR | O_CLOEXEC);
|
||||||
|
if fd < 0 {
|
||||||
|
mknod(str_ptr!("/null"), S_IFCHR | 0666, makedev(1, 3));
|
||||||
|
fd = open(str_ptr!("/null"), O_RDWR | O_CLOEXEC);
|
||||||
|
fs::remove_file("/null").ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
syscall(SYS_dup3, fd, STDIN_FILENO, O_CLOEXEC);
|
||||||
|
syscall(SYS_dup3, fd, STDOUT_FILENO, O_CLOEXEC);
|
||||||
|
syscall(SYS_dup3, fd, STDERR_FILENO, O_CLOEXEC);
|
||||||
|
if fd > STDERR_FILENO {
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Ok(kmsg) = File::options().write(true).open("/dev/kmsg") {
|
||||||
|
KMSG.set(kmsg).ok();
|
||||||
|
} else {
|
||||||
|
unsafe {
|
||||||
|
mknod(str_ptr!("/kmsg"), S_IFCHR | 0666, makedev(1, 11));
|
||||||
|
KMSG.set(File::options().write(true).open("/kmsg").unwrap())
|
||||||
|
.ok();
|
||||||
|
unlink(str_ptr!("/kmsg"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disable kmsg rate limiting
|
||||||
|
if let Ok(mut rate) = File::options()
|
||||||
|
.write(true)
|
||||||
|
.open("/proc/sys/kernel/printk_devkmsg")
|
||||||
|
{
|
||||||
|
writeln!(rate, "on").ok();
|
||||||
|
}
|
||||||
|
|
||||||
fn klog_fmt(_: LogLevel, args: Arguments) {
|
fn klog_fmt(_: LogLevel, args: Arguments) {
|
||||||
let mut buf: [u8; 4096] = [0; 4096];
|
if let Some(kmsg) = KMSG.get().as_mut() {
|
||||||
buf[..PFX_LEN].copy_from_slice(PREFIX);
|
let mut buf: [u8; 4096] = [0; 4096];
|
||||||
let len = fmt_to_buf(&mut buf[PFX_LEN..], args) + PFX_LEN;
|
let len = fmt_to_buf(&mut buf, format_args!("magiskinit: {}", args));
|
||||||
unsafe {
|
kmsg.write_all(&buf[..len]).ok();
|
||||||
klog_write(buf.as_ptr(), len as i32);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn klog_write_impl(_: LogLevel, msg: &[u8]) {
|
fn klog_write_impl(_: LogLevel, msg: &[u8]) {
|
||||||
unsafe {
|
if let Some(kmsg) = KMSG.get().as_mut() {
|
||||||
klog_write(msg.as_ptr(), msg.len() as i32);
|
let mut buf: [u8; 4096] = [0; 4096];
|
||||||
|
let mut len = copy_str(&mut buf, b"magiskinit: ");
|
||||||
|
len += copy_str(&mut buf[len..], msg);
|
||||||
|
kmsg.write_all(&buf[..len]).ok();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -349,7 +349,7 @@ void MagiskInit::patch_rw_root() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int magisk_proxy_main(int argc, char *argv[]) {
|
int magisk_proxy_main(int argc, char *argv[]) {
|
||||||
setup_klog();
|
rust::setup_klog();
|
||||||
LOGD("%s\n", __FUNCTION__);
|
LOGD("%s\n", __FUNCTION__);
|
||||||
|
|
||||||
// Mount rootfs as rw to do post-init rootfs patches
|
// Mount rootfs as rw to do post-init rootfs patches
|
||||||
|
Loading…
Reference in New Issue
Block a user