Linker namespace

This commit is contained in:
Nullptr
2023-02-08 16:38:39 +08:00
parent fb1ba93db8
commit f75d15c6f6
4 changed files with 89 additions and 11 deletions

View File

@@ -6,8 +6,9 @@ Warning: The current version of Zygisksu is UNSTABLE. You may suffer boot loop o
## Requirements ## Requirements
+ Minimal KernelSU version: 15 + Minimal KernelSU version: 10575
+ Minimal ksud version: 7b32c0e + Minimal ksud version: 10200
+ Full SELinux patch support (If non-gki kernel)
## Compatibility ## Compatibility
@@ -22,6 +23,7 @@ Warning: The current version of Zygisksu is UNSTABLE. You may suffer boot loop o
- [x] [Inject] Basic Zygisk loader - [x] [Inject] Basic Zygisk loader
- [x] [Inject] Stabilize injector - [x] [Inject] Stabilize injector
- [x] [Inject] Unload - [x] [Inject] Unload
- [x] [Daemon] Linker namespace
- [ ] [Daemon] Separate zygiskd process - [ ] [Daemon] Separate zygiskd process
- [ ] [Daemon] Handle 64 bit only devices - [ ] [Daemon] Handle 64 bit only devices
- [ ] [Daemon] Handle zygote death - [ ] [Daemon] Handle zygote death

82
zygiskd/src/dl.rs Normal file
View File

@@ -0,0 +1,82 @@
use anyhow::{bail, Result};
use std::ffi::{c_char, c_void};
use nix::libc;
const ANDROID_NAMESPACE_TYPE_SHARED: u64 = 0x2;
const ANDROID_DLEXT_USE_NAMESPACE: u64 = 0x200;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
struct AndroidNamespace {
_unused: [u8; 0],
}
#[repr(C)]
struct AndroidDlextinfo {
pub flags: u64,
pub reserved_addr: *mut c_void,
pub reserved_size: libc::size_t,
pub relro_fd: libc::c_int,
pub library_fd: libc::c_int,
pub library_fd_offset: libc::off64_t,
pub library_namespace: *mut AndroidNamespace,
}
extern "C" {
fn android_dlopen_ext(
filename: *const c_char,
flags: libc::c_int,
extinfo: *const AndroidDlextinfo,
) -> *mut c_void;
}
type AndroidCreateNamespaceFn = unsafe extern "C" fn(
*const c_char, // name
*const c_char, // ld_library_path
*const c_char, // default_library_path
u64, // type
*const c_char, // permitted_when_isolated_path
*mut AndroidNamespace, // parent
*const c_void, // caller_addr
) -> *mut AndroidNamespace;
pub unsafe fn dlopen(path: &str, flags: i32) -> Result<*mut c_void> {
let filename = std::ffi::CString::new(path)?;
let filename = filename.as_ptr() as *mut _;
let dir = libc::dirname(filename);
let mut info = AndroidDlextinfo {
flags: 0,
reserved_addr: std::ptr::null_mut(),
reserved_size: 0,
relro_fd: 0,
library_fd: 0,
library_fd_offset: 0,
library_namespace: std::ptr::null_mut(),
};
let android_create_namespace_fn = libc::dlsym(
libc::RTLD_DEFAULT,
std::ffi::CString::new("__loader_android_create_namespace")?.as_ptr(),
);
let android_create_namespace_fn: AndroidCreateNamespaceFn = std::mem::transmute(android_create_namespace_fn);
let ns = android_create_namespace_fn(
filename, dir, std::ptr::null(),
ANDROID_NAMESPACE_TYPE_SHARED,
std::ptr::null(), std::ptr::null_mut(),
&dlopen as *const _ as *const c_void,
);
if ns != std::ptr::null_mut() {
info.flags = ANDROID_DLEXT_USE_NAMESPACE;
info.library_namespace = ns;
log::debug!("Open {} with namespace {:p}", path, ns);
} else {
log::debug!("Cannot create namespace for {}", path);
};
let result = android_dlopen_ext(filename, flags, &info);
if result.is_null() {
let e = std::ffi::CStr::from_ptr(libc::dlerror()).to_string_lossy();
bail!("dlopen failed: {}", e);
}
Ok(result)
}

View File

@@ -1,6 +1,7 @@
#![allow(dead_code)] #![allow(dead_code)]
mod constants; mod constants;
mod dl;
mod utils; mod utils;
mod watchdog; mod watchdog;
mod zygisk; mod zygisk;

View File

@@ -1,6 +1,6 @@
use crate::constants::DaemonSocketAction; use crate::constants::DaemonSocketAction;
use crate::utils::{restore_native_bridge, UnixStreamExt}; use crate::utils::{restore_native_bridge, UnixStreamExt};
use crate::{constants, utils}; use crate::{constants, dl, utils};
use anyhow::{bail, Result}; use anyhow::{bail, Result};
use memfd::Memfd; use memfd::Memfd;
use nix::{ use nix::{
@@ -151,14 +151,7 @@ fn create_memfd(name: &str, so_path: &PathBuf) -> Result<Memfd> {
fn preload_module(memfd: &Memfd) -> Result<Option<ZygiskCompanionEntryFn>> { fn preload_module(memfd: &Memfd) -> Result<Option<ZygiskCompanionEntryFn>> {
unsafe { unsafe {
let path = format!("/proc/self/fd/{}", memfd.as_raw_fd()); let path = format!("/proc/self/fd/{}", memfd.as_raw_fd());
let filename = std::ffi::CString::new(path)?; let handle = dl::dlopen(&path, libc::RTLD_NOW)?;
let handle = libc::dlopen(filename.as_ptr(), libc::RTLD_LAZY);
if handle.is_null() {
let e = std::ffi::CStr::from_ptr(libc::dlerror())
.to_string_lossy()
.into_owned();
bail!("dlopen failed: {}", e);
}
let symbol = std::ffi::CString::new("zygisk_companion_entry")?; let symbol = std::ffi::CString::new("zygisk_companion_entry")?;
let entry = dlsym(handle, symbol.as_ptr()); let entry = dlsym(handle, symbol.as_ptr());
if entry.is_null() { if entry.is_null() {