mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-04-29 22:14:27 +02:00
Migrate selinux.cpp to selinux.rs
This commit is contained in:
parent
c7d1af9805
commit
73840f8721
@ -19,7 +19,6 @@ LOCAL_SRC_FILES := \
|
|||||||
core/magisk.cpp \
|
core/magisk.cpp \
|
||||||
core/daemon.cpp \
|
core/daemon.cpp \
|
||||||
core/scripting.cpp \
|
core/scripting.cpp \
|
||||||
core/selinux.cpp \
|
|
||||||
core/sqlite.cpp \
|
core/sqlite.cpp \
|
||||||
core/module.cpp \
|
core/module.cpp \
|
||||||
core/thread.cpp \
|
core/thread.cpp \
|
||||||
|
@ -85,6 +85,7 @@ pub trait Utf8CStrBuf: Write + AsRef<Utf8CStr> + Deref<Target = Utf8CStr> {
|
|||||||
fn capacity(&self) -> usize;
|
fn capacity(&self) -> usize;
|
||||||
fn clear(&mut self);
|
fn clear(&mut self);
|
||||||
fn as_mut_ptr(&mut self) -> *mut c_char;
|
fn as_mut_ptr(&mut self) -> *mut c_char;
|
||||||
|
fn truncate(&mut self, new_len: usize);
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn is_empty(&self) -> bool {
|
fn is_empty(&self) -> bool {
|
||||||
@ -183,6 +184,11 @@ impl Utf8CStrBuf for Utf8CString {
|
|||||||
fn as_mut_ptr(&mut self) -> *mut c_char {
|
fn as_mut_ptr(&mut self) -> *mut c_char {
|
||||||
self.0.as_mut_ptr().cast()
|
self.0.as_mut_ptr().cast()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn truncate(&mut self, new_len: usize) {
|
||||||
|
self.0.truncate(new_len);
|
||||||
|
self.0.nul_terminate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<String> for Utf8CString {
|
impl From<String> for Utf8CString {
|
||||||
@ -337,6 +343,12 @@ impl ToOwned for Utf8CStr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl AsRef<Utf8CStr> for Utf8CStr {
|
||||||
|
fn as_ref(&self) -> &Utf8CStr {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Notice that we only implement ExternType on Utf8CStr *reference*
|
// Notice that we only implement ExternType on Utf8CStr *reference*
|
||||||
unsafe impl ExternType for &Utf8CStr {
|
unsafe impl ExternType for &Utf8CStr {
|
||||||
type Id = type_id!("rust::Utf8CStr");
|
type Id = type_id!("rust::Utf8CStr");
|
||||||
@ -449,7 +461,7 @@ macro_rules! impl_cstr_misc {
|
|||||||
self == other.as_cstr()
|
self == other.as_cstr()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<T: AsRef<Utf8CStr>, $($g)*> PartialEq<T> for $t {
|
impl<T: AsRef<Utf8CStr> + ?Sized, $($g)*> PartialEq<T> for $t {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn eq(&self, other: &T) -> bool {
|
fn eq(&self, other: &T) -> bool {
|
||||||
self.as_bytes_with_nul() == other.as_ref().as_bytes_with_nul()
|
self.as_bytes_with_nul() == other.as_ref().as_bytes_with_nul()
|
||||||
@ -521,6 +533,13 @@ macro_rules! impl_cstr_buf {
|
|||||||
fn as_mut_ptr(&mut self) -> *mut c_char {
|
fn as_mut_ptr(&mut self) -> *mut c_char {
|
||||||
self.buf.as_mut_ptr().cast()
|
self.buf.as_mut_ptr().cast()
|
||||||
}
|
}
|
||||||
|
fn truncate(&mut self, new_len: usize) {
|
||||||
|
if self.used <= new_len {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self.buf[new_len] = b'\0';
|
||||||
|
self.used = new_len;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)*}
|
)*}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#include <consts.hpp>
|
#include <consts.hpp>
|
||||||
#include <selinux.hpp>
|
|
||||||
#include <base.hpp>
|
#include <base.hpp>
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#include <consts.hpp>
|
#include <consts.hpp>
|
||||||
#include <selinux.hpp>
|
|
||||||
#include <base.hpp>
|
#include <base.hpp>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
#include <consts.hpp>
|
#include <consts.hpp>
|
||||||
#include <base.hpp>
|
#include <base.hpp>
|
||||||
#include <core.hpp>
|
#include <core.hpp>
|
||||||
#include <selinux.hpp>
|
|
||||||
#include <flags.h>
|
#include <flags.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@ -339,6 +338,16 @@ static void switch_cgroup(const char *cgroup, int pid) {
|
|||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int setcon(const char *con) {
|
||||||
|
int fd = open("/proc/self/attr/current", O_WRONLY | O_CLOEXEC);
|
||||||
|
if (fd < 0)
|
||||||
|
return fd;
|
||||||
|
size_t len = strlen(con) + 1;
|
||||||
|
int rc = write(fd, con, len);
|
||||||
|
close(fd);
|
||||||
|
return rc != len;
|
||||||
|
}
|
||||||
|
|
||||||
static void daemon_entry() {
|
static void daemon_entry() {
|
||||||
android_logging();
|
android_logging();
|
||||||
|
|
||||||
@ -383,8 +392,6 @@ static void daemon_entry() {
|
|||||||
set_prop("ro.vendor.mtk_model", "0");
|
set_prop("ro.vendor.mtk_model", "0");
|
||||||
}
|
}
|
||||||
|
|
||||||
restore_tmpcon();
|
|
||||||
|
|
||||||
// Cleanups
|
// Cleanups
|
||||||
const char *tmp = get_magisk_tmp();
|
const char *tmp = get_magisk_tmp();
|
||||||
char path[64];
|
char path[64];
|
||||||
|
@ -8,6 +8,7 @@ use crate::get_prop;
|
|||||||
use crate::logging::{magisk_logging, setup_logfile, start_log_daemon};
|
use crate::logging::{magisk_logging, setup_logfile, start_log_daemon};
|
||||||
use crate::mount::{clean_mounts, setup_mounts};
|
use crate::mount::{clean_mounts, setup_mounts};
|
||||||
use crate::package::ManagerInfo;
|
use crate::package::ManagerInfo;
|
||||||
|
use crate::selinux::restore_tmpcon;
|
||||||
use crate::su::SuInfo;
|
use crate::su::SuInfo;
|
||||||
use base::libc::{O_CLOEXEC, O_RDONLY};
|
use base::libc::{O_CLOEXEC, O_RDONLY};
|
||||||
use base::{AtomicArc, BufReadExt, FsPathBuilder, ResultExt, Utf8CStr, cstr, error, info, libc};
|
use base::{AtomicArc, BufReadExt, FsPathBuilder, ResultExt, Utf8CStr, cstr, error, info, libc};
|
||||||
@ -259,6 +260,8 @@ pub fn daemon_entry() {
|
|||||||
}
|
}
|
||||||
info!("* Device API level: {}", sdk_int);
|
info!("* Device API level: {}", sdk_int);
|
||||||
|
|
||||||
|
restore_tmpcon().log_ok();
|
||||||
|
|
||||||
let magiskd = MagiskD {
|
let magiskd = MagiskD {
|
||||||
sdk_int,
|
sdk_int,
|
||||||
is_emulator,
|
is_emulator,
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
#include <base.hpp>
|
#include <base.hpp>
|
||||||
#include <sqlite.hpp>
|
#include <sqlite.hpp>
|
||||||
#include <core.hpp>
|
#include <core.hpp>
|
||||||
#include <selinux.hpp>
|
|
||||||
|
|
||||||
#include "deny.hpp"
|
#include "deny.hpp"
|
||||||
|
|
||||||
@ -109,10 +108,10 @@ static bool proc_name_match(int pid, string_view name) {
|
|||||||
|
|
||||||
bool proc_context_match(int pid, string_view context) {
|
bool proc_context_match(int pid, string_view context) {
|
||||||
char buf[PATH_MAX];
|
char buf[PATH_MAX];
|
||||||
char con[1024];
|
char con[1024] = {0};
|
||||||
|
|
||||||
sprintf(buf, "/proc/%d", pid);
|
sprintf(buf, "/proc/%d", pid);
|
||||||
if (lgetfilecon(buf, { con, sizeof(con) }) >= 0) {
|
if (lgetfilecon(buf, byte_data{ con, sizeof(con) })) {
|
||||||
return str_starts(con, context);
|
return str_starts(con, context);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <base.hpp>
|
|
||||||
|
|
||||||
int setcon(const char *con);
|
|
||||||
int getfilecon(const char *path, byte_data con);
|
|
||||||
int lgetfilecon(const char *path, byte_data con);
|
|
||||||
int fgetfilecon(int fd, byte_data con);
|
|
||||||
int setfilecon(const char *path, const char *con);
|
|
||||||
int lsetfilecon(const char *path, const char *con);
|
|
||||||
int fsetfilecon(int fd, const char *con);
|
|
||||||
int getfilecon_at(int dirfd, const char *name, byte_data con);
|
|
||||||
void setfilecon_at(int dirfd, const char *name, const char *con);
|
|
||||||
|
|
||||||
void restorecon();
|
|
||||||
void restore_tmpcon();
|
|
@ -15,6 +15,7 @@ use derive::Decodable;
|
|||||||
use logging::{android_logging, setup_logfile, zygisk_close_logd, zygisk_get_logd, zygisk_logging};
|
use logging::{android_logging, setup_logfile, zygisk_close_logd, zygisk_get_logd, zygisk_logging};
|
||||||
use mount::{find_preinit_device, revert_unmount};
|
use mount::{find_preinit_device, revert_unmount};
|
||||||
use resetprop::{persist_delete_prop, persist_get_prop, persist_get_props, persist_set_prop};
|
use resetprop::{persist_delete_prop, persist_get_prop, persist_get_props, persist_set_prop};
|
||||||
|
use selinux::{lgetfilecon, lsetfilecon, restorecon, setfilecon};
|
||||||
use socket::{recv_fd, recv_fds, send_fd, send_fds};
|
use socket::{recv_fd, recv_fds, send_fd, send_fds};
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::mem::ManuallyDrop;
|
use std::mem::ManuallyDrop;
|
||||||
@ -31,6 +32,7 @@ mod logging;
|
|||||||
mod mount;
|
mod mount;
|
||||||
mod package;
|
mod package;
|
||||||
mod resetprop;
|
mod resetprop;
|
||||||
|
mod selinux;
|
||||||
mod socket;
|
mod socket;
|
||||||
mod su;
|
mod su;
|
||||||
mod zygisk;
|
mod zygisk;
|
||||||
@ -205,13 +207,16 @@ pub mod ffi {
|
|||||||
fn recv_fd(socket: i32) -> i32;
|
fn recv_fd(socket: i32) -> i32;
|
||||||
fn recv_fds(socket: i32) -> Vec<i32>;
|
fn recv_fds(socket: i32) -> Vec<i32>;
|
||||||
unsafe fn write_to_fd(self: &SuRequest, fd: i32);
|
unsafe fn write_to_fd(self: &SuRequest, fd: i32);
|
||||||
|
|
||||||
#[namespace = "rust"]
|
|
||||||
fn daemon_entry();
|
|
||||||
|
|
||||||
fn pump_tty(infd: i32, outfd: i32);
|
fn pump_tty(infd: i32, outfd: i32);
|
||||||
fn get_pty_num(fd: i32) -> i32;
|
fn get_pty_num(fd: i32) -> i32;
|
||||||
fn restore_stdin() -> bool;
|
fn restore_stdin() -> bool;
|
||||||
|
fn restorecon();
|
||||||
|
fn lgetfilecon(path: Utf8CStrRef, con: &mut [u8]) -> bool;
|
||||||
|
fn setfilecon(path: Utf8CStrRef, con: Utf8CStrRef) -> bool;
|
||||||
|
fn lsetfilecon(path: Utf8CStrRef, con: Utf8CStrRef) -> bool;
|
||||||
|
|
||||||
|
#[namespace = "rust"]
|
||||||
|
fn daemon_entry();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default constructors
|
// Default constructors
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
#include <base.hpp>
|
#include <base.hpp>
|
||||||
#include <consts.hpp>
|
#include <consts.hpp>
|
||||||
#include <core.hpp>
|
#include <core.hpp>
|
||||||
#include <selinux.hpp>
|
|
||||||
#include <flags.h>
|
#include <flags.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
@ -7,7 +7,6 @@
|
|||||||
#include <base.hpp>
|
#include <base.hpp>
|
||||||
#include <consts.hpp>
|
#include <consts.hpp>
|
||||||
#include <core.hpp>
|
#include <core.hpp>
|
||||||
#include <selinux.hpp>
|
|
||||||
|
|
||||||
#include "node.hpp"
|
#include "node.hpp"
|
||||||
|
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
#include <consts.hpp>
|
#include <consts.hpp>
|
||||||
#include <base.hpp>
|
#include <base.hpp>
|
||||||
#include <selinux.hpp>
|
|
||||||
#include <core.hpp>
|
#include <core.hpp>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
@ -1,139 +0,0 @@
|
|||||||
#include <unistd.h>
|
|
||||||
#include <sys/syscall.h>
|
|
||||||
#include <sys/xattr.h>
|
|
||||||
|
|
||||||
#include <consts.hpp>
|
|
||||||
#include <base.hpp>
|
|
||||||
#include <selinux.hpp>
|
|
||||||
#include <core.hpp>
|
|
||||||
#include <flags.h>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
int setcon(const char *con) {
|
|
||||||
int fd = open("/proc/self/attr/current", O_WRONLY | O_CLOEXEC);
|
|
||||||
if (fd < 0)
|
|
||||||
return fd;
|
|
||||||
size_t len = strlen(con) + 1;
|
|
||||||
int rc = write(fd, con, len);
|
|
||||||
close(fd);
|
|
||||||
return rc != len;
|
|
||||||
}
|
|
||||||
|
|
||||||
int getfilecon(const char *path, byte_data con) {
|
|
||||||
return syscall(__NR_getxattr, path, XATTR_NAME_SELINUX, con.buf(), con.sz());
|
|
||||||
}
|
|
||||||
|
|
||||||
int lgetfilecon(const char *path, byte_data con) {
|
|
||||||
return syscall(__NR_lgetxattr, path, XATTR_NAME_SELINUX, con.buf(), con.sz());
|
|
||||||
}
|
|
||||||
|
|
||||||
int fgetfilecon(int fd, byte_data con) {
|
|
||||||
return syscall(__NR_fgetxattr, fd, XATTR_NAME_SELINUX, con.buf(), con.sz());
|
|
||||||
}
|
|
||||||
|
|
||||||
int setfilecon(const char *path, const char *con) {
|
|
||||||
return syscall(__NR_setxattr, path, XATTR_NAME_SELINUX, con, strlen(con) + 1, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int lsetfilecon(const char *path, const char *con) {
|
|
||||||
return syscall(__NR_lsetxattr, path, XATTR_NAME_SELINUX, con, strlen(con) + 1, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int fsetfilecon(int fd, const char *con) {
|
|
||||||
return syscall(__NR_fsetxattr, fd, XATTR_NAME_SELINUX, con, strlen(con) + 1, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int getfilecon_at(int dirfd, const char *name, byte_data con) {
|
|
||||||
char path[4096];
|
|
||||||
fd_pathat(dirfd, name, path, sizeof(path));
|
|
||||||
return lgetfilecon(path, con);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setfilecon_at(int dirfd, const char *name, const char *con) {
|
|
||||||
char path[4096];
|
|
||||||
fd_pathat(dirfd, name, path, sizeof(path));
|
|
||||||
lsetfilecon(path, con);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define UNLABEL_CON "u:object_r:unlabeled:s0"
|
|
||||||
#define SYSTEM_CON "u:object_r:system_file:s0"
|
|
||||||
#define ADB_CON "u:object_r:adb_data_file:s0"
|
|
||||||
#define ROOT_CON "u:object_r:rootfs:s0"
|
|
||||||
|
|
||||||
static void restore_syscon_from_null(int dirfd) {
|
|
||||||
struct dirent *entry;
|
|
||||||
char con[1024];
|
|
||||||
|
|
||||||
if (fgetfilecon(dirfd, { con, sizeof(con) }) >= 0) {
|
|
||||||
if (con[0] == '\0' || strcmp(con, UNLABEL_CON) == 0)
|
|
||||||
fsetfilecon(dirfd, SYSTEM_CON);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto dir = xopen_dir(dirfd);
|
|
||||||
while ((entry = xreaddir(dir.get()))) {
|
|
||||||
int fd = openat(dirfd, entry->d_name, O_RDONLY | O_CLOEXEC);
|
|
||||||
if (entry->d_type == DT_DIR) {
|
|
||||||
restore_syscon_from_null(fd);
|
|
||||||
continue;
|
|
||||||
} else if (entry->d_type == DT_REG) {
|
|
||||||
if (fgetfilecon(fd, { con, sizeof(con) }) >= 0) {
|
|
||||||
if (con[0] == '\0' || strcmp(con, UNLABEL_CON) == 0)
|
|
||||||
fsetfilecon(fd, SYSTEM_CON);
|
|
||||||
}
|
|
||||||
} else if (entry->d_type == DT_LNK) {
|
|
||||||
if (getfilecon_at(dirfd, entry->d_name, { con, sizeof(con) }) >= 0) {
|
|
||||||
if (con[0] == '\0' || strcmp(con, UNLABEL_CON) == 0)
|
|
||||||
setfilecon_at(dirfd, entry->d_name, SYSTEM_CON);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
close(fd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void restore_syscon(int dirfd) {
|
|
||||||
struct dirent *entry;
|
|
||||||
|
|
||||||
fsetfilecon(dirfd, SYSTEM_CON);
|
|
||||||
fchown(dirfd, 0, 0);
|
|
||||||
|
|
||||||
auto dir = xopen_dir(dirfd);
|
|
||||||
while ((entry = xreaddir(dir.get()))) {
|
|
||||||
int fd = xopenat(dirfd, entry->d_name, O_RDONLY | O_CLOEXEC);
|
|
||||||
if (entry->d_type == DT_DIR) {
|
|
||||||
restore_syscon(fd);
|
|
||||||
continue;
|
|
||||||
} else if (entry->d_type) {
|
|
||||||
fsetfilecon(fd, SYSTEM_CON);
|
|
||||||
fchown(fd, 0, 0);
|
|
||||||
}
|
|
||||||
close(fd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void restorecon() {
|
|
||||||
int fd = xopen("/sys/fs/selinux/context", O_WRONLY | O_CLOEXEC);
|
|
||||||
if (write(fd, ADB_CON, sizeof(ADB_CON)) >= 0)
|
|
||||||
lsetfilecon(SECURE_DIR, ADB_CON);
|
|
||||||
close(fd);
|
|
||||||
lsetfilecon(MODULEROOT, SYSTEM_CON);
|
|
||||||
restore_syscon_from_null(xopen(MODULEROOT, O_RDONLY | O_CLOEXEC));
|
|
||||||
restore_syscon(xopen(DATABIN, O_RDONLY | O_CLOEXEC));
|
|
||||||
}
|
|
||||||
|
|
||||||
void restore_tmpcon() {
|
|
||||||
const char *tmp = get_magisk_tmp();
|
|
||||||
if (tmp == "/sbin"sv)
|
|
||||||
setfilecon(tmp, ROOT_CON);
|
|
||||||
else
|
|
||||||
chmod(tmp, 0711);
|
|
||||||
|
|
||||||
auto dir = xopen_dir(tmp);
|
|
||||||
int dfd = dirfd(dir.get());
|
|
||||||
|
|
||||||
for (dirent *entry; (entry = xreaddir(dir.get()));)
|
|
||||||
setfilecon_at(dfd, entry->d_name, SYSTEM_CON);
|
|
||||||
|
|
||||||
string logd = tmp + "/"s LOG_PIPE;
|
|
||||||
setfilecon(logd.data(), MAGISK_LOG_CON);
|
|
||||||
}
|
|
108
native/src/core/selinux.rs
Normal file
108
native/src/core/selinux.rs
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
use crate::consts::{DATABIN, LOG_PIPE, MAGISK_LOG_CON, MODULEROOT, SECURE_DIR};
|
||||||
|
use crate::ffi::get_magisk_tmp;
|
||||||
|
use base::libc::{O_CLOEXEC, O_WRONLY};
|
||||||
|
use base::{Directory, FsPathBuilder, LoggedResult, ResultExt, Utf8CStr, Utf8CStrBuf, cstr, libc};
|
||||||
|
use std::io::Write;
|
||||||
|
|
||||||
|
const UNLABEL_CON: &Utf8CStr = cstr!("u:object_r:unlabeled:s0");
|
||||||
|
const SYSTEM_CON: &Utf8CStr = cstr!("u:object_r:system_file:s0");
|
||||||
|
const ADB_CON: &Utf8CStr = cstr!("u:object_r:adb_data_file:s0");
|
||||||
|
const ROOT_CON: &Utf8CStr = cstr!("u:object_r:rootfs:s0");
|
||||||
|
|
||||||
|
fn restore_syscon_from_unlabeled(
|
||||||
|
path: &mut dyn Utf8CStrBuf,
|
||||||
|
con: &mut dyn Utf8CStrBuf,
|
||||||
|
) -> LoggedResult<()> {
|
||||||
|
let dir_path_len = path.len();
|
||||||
|
if path.get_secontext(con).log().is_ok() && con.as_str() == UNLABEL_CON {
|
||||||
|
path.set_secontext(SYSTEM_CON)?;
|
||||||
|
}
|
||||||
|
let mut dir = Directory::open(path)?;
|
||||||
|
while let Some(ref e) = dir.read()? {
|
||||||
|
path.truncate(dir_path_len);
|
||||||
|
path.append_path(e.name());
|
||||||
|
if e.is_dir() {
|
||||||
|
restore_syscon_from_unlabeled(path, con)?;
|
||||||
|
} else if (e.is_file() || e.is_symlink())
|
||||||
|
&& path.get_secontext(con).log().is_ok()
|
||||||
|
&& con.as_str() == UNLABEL_CON
|
||||||
|
{
|
||||||
|
path.set_secontext(SYSTEM_CON)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn restore_syscon(path: &mut dyn Utf8CStrBuf) -> LoggedResult<()> {
|
||||||
|
let dir_path_len = path.len();
|
||||||
|
path.set_secontext(SYSTEM_CON)?;
|
||||||
|
unsafe { libc::lchown(path.as_ptr(), 0, 0) };
|
||||||
|
let mut dir = Directory::open(path)?;
|
||||||
|
while let Some(ref e) = dir.read()? {
|
||||||
|
path.truncate(dir_path_len);
|
||||||
|
path.append_path(e.name());
|
||||||
|
if e.is_dir() {
|
||||||
|
restore_syscon(path)?;
|
||||||
|
} else if e.is_file() || e.is_symlink() {
|
||||||
|
path.set_secontext(SYSTEM_CON)?;
|
||||||
|
unsafe { libc::lchown(path.as_ptr(), 0, 0) };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn restorecon() {
|
||||||
|
if let Ok(mut file) = cstr!("/sys/fs/selinux/context")
|
||||||
|
.open(O_WRONLY | O_CLOEXEC)
|
||||||
|
.log()
|
||||||
|
{
|
||||||
|
if file.write_all(ADB_CON.as_bytes_with_nul()).is_ok() {
|
||||||
|
cstr!(SECURE_DIR).set_secontext(ADB_CON).log_ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut path = cstr::buf::default();
|
||||||
|
let mut con = cstr::buf::new::<1024>();
|
||||||
|
path.push_str(MODULEROOT);
|
||||||
|
path.set_secontext(SYSTEM_CON).log_ok();
|
||||||
|
restore_syscon_from_unlabeled(&mut path, &mut con).log_ok();
|
||||||
|
|
||||||
|
path.clear();
|
||||||
|
path.push_str(DATABIN);
|
||||||
|
restore_syscon(&mut path).log_ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn restore_tmpcon() -> LoggedResult<()> {
|
||||||
|
let tmp = get_magisk_tmp();
|
||||||
|
if tmp == "/sbin" {
|
||||||
|
tmp.set_secontext(ROOT_CON)?;
|
||||||
|
} else {
|
||||||
|
unsafe { libc::chmod(tmp.as_ptr(), 0o711) };
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut path = cstr::buf::default();
|
||||||
|
let mut dir = Directory::open(tmp)?;
|
||||||
|
while let Some(ref e) = dir.read()? {
|
||||||
|
e.resolve_path(&mut path)?;
|
||||||
|
path.set_secontext(SYSTEM_CON)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
path.clear();
|
||||||
|
path.append_path(tmp).append_path(LOG_PIPE);
|
||||||
|
path.set_secontext(cstr!(MAGISK_LOG_CON))?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn lgetfilecon(path: &Utf8CStr, con: &mut [u8]) -> bool {
|
||||||
|
let mut con = cstr::buf::wrap(con);
|
||||||
|
path.get_secontext(&mut con).is_ok()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn setfilecon(path: &Utf8CStr, con: &Utf8CStr) -> bool {
|
||||||
|
path.follow_link().set_secontext(con).is_ok()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn lsetfilecon(path: &Utf8CStr, con: &Utf8CStr) -> bool {
|
||||||
|
path.set_secontext(con).is_ok()
|
||||||
|
}
|
@ -2,7 +2,6 @@
|
|||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
|
||||||
#include <base.hpp>
|
#include <base.hpp>
|
||||||
#include <selinux.hpp>
|
|
||||||
#include <consts.hpp>
|
#include <consts.hpp>
|
||||||
#include <core.hpp>
|
#include <core.hpp>
|
||||||
|
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
#include <consts.hpp>
|
#include <consts.hpp>
|
||||||
#include <base.hpp>
|
#include <base.hpp>
|
||||||
#include <core.hpp>
|
#include <core.hpp>
|
||||||
#include <selinux.hpp>
|
|
||||||
|
|
||||||
#include "zygisk.hpp"
|
#include "zygisk.hpp"
|
||||||
|
|
||||||
|
@ -15,16 +15,25 @@ pub const LOGFILE: &str = "/cache/magisk.log";
|
|||||||
// data paths
|
// data paths
|
||||||
pub const SECURE_DIR: &str = "/data/adb";
|
pub const SECURE_DIR: &str = "/data/adb";
|
||||||
pub const MODULEROOT: &str = concatcp!(SECURE_DIR, "/modules");
|
pub const MODULEROOT: &str = concatcp!(SECURE_DIR, "/modules");
|
||||||
|
pub const DATABIN: &str = concatcp!(SECURE_DIR, "/magisk");
|
||||||
|
|
||||||
// tmpfs paths
|
// tmpfs paths
|
||||||
const INTERNAL_DIR: &str = ".magisk";
|
const INTERNAL_DIR: &str = ".magisk";
|
||||||
pub const LOG_PIPE: &str = concatcp!(INTERNAL_DIR, "/device/log");
|
|
||||||
pub const MAIN_CONFIG: &str = concatcp!(INTERNAL_DIR, "/config");
|
pub const MAIN_CONFIG: &str = concatcp!(INTERNAL_DIR, "/config");
|
||||||
pub const PREINITMIRR: &str = concatcp!(INTERNAL_DIR, "/preinit");
|
pub const PREINITMIRR: &str = concatcp!(INTERNAL_DIR, "/preinit");
|
||||||
pub const MODULEMNT: &str = concatcp!(INTERNAL_DIR, "/modules");
|
pub const MODULEMNT: &str = concatcp!(INTERNAL_DIR, "/modules");
|
||||||
pub const WORKERDIR: &str = concatcp!(INTERNAL_DIR, "/worker");
|
pub const WORKERDIR: &str = concatcp!(INTERNAL_DIR, "/worker");
|
||||||
pub const DEVICEDIR: &str = concatcp!(INTERNAL_DIR, "/device");
|
pub const DEVICEDIR: &str = concatcp!(INTERNAL_DIR, "/device");
|
||||||
pub const PREINITDEV: &str = concatcp!(DEVICEDIR, "/preinit");
|
pub const PREINITDEV: &str = concatcp!(DEVICEDIR, "/preinit");
|
||||||
|
pub const LOG_PIPE: &str = concatcp!(DEVICEDIR, "/log");
|
||||||
pub const ROOTOVL: &str = concatcp!(INTERNAL_DIR, "/rootdir");
|
pub const ROOTOVL: &str = concatcp!(INTERNAL_DIR, "/rootdir");
|
||||||
pub const ROOTMNT: &str = concatcp!(ROOTOVL, "/.mount_list");
|
pub const ROOTMNT: &str = concatcp!(ROOTOVL, "/.mount_list");
|
||||||
pub const SELINUXMOCK: &str = concatcp!(INTERNAL_DIR, "/selinux");
|
pub const SELINUXMOCK: &str = concatcp!(INTERNAL_DIR, "/selinux");
|
||||||
|
|
||||||
|
// Unconstrained domain the daemon and root processes run in
|
||||||
|
pub const SEPOL_PROC_DOMAIN: &str = "magisk";
|
||||||
|
// Unconstrained file type that anyone can access
|
||||||
|
pub const SEPOL_FILE_TYPE: &str = "magisk_file";
|
||||||
|
// Log pipe that only root and zygote can open
|
||||||
|
pub const SEPOL_LOG_TYPE: &str = "magisk_log_file";
|
||||||
|
pub const MAGISK_LOG_CON: &str = concatcp!("u:object_r:", SEPOL_LOG_TYPE, ":s0");
|
||||||
|
@ -6,6 +6,9 @@ use std::fmt::Write;
|
|||||||
|
|
||||||
use crate::ffi::SePolicy;
|
use crate::ffi::SePolicy;
|
||||||
|
|
||||||
|
#[path = "../include/consts.rs"]
|
||||||
|
mod consts;
|
||||||
|
|
||||||
#[cfg(feature = "main")]
|
#[cfg(feature = "main")]
|
||||||
mod cli;
|
mod cli;
|
||||||
mod rules;
|
mod rules;
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use crate::consts::{SEPOL_FILE_TYPE, SEPOL_LOG_TYPE, SEPOL_PROC_DOMAIN};
|
||||||
use crate::{SePolicy, ffi::Xperm};
|
use crate::{SePolicy, ffi::Xperm};
|
||||||
use base::{LogLevel, set_log_level_state};
|
use base::{LogLevel, set_log_level_state};
|
||||||
|
|
||||||
@ -12,22 +13,22 @@ macro_rules! rules {
|
|||||||
vec!["servicemanager", "vndservicemanager", "hwservicemanager"]
|
vec!["servicemanager", "vndservicemanager", "hwservicemanager"]
|
||||||
};
|
};
|
||||||
(@args [proc]) => {
|
(@args [proc]) => {
|
||||||
vec!["magisk"]
|
vec![SEPOL_PROC_DOMAIN]
|
||||||
};
|
};
|
||||||
(@args [file]) => {
|
(@args [file]) => {
|
||||||
vec!["magisk_file"]
|
vec![SEPOL_FILE_TYPE]
|
||||||
};
|
};
|
||||||
(@args [log]) => {
|
(@args [log]) => {
|
||||||
vec!["magisk_log_file"]
|
vec![SEPOL_LOG_TYPE]
|
||||||
};
|
};
|
||||||
(@args proc) => {
|
(@args proc) => {
|
||||||
"magisk"
|
SEPOL_PROC_DOMAIN
|
||||||
};
|
};
|
||||||
(@args file) => {
|
(@args file) => {
|
||||||
"magisk_file"
|
SEPOL_FILE_TYPE
|
||||||
};
|
};
|
||||||
(@args log) => {
|
(@args log) => {
|
||||||
"magisk_log_file"
|
SEPOL_LOG_TYPE
|
||||||
};
|
};
|
||||||
(@args [$($arg:tt)*]) => {
|
(@args [$($arg:tt)*]) => {
|
||||||
vec![$($arg)*]
|
vec![$($arg)*]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user