mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-01-12 09:43:36 +00:00
Migrate prune_su_access to Rust
This commit is contained in:
parent
5637a258fc
commit
4d4195c02d
@ -20,7 +20,6 @@ LOCAL_SRC_FILES := \
|
||||
core/daemon.cpp \
|
||||
core/bootstages.cpp \
|
||||
core/socket.cpp \
|
||||
core/package.cpp \
|
||||
core/scripting.cpp \
|
||||
core/selinux.cpp \
|
||||
core/sqlite.cpp \
|
||||
|
16
native/src/Cargo.lock
generated
16
native/src/Cargo.lock
generated
@ -70,6 +70,21 @@ version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
|
||||
|
||||
[[package]]
|
||||
name = "bit-set"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3"
|
||||
dependencies = [
|
||||
"bit-vec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bit-vec"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7"
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.11.0-rc.3"
|
||||
@ -442,6 +457,7 @@ name = "magisk"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"base",
|
||||
"bit-set",
|
||||
"bytemuck",
|
||||
"cxx",
|
||||
"cxx-gen",
|
||||
|
@ -25,6 +25,7 @@ der = "0.8.0-rc.1"
|
||||
bytemuck = "1.16"
|
||||
fdt = "0.1"
|
||||
const_format = "0.2"
|
||||
bit-set = "0.8"
|
||||
|
||||
[workspace.dependencies.argh]
|
||||
git = "https://github.com/google/argh.git"
|
||||
|
@ -23,3 +23,4 @@ num-derive = { workspace = true }
|
||||
quick-protobuf = { workspace = true }
|
||||
bytemuck = { workspace = true, features = ["derive"] }
|
||||
thiserror = { workspace = true }
|
||||
bit-set = { workspace = true }
|
||||
|
@ -144,7 +144,7 @@ static void handle_request_async(int client, int code, const sock_cred &cred) {
|
||||
break;
|
||||
case +RequestCode::ZYGOTE_RESTART:
|
||||
LOGI("** zygote restarted\n");
|
||||
prune_su_access();
|
||||
MagiskD().prune_su_access();
|
||||
scan_deny_apps();
|
||||
reset_zygisk(false);
|
||||
close(client);
|
||||
|
@ -5,7 +5,11 @@ use crate::get_prop;
|
||||
use crate::logging::{magisk_logging, start_log_daemon};
|
||||
use crate::package::ManagerInfo;
|
||||
use base::libc::{O_CLOEXEC, O_RDONLY};
|
||||
use base::{cstr, info, libc, open_fd, BufReadExt, FsPath, FsPathBuf, ReadExt, Utf8CStrBufArr};
|
||||
use base::{
|
||||
cstr, info, libc, open_fd, BufReadExt, DirEntry, Directory, FsPath, FsPathBuf, LoggedResult,
|
||||
ReadExt, Utf8CStr, Utf8CStrBufArr,
|
||||
};
|
||||
use bit_set::BitSet;
|
||||
use bytemuck::bytes_of;
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
@ -37,6 +41,8 @@ impl BootStateFlags {
|
||||
}
|
||||
}
|
||||
|
||||
pub const AID_APP_START: i32 = 10000;
|
||||
pub const AID_APP_END: i32 = 19999;
|
||||
pub const AID_USER_OFFSET: i32 = 100000;
|
||||
|
||||
pub const fn to_app_id(uid: i32) -> i32 {
|
||||
@ -62,14 +68,48 @@ impl MagiskD {
|
||||
self.sdk_int
|
||||
}
|
||||
|
||||
pub fn app_data_dir(&self) -> &'static str {
|
||||
pub fn app_data_dir(&self) -> &'static Utf8CStr {
|
||||
if self.sdk_int >= 24 {
|
||||
"/data/user_de"
|
||||
cstr!("/data/user_de")
|
||||
} else {
|
||||
"/data/user"
|
||||
cstr!("/data/user")
|
||||
}
|
||||
}
|
||||
|
||||
// app_id = app_no + AID_APP_START
|
||||
// app_no range: [0, 9999]
|
||||
pub fn get_app_no_list(&self) -> BitSet {
|
||||
let mut list = BitSet::new();
|
||||
let _: LoggedResult<()> = try {
|
||||
let mut dir = Directory::open(self.app_data_dir())?;
|
||||
// For each user
|
||||
loop {
|
||||
let entry: DirEntry;
|
||||
match dir.read()? {
|
||||
None => break,
|
||||
Some(e) => entry = e,
|
||||
}
|
||||
if let Ok(mut dir) = entry.open_as_dir() {
|
||||
// For each package
|
||||
loop {
|
||||
match dir.read()? {
|
||||
None => break,
|
||||
Some(e) => {
|
||||
let attr = e.get_attr()?;
|
||||
let app_id = to_app_id(attr.st.st_uid as i32);
|
||||
if app_id >= AID_APP_START && app_id <= AID_APP_END {
|
||||
let app_no = app_id - AID_APP_START;
|
||||
list.insert(app_no as usize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
list
|
||||
}
|
||||
|
||||
pub fn boot_stage_handler(&self, client: i32, code: i32) {
|
||||
// Make sure boot stage execution is always serialized
|
||||
let mut state = self.boot_stage_lock.lock().unwrap();
|
||||
|
@ -213,7 +213,7 @@ impl MagiskD {
|
||||
)
|
||||
}
|
||||
|
||||
fn db_exec(&self, sql: &str, args: &[DbArg]) -> i32 {
|
||||
pub fn db_exec(&self, sql: &str, args: &[DbArg]) -> i32 {
|
||||
self.db_exec_impl(sql, args, None, ptr::null_mut())
|
||||
}
|
||||
|
||||
@ -308,10 +308,6 @@ impl MagiskD {
|
||||
self.set_db_setting(key, value).log().is_ok()
|
||||
}
|
||||
|
||||
pub fn rm_db_string_for_cxx(&self, key: DbEntryKey) -> bool {
|
||||
self.rm_db_string(key).log().is_ok()
|
||||
}
|
||||
|
||||
pub fn db_exec_for_cxx(&self, client_fd: RawFd) {
|
||||
// Take ownership
|
||||
let fd = unsafe { OwnedFd::from_raw_fd(client_fd) };
|
||||
|
@ -12,8 +12,6 @@
|
||||
|
||||
#define AID_ROOT 0
|
||||
#define AID_SHELL 2000
|
||||
#define AID_APP_START 10000
|
||||
#define AID_APP_END 19999
|
||||
#define AID_USER_OFFSET 100000
|
||||
|
||||
#define to_app_id(uid) (uid % AID_USER_OFFSET)
|
||||
@ -60,10 +58,6 @@ void denylist_handler(int client, const sock_cred *cred);
|
||||
void su_daemon_handler(int client, const sock_cred *cred);
|
||||
void zygisk_handler(int client, const sock_cred *cred);
|
||||
|
||||
// Package
|
||||
std::vector<bool> get_app_no_list();
|
||||
void prune_su_access();
|
||||
|
||||
// Module stuffs
|
||||
void handle_modules();
|
||||
void load_modules();
|
||||
|
@ -181,6 +181,7 @@ pub mod ffi {
|
||||
fn sdk_int(&self) -> i32;
|
||||
fn boot_stage_handler(&self, client: i32, code: i32);
|
||||
fn preserve_stub_apk(&self);
|
||||
fn prune_su_access(&self);
|
||||
#[cxx_name = "get_manager"]
|
||||
unsafe fn get_manager_for_cxx(&self, user: i32, ptr: *mut CxxString, install: bool) -> i32;
|
||||
|
||||
@ -189,9 +190,6 @@ pub mod ffi {
|
||||
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;
|
||||
fn get_db_string(&self, key: DbEntryKey) -> String;
|
||||
#[cxx_name = "rm_db_string"]
|
||||
fn rm_db_string_for_cxx(&self, key: DbEntryKey) -> bool;
|
||||
#[cxx_name = "db_exec"]
|
||||
fn db_exec_for_cxx(&self, client_fd: i32);
|
||||
#[cxx_name = "get_root_settings"]
|
||||
|
@ -1,39 +0,0 @@
|
||||
#include <base.hpp>
|
||||
#include <consts.hpp>
|
||||
#include <core.hpp>
|
||||
#include <sqlite.hpp>
|
||||
#include <flags.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
// app_id = app_no + AID_APP_START
|
||||
// app_no range: [0, 9999]
|
||||
vector<bool> get_app_no_list() {
|
||||
vector<bool> list;
|
||||
auto data_dir = xopen_dir(APP_DATA_DIR);
|
||||
if (!data_dir)
|
||||
return list;
|
||||
dirent *entry;
|
||||
while ((entry = xreaddir(data_dir.get()))) {
|
||||
// For each user
|
||||
int dfd = xopenat(dirfd(data_dir.get()), entry->d_name, O_RDONLY);
|
||||
if (auto dir = xopen_dir(dfd)) {
|
||||
while ((entry = xreaddir(dir.get()))) {
|
||||
// For each package
|
||||
struct stat st{};
|
||||
xfstatat(dfd, entry->d_name, &st, 0);
|
||||
int app_id = to_app_id(st.st_uid);
|
||||
if (app_id >= AID_APP_START && app_id <= AID_APP_END) {
|
||||
int app_no = app_id - AID_APP_START;
|
||||
if (list.size() <= app_no) {
|
||||
list.resize(app_no + 1);
|
||||
}
|
||||
list[app_no] = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
close(dfd);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
use crate::daemon::MagiskD;
|
||||
use crate::daemon::{to_app_id, MagiskD, AID_APP_END, AID_APP_START};
|
||||
use crate::db::DbArg::Integer;
|
||||
use crate::db::{SqlTable, SqliteResult, SqliteReturn};
|
||||
use crate::ffi::{DbValues, RootSettings, SuPolicy};
|
||||
@ -35,6 +35,14 @@ impl SqlTable for RootSettings {
|
||||
}
|
||||
}
|
||||
|
||||
struct UidList(Vec<i32>);
|
||||
|
||||
impl SqlTable for UidList {
|
||||
fn on_row(&mut self, _: &[String], values: &DbValues) {
|
||||
self.0.push(values.get_int(0));
|
||||
}
|
||||
}
|
||||
|
||||
impl MagiskD {
|
||||
fn get_root_settings(&self, uid: i32, settings: &mut RootSettings) -> SqliteResult {
|
||||
self.db_exec_with_rows(
|
||||
@ -49,6 +57,36 @@ impl MagiskD {
|
||||
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
|
||||
.db_exec_with_rows("SELECT uid FROM policies", &[], &mut list)
|
||||
.sql_result()
|
||||
.log()
|
||||
.is_err()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
let app_list = self.get_app_no_list();
|
||||
let mut rm_uids = Vec::new();
|
||||
|
||||
for uid in list.0 {
|
||||
let app_id = to_app_id(uid);
|
||||
if app_id >= AID_APP_START && app_id <= AID_APP_END {
|
||||
let app_no = app_id - AID_APP_START;
|
||||
if !app_list.contains(app_no as usize) {
|
||||
// The app_id is no longer installed
|
||||
rm_uids.push(uid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for uid in rm_uids {
|
||||
self.db_exec("DELETE FROM policies WHERE uid=?", &[Integer(uid as i64)]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_default_root_settings() -> RootSettings {
|
||||
|
@ -116,34 +116,6 @@ bool uid_granted_root(int uid) {
|
||||
return granted;
|
||||
}
|
||||
|
||||
struct policy_uid_list : public vector<int> {
|
||||
void operator()(StringSlice, const DbValues &values) {
|
||||
push_back(values.get_int(0));
|
||||
}
|
||||
};
|
||||
|
||||
void prune_su_access() {
|
||||
cached.reset();
|
||||
policy_uid_list uids;
|
||||
if (!db_exec("SELECT uid FROM policies", {}, uids))
|
||||
return;
|
||||
vector<bool> app_no_list = get_app_no_list();
|
||||
vector<int> rm_uids;
|
||||
for (int uid : uids) {
|
||||
int app_id = to_app_id(uid);
|
||||
if (app_id >= AID_APP_START && app_id <= AID_APP_END) {
|
||||
int app_no = app_id - AID_APP_START;
|
||||
if (app_no >= app_no_list.size() || !app_no_list[app_no]) {
|
||||
// The app_id is no longer installed
|
||||
rm_uids.push_back(uid);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int uid : rm_uids) {
|
||||
db_exec("DELETE FROM policies WHERE uid=?", { uid });
|
||||
}
|
||||
}
|
||||
|
||||
static shared_ptr<su_info> get_su_info(unsigned uid) {
|
||||
if (uid == AID_ROOT) {
|
||||
auto info = make_shared<su_info>(uid);
|
||||
|
Loading…
x
Reference in New Issue
Block a user