Cleanup code and bindings

This commit is contained in:
topjohnwu
2025-02-02 12:57:09 +08:00
committed by John Wu
parent a786801141
commit 0469817781
13 changed files with 125 additions and 198 deletions

View File

@@ -18,7 +18,6 @@ LOCAL_SRC_FILES := \
core/applets.cpp \
core/magisk.cpp \
core/daemon.cpp \
core/socket.cpp \
core/scripting.cpp \
core/selinux.cpp \
core/sqlite.cpp \

View File

@@ -136,6 +136,38 @@ void MagiskD::reboot() const noexcept {
exec_command_sync("/system/bin/reboot");
}
bool get_client_cred(int fd, sock_cred *cred) {
socklen_t len = sizeof(ucred);
if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, cred, &len) != 0)
return false;
char buf[4096];
len = sizeof(buf);
if (getsockopt(fd, SOL_SOCKET, SO_PEERSEC, buf, &len) != 0)
len = 0;
buf[len] = '\0';
cred->context = buf;
return true;
}
bool read_string(int fd, std::string &str) {
str.clear();
auto len = read_any<size_t>(fd);
str.resize(len);
return xxread(fd, str.data(), len) == len;
}
string read_string(int fd) {
string str;
read_string(fd, str);
return str;
}
void write_string(int fd, string_view str) {
if (fd < 0) return;
write_any(fd, str.size());
xwrite(fd, str.data(), str.size());
}
static void handle_request_async(int client, int code, const sock_cred &cred) {
auto &daemon = MagiskD::Get();
switch (code) {

View File

@@ -91,10 +91,6 @@ impl MagiskD {
self.sdk_int
}
pub fn set_module_list(&self, module_list: Vec<ModuleInfo>) {
self.module_list.set(module_list).ok();
}
pub fn app_data_dir(&self) -> &'static Utf8CStr {
if self.sdk_int >= 24 {
cstr!("/data/user_de")
@@ -152,7 +148,8 @@ impl MagiskD {
);
initialize_denylist();
setup_mounts();
self.handle_modules();
let modules = self.handle_modules();
self.module_list.set(modules).ok();
false
}

View File

@@ -1,11 +1,12 @@
#![allow(improper_ctypes, improper_ctypes_definitions)]
use crate::daemon::{MagiskD, MAGISKD};
use crate::ffi::{
open_and_init_db, sqlite3, sqlite3_errstr, DbEntryKey, DbSettings, DbStatement, DbValues,
MntNsMode, MultiuserMode, RootAccess,
open_and_init_db, sqlite3, sqlite3_errstr, DbEntryKey, DbStatement, DbValues, MntNsMode,
};
use crate::socket::{IpcRead, IpcWrite};
use base::{LoggedResult, ResultExt, Utf8CStr};
use num_derive::FromPrimitive;
use num_traits::FromPrimitive;
use std::ffi::c_void;
use std::fs::File;
use std::io::{BufReader, BufWriter};
@@ -55,16 +56,33 @@ where
}
}
impl Default for RootAccess {
fn default() -> Self {
RootAccess::AppsAndAdb
}
#[derive(Default)]
pub struct DbSettings {
pub root_access: RootAccess,
pub multiuser_mode: MultiuserMode,
pub mnt_ns: MntNsMode,
pub boot_count: i32,
pub denylist: bool,
pub zygisk: bool,
}
impl Default for MultiuserMode {
fn default() -> Self {
MultiuserMode::OwnerOnly
}
#[repr(i32)]
#[derive(Default, FromPrimitive)]
pub enum RootAccess {
Disabled,
AppsOnly,
AdbOnly,
#[default]
AppsAndAdb,
}
#[repr(i32)]
#[derive(Default, FromPrimitive)]
pub enum MultiuserMode {
#[default]
OwnerOnly,
OwnerManaged,
User,
}
impl Default for MntNsMode {
@@ -100,8 +118,10 @@ impl SqlTable for DbSettings {
}
}
match key {
"root_access" => self.root_access = RootAccess { repr: value },
"multiuser_mode" => self.multiuser_mode = MultiuserMode { repr: value },
"root_access" => self.root_access = RootAccess::from_i32(value).unwrap_or_default(),
"multiuser_mode" => {
self.multiuser_mode = MultiuserMode::from_i32(value).unwrap_or_default()
}
"mnt_ns" => self.mnt_ns = MntNsMode { repr: value },
"denylist" => self.denylist = value != 0,
"zygisk" => self.zygisk = value != 0,
@@ -226,8 +246,8 @@ impl MagiskD {
pub fn get_db_setting(&self, key: DbEntryKey) -> i32 {
// Get default values
let mut val = match key {
DbEntryKey::RootAccess => RootAccess::default().repr,
DbEntryKey::SuMultiuserMode => MultiuserMode::default().repr,
DbEntryKey::RootAccess => RootAccess::default() as i32,
DbEntryKey::SuMultiuserMode => MultiuserMode::default() as i32,
DbEntryKey::SuMntNs => MntNsMode::default().repr,
DbEntryKey::DenylistConfig => 0,
DbEntryKey::ZygiskConfig => self.is_emulator as i32,
@@ -302,14 +322,6 @@ impl MagiskD {
}
impl MagiskD {
pub fn get_db_settings_for_cxx(&self, cfg: &mut DbSettings) -> bool {
cfg.zygisk = self.is_emulator;
self.db_exec_with_rows("SELECT * FROM settings", &[], cfg)
.sql_result()
.log()
.is_ok()
}
pub fn set_db_setting_for_cxx(&self, key: DbEntryKey, value: i32) -> bool {
self.set_db_setting(key, value).log().is_ok()
}

View File

@@ -1,5 +1,6 @@
#pragma once
#include <sys/socket.h>
#include <pthread.h>
#include <poll.h>
#include <string>
@@ -9,7 +10,6 @@
#include <base.hpp>
#include "socket.hpp"
#include "../core-rs.hpp"
#define AID_ROOT 0
@@ -40,6 +40,45 @@ bool setup_magisk_env();
bool check_key_combo();
void restore_zygisk_prop();
// Sockets
struct sock_cred : public ucred {
std::string context;
};
template<typename T> requires(std::is_trivially_copyable_v<T>)
T read_any(int fd) {
T val;
if (xxread(fd, &val, sizeof(val)) != sizeof(val))
return -1;
return val;
}
template<typename T> requires(std::is_trivially_copyable_v<T>)
void write_any(int fd, T val) {
if (fd < 0) return;
xwrite(fd, &val, sizeof(val));
}
template<typename T> requires(std::is_trivially_copyable_v<T>)
void write_vector(int fd, const std::vector<T> &vec) {
write_any(fd, vec.size());
xwrite(fd, vec.data(), vec.size() * sizeof(T));
}
template<typename T> requires(std::is_trivially_copyable_v<T>)
bool read_vector(int fd, std::vector<T> &vec) {
auto size = read_any<size_t>(fd);
vec.resize(size);
return xread(fd, vec.data(), size * sizeof(T)) == size * sizeof(T);
}
bool get_client_cred(int fd, sock_cred *cred);
static inline int read_int(int fd) { return read_any<int>(fd); }
static inline void write_int(int fd, int val) { write_any(fd, val); }
std::string read_string(int fd);
bool read_string(int fd, std::string &str);
void write_string(int fd, std::string_view str);
// Poll control
using poll_callback = void(*)(pollfd*);
void register_poll(const pollfd *pfd, poll_callback callback);

View File

@@ -1,49 +0,0 @@
#pragma once
#include <sys/un.h>
#include <sys/socket.h>
#include <string_view>
#include <string>
#include <vector>
#include <base.hpp>
struct sock_cred : public ucred {
std::string context;
};
template<typename T> requires(std::is_trivially_copyable_v<T>)
T read_any(int fd) {
T val;
if (xxread(fd, &val, sizeof(val)) != sizeof(val))
return -1;
return val;
}
template<typename T> requires(std::is_trivially_copyable_v<T>)
void write_any(int fd, T val) {
if (fd < 0) return;
xwrite(fd, &val, sizeof(val));
}
template<typename T> requires(std::is_trivially_copyable_v<T>)
void write_vector(int fd, const std::vector<T> &vec) {
write_any(fd, vec.size());
xwrite(fd, vec.data(), vec.size() * sizeof(T));
}
template<typename T> requires(std::is_trivially_copyable_v<T>)
bool read_vector(int fd, std::vector<T> &vec) {
auto size = read_any<size_t>(fd);
vec.resize(size);
return xread(fd, vec.data(), size * sizeof(T)) == size * sizeof(T);
}
bool get_client_cred(int fd, sock_cred *cred);
static inline int read_int(int fd) { return read_any<int>(fd); }
int read_int_be(int fd);
static inline void write_int(int fd, int val) { write_any(fd, val); }
void write_int_be(int fd, int val);
std::string read_string(int fd);
bool read_string(int fd, std::string &str);
void write_string(int fd, std::string_view str);

View File

@@ -34,6 +34,7 @@ mod socket;
mod su;
mod zygisk;
#[allow(clippy::needless_lifetimes)]
#[cxx::bridge]
pub mod ffi {
#[repr(i32)]
@@ -71,21 +72,6 @@ pub mod ffi {
SuManager,
}
#[repr(i32)]
enum RootAccess {
Disabled,
AppsOnly,
AdbOnly,
AppsAndAdb,
}
#[repr(i32)]
enum MultiuserMode {
OwnerOnly,
OwnerManaged,
User,
}
#[repr(i32)]
enum MntNsMode {
Global,
@@ -93,16 +79,6 @@ pub mod ffi {
Isolate,
}
#[derive(Default)]
struct DbSettings {
root_access: RootAccess,
multiuser_mode: MultiuserMode,
mnt_ns: MntNsMode,
boot_count: i32,
denylist: bool,
zygisk: bool,
}
#[repr(i32)]
enum SuPolicy {
Query,
@@ -110,12 +86,6 @@ pub mod ffi {
Allow,
}
struct RootSettings {
policy: SuPolicy,
log: bool,
notify: bool,
}
struct ModuleInfo {
name: String,
z32: i32,
@@ -242,14 +212,6 @@ pub mod ffi {
// Default constructors
extern "Rust" {
#[Self = DbSettings]
#[cxx_name = "New"]
fn default() -> DbSettings;
#[Self = RootSettings]
#[cxx_name = "New"]
fn default() -> RootSettings;
#[Self = SuRequest]
#[cxx_name = "New"]
fn default() -> SuRequest;
@@ -268,17 +230,12 @@ pub mod ffi {
fn su_daemon_handler(&self, client: i32, cred: &UCred);
#[cxx_name = "get_manager"]
unsafe fn get_manager_for_cxx(&self, user: i32, ptr: *mut CxxString, install: bool) -> i32;
fn set_module_list(&self, module_list: Vec<ModuleInfo>);
#[cxx_name = "get_db_settings"]
fn get_db_settings_for_cxx(&self, cfg: &mut DbSettings) -> bool;
fn get_db_setting(&self, key: DbEntryKey) -> i32;
#[cxx_name = "set_db_setting"]
fn set_db_setting_for_cxx(&self, key: DbEntryKey, value: i32) -> bool;
#[cxx_name = "db_exec"]
fn db_exec_for_cxx(&self, client_fd: i32);
#[cxx_name = "get_root_settings"]
fn get_root_settings_for_cxx(&self, uid: i32, settings: &mut RootSettings) -> bool;
#[Self = MagiskD]
#[cxx_name = "Get"]
@@ -287,7 +244,7 @@ pub mod ffi {
unsafe extern "C++" {
#[allow(dead_code)]
fn reboot(self: &MagiskD);
fn handle_modules(self: &MagiskD);
fn handle_modules(self: &MagiskD) -> Vec<ModuleInfo>;
}
}

View File

@@ -466,22 +466,20 @@ static rust::Vec<ModuleInfo> collect_modules(bool zygisk_enabled, bool open_zygi
};
std::for_each(modules.begin(),modules.end(), [&](ModuleInfo &info) {
info.z32 = convert_to_memfd(info.z32);
#if defined(__LP64__)
info.z64 = convert_to_memfd(info.z64);
#endif
});
}
return modules;
}
void MagiskD::handle_modules() const noexcept {
rust::Vec<ModuleInfo> MagiskD::handle_modules() const noexcept {
bool zygisk = zygisk_enabled();
prepare_modules();
exec_module_scripts("post-fs-data", collect_modules(zygisk, false));
// Recollect modules (module scripts could remove itself)
auto list = collect_modules(zygisk, true);
load_modules(zygisk, list);
set_module_list(std::move(list));
return list;
}
static int check_rules_dir(char *buf, size_t sz) {

View File

@@ -1,47 +0,0 @@
#include <fcntl.h>
#include <endian.h>
#include <socket.hpp>
#include <base.hpp>
using namespace std;
bool get_client_cred(int fd, sock_cred *cred) {
socklen_t len = sizeof(ucred);
if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, cred, &len) != 0)
return false;
char buf[4096];
len = sizeof(buf);
if (getsockopt(fd, SOL_SOCKET, SO_PEERSEC, buf, &len) != 0)
len = 0;
buf[len] = '\0';
cred->context = buf;
return true;
}
int read_int_be(int fd) {
return ntohl(read_int(fd));
}
void write_int_be(int fd, int val) {
write_int(fd, htonl(val));
}
bool read_string(int fd, std::string &str) {
str.clear();
auto len = read_any<size_t>(fd);
str.resize(len);
return xxread(fd, str.data(), len) == len;
}
string read_string(int fd) {
string str;
read_string(fd, str);
return str;
}
void write_string(int fd, string_view str) {
if (fd < 0) return;
write_any(fd, str.size());
xwrite(fd, str.data(), str.size());
}

View File

@@ -87,11 +87,11 @@ impl<T: Decodable> Decodable for Vec<T> {
impl Encodable for str {
fn encoded_len(&self) -> usize {
size_of::<usize>() + self.as_bytes().len()
size_of::<usize>() + self.len()
}
fn encode(&self, w: &mut impl Write) -> io::Result<()> {
self.as_bytes().len().encode(w)?;
self.len().encode(w)?;
w.write_all(self.as_bytes())
}
}

View File

@@ -20,11 +20,6 @@ using namespace std;
// 0x18800020 = FLAG_ACTIVITY_NEW_TASK|FLAG_ACTIVITY_MULTIPLE_TASK|
// FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS|FLAG_INCLUDE_STOPPED_PACKAGES
#define get_cmd(to) \
((to).command.empty() ? \
((to).shell.empty() ? DEFAULT_SHELL : (to).shell.data()) : \
(to).command.data())
class Extra {
const char *key;
enum {

View File

@@ -1,9 +1,10 @@
use crate::daemon::{to_app_id, to_user_id, MagiskD, AID_ROOT, AID_SHELL};
use crate::db::{DbSettings, MultiuserMode, RootAccess};
use crate::ffi::{
app_log, app_notify, app_request, exec_root_shell, DbSettings, MultiuserMode, RootAccess,
RootSettings, SuAppRequest, SuPolicy, SuRequest,
app_log, app_notify, app_request, exec_root_shell, SuAppRequest, SuPolicy, SuRequest,
};
use crate::socket::IpcRead;
use crate::su::db::RootSettings;
use crate::UCred;
use base::{debug, error, exit_on_error, libc, warn, LoggedResult, ResultExt, WriteExt};
use std::fs::File;
@@ -133,7 +134,7 @@ impl MagiskD {
let info = self.get_su_info(cred.uid as i32);
let app_req = SuAppRequest {
uid: cred.uid as i32,
pid: cred.pid as i32,
pid: cred.pid,
eval_uid: info.eval_uid,
mgr_pkg: &info.mgr_pkg,
mgr_uid: info.mgr_uid,

View File

@@ -2,8 +2,8 @@ use crate::daemon::{
to_app_id, to_user_id, MagiskD, AID_APP_END, AID_APP_START, AID_ROOT, AID_SHELL,
};
use crate::db::DbArg::Integer;
use crate::db::{SqlTable, SqliteResult, SqliteReturn};
use crate::ffi::{DbValues, MultiuserMode, RootAccess, RootSettings, SuPolicy};
use crate::db::{MultiuserMode, RootAccess, SqlTable, SqliteResult, SqliteReturn};
use crate::ffi::{DbValues, SuPolicy};
use base::ResultExt;
impl Default for SuPolicy {
@@ -12,14 +12,11 @@ impl Default for SuPolicy {
}
}
impl Default for RootSettings {
fn default() -> Self {
RootSettings {
policy: Default::default(),
log: true,
notify: true,
}
}
#[derive(Default)]
pub struct RootSettings {
pub policy: SuPolicy,
pub log: bool,
pub notify: bool,
}
impl SqlTable for RootSettings {
@@ -56,10 +53,6 @@ impl MagiskD {
.sql_result()
}
pub fn get_root_settings_for_cxx(&self, uid: i32, settings: &mut RootSettings) -> bool {
self.get_root_settings(uid, settings).log().is_ok()
}
pub fn prune_su_access(&self) {
let mut list = UidList(Vec::new());
if self