Remove an additional unique_ptr indirection

This commit is contained in:
topjohnwu 2025-02-05 14:18:16 +08:00
parent a14fc90f07
commit b7ca73f431
10 changed files with 109 additions and 129 deletions

View File

@ -9,19 +9,19 @@ using namespace std;
void MagiskInit::patch_sepolicy(const char *in, const char *out) { void MagiskInit::patch_sepolicy(const char *in, const char *out) {
LOGD("Patching monolithic policy\n"); LOGD("Patching monolithic policy\n");
auto sepol = unique_ptr<sepolicy>(sepolicy::from_file(in)); auto sepol = SePolicy::from_file(in);
sepol->magisk_rules(); sepol.magisk_rules();
// Custom rules // Custom rules
auto rule = "/data/" PREINITMIRR "/sepolicy.rule"; auto rule = "/data/" PREINITMIRR "/sepolicy.rule";
if (xaccess(rule, R_OK) == 0) { if (xaccess(rule, R_OK) == 0) {
LOGD("Loading custom sepolicy patch: [%s]\n", rule); LOGD("Loading custom sepolicy patch: [%s]\n", rule);
sepol->load_rule_file(rule); sepol.load_rule_file(rule);
} }
LOGD("Dumping sepolicy to: [%s]\n", out); LOGD("Dumping sepolicy to: [%s]\n", out);
sepol->to_file(out); sepol.to_file(out);
// Remove OnePlus stupid debug sepolicy and use our own // Remove OnePlus stupid debug sepolicy and use our own
if (access("/sepolicy_debug", F_OK) == 0) { if (access("/sepolicy_debug", F_OK) == 0) {
@ -124,12 +124,12 @@ bool MagiskInit::hijack_sepolicy() {
xumount2(SELINUX_ENFORCE, MNT_DETACH); xumount2(SELINUX_ENFORCE, MNT_DETACH);
// Load and patch policy // Load and patch policy
auto sepol = unique_ptr<sepolicy>(sepolicy::from_file(MOCK_LOAD)); auto sepol = SePolicy::from_file(MOCK_LOAD);
sepol->magisk_rules(); sepol.magisk_rules();
sepol->load_rules(rules); sepol.load_rules(rules);
// Load patched policy into kernel // Load patched policy into kernel
sepol->to_file(SELINUX_LOAD); sepol.to_file(SELINUX_LOAD);
// restore mounted files' context after sepolicy loaded // restore mounted files' context after sepolicy loaded
rust::reset_overlay_contexts(); rust::reset_overlay_contexts();

View File

@ -62,70 +62,70 @@ static inline void expand(const Xperms &vec, T &&...args) {
} }
} }
void sepolicy::allow(StrVec src, StrVec tgt, StrVec cls, StrVec perm) noexcept { void SePolicy::allow(StrVec src, StrVec tgt, StrVec cls, StrVec perm) noexcept {
expand(src, tgt, cls, perm, [this](auto ...args) { expand(src, tgt, cls, perm, [this](auto ...args) {
print_rule("allow", args...); print_rule("allow", args...);
impl->add_rule(args..., AVTAB_ALLOWED, false); impl->add_rule(args..., AVTAB_ALLOWED, false);
}); });
} }
void sepolicy::deny(StrVec src, StrVec tgt, StrVec cls, StrVec perm) noexcept { void SePolicy::deny(StrVec src, StrVec tgt, StrVec cls, StrVec perm) noexcept {
expand(src, tgt, cls, perm, [this](auto ...args) { expand(src, tgt, cls, perm, [this](auto ...args) {
print_rule("deny", args...); print_rule("deny", args...);
impl->add_rule(args..., AVTAB_ALLOWED, true); impl->add_rule(args..., AVTAB_ALLOWED, true);
}); });
} }
void sepolicy::auditallow(StrVec src, StrVec tgt, StrVec cls, StrVec perm) noexcept { void SePolicy::auditallow(StrVec src, StrVec tgt, StrVec cls, StrVec perm) noexcept {
expand(src, tgt, cls, perm, [this](auto ...args) { expand(src, tgt, cls, perm, [this](auto ...args) {
print_rule("auditallow", args...); print_rule("auditallow", args...);
impl->add_rule(args..., AVTAB_AUDITALLOW, false); impl->add_rule(args..., AVTAB_AUDITALLOW, false);
}); });
} }
void sepolicy::dontaudit(StrVec src, StrVec tgt, StrVec cls, StrVec perm) noexcept { void SePolicy::dontaudit(StrVec src, StrVec tgt, StrVec cls, StrVec perm) noexcept {
expand(src, tgt, cls, perm, [this](auto ...args) { expand(src, tgt, cls, perm, [this](auto ...args) {
print_rule("dontaudit", args...); print_rule("dontaudit", args...);
impl->add_rule(args..., AVTAB_AUDITDENY, true); impl->add_rule(args..., AVTAB_AUDITDENY, true);
}); });
} }
void sepolicy::permissive(StrVec types) noexcept { void SePolicy::permissive(StrVec types) noexcept {
expand(types, [this](auto ...args) { expand(types, [this](auto ...args) {
print_rule("permissive", args...); print_rule("permissive", args...);
impl->set_type_state(args..., true); impl->set_type_state(args..., true);
}); });
} }
void sepolicy::enforce(StrVec types) noexcept { void SePolicy::enforce(StrVec types) noexcept {
expand(types, [this](auto ...args) { expand(types, [this](auto ...args) {
print_rule("enforce", args...); print_rule("enforce", args...);
impl->set_type_state(args..., false); impl->set_type_state(args..., false);
}); });
} }
void sepolicy::typeattribute(StrVec types, StrVec attrs) noexcept { void SePolicy::typeattribute(StrVec types, StrVec attrs) noexcept {
expand(types, attrs, [this](auto ...args) { expand(types, attrs, [this](auto ...args) {
print_rule("typeattribute", args...); print_rule("typeattribute", args...);
impl->add_typeattribute(args...); impl->add_typeattribute(args...);
}); });
} }
void sepolicy::type(Str type, StrVec attrs) noexcept { void SePolicy::type(Str type, StrVec attrs) noexcept {
expand(type, attrs, [this](auto name, auto attr) { expand(type, attrs, [this](auto name, auto attr) {
print_rule("type", name, attr); print_rule("type", name, attr);
impl->add_type(name, TYPE_TYPE) && impl->add_typeattribute(name, attr); impl->add_type(name, TYPE_TYPE) && impl->add_typeattribute(name, attr);
}); });
} }
void sepolicy::attribute(Str name) noexcept { void SePolicy::attribute(Str name) noexcept {
expand(name, [this](auto ...args) { expand(name, [this](auto ...args) {
print_rule("attribute", args...); print_rule("attribute", args...);
impl->add_type(args..., TYPE_ATTRIB); impl->add_type(args..., TYPE_ATTRIB);
}); });
} }
void sepolicy::type_transition(Str src, Str tgt, Str cls, Str def, Str obj) noexcept { void SePolicy::type_transition(Str src, Str tgt, Str cls, Str def, Str obj) noexcept {
expand(src, tgt, cls, def, obj, [this](auto s, auto t, auto c, auto d, auto o) { expand(src, tgt, cls, def, obj, [this](auto s, auto t, auto c, auto d, auto o) {
if (o) { if (o) {
print_rule("type_transition", s, t, c, d, o); print_rule("type_transition", s, t, c, d, o);
@ -137,42 +137,42 @@ void sepolicy::type_transition(Str src, Str tgt, Str cls, Str def, Str obj) noex
}); });
} }
void sepolicy::type_change(Str src, Str tgt, Str cls, Str def) noexcept { void SePolicy::type_change(Str src, Str tgt, Str cls, Str def) noexcept {
expand(src, tgt, cls, def, [this](auto ...args) { expand(src, tgt, cls, def, [this](auto ...args) {
print_rule("type_change", args...); print_rule("type_change", args...);
impl->add_type_rule(args..., AVTAB_CHANGE); impl->add_type_rule(args..., AVTAB_CHANGE);
}); });
} }
void sepolicy::type_member(Str src, Str tgt, Str cls, Str def) noexcept { void SePolicy::type_member(Str src, Str tgt, Str cls, Str def) noexcept {
expand(src, tgt, cls, def, [this](auto ...args) { expand(src, tgt, cls, def, [this](auto ...args) {
print_rule("type_member", args...); print_rule("type_member", args...);
impl->add_type_rule(args..., AVTAB_MEMBER); impl->add_type_rule(args..., AVTAB_MEMBER);
}); });
} }
void sepolicy::genfscon(Str fs_name, Str path, Str ctx) noexcept { void SePolicy::genfscon(Str fs_name, Str path, Str ctx) noexcept {
expand(fs_name, path, ctx, [this](auto ...args) { expand(fs_name, path, ctx, [this](auto ...args) {
print_rule("genfscon", args...); print_rule("genfscon", args...);
impl->add_genfscon(args...); impl->add_genfscon(args...);
}); });
} }
void sepolicy::allowxperm(StrVec src, StrVec tgt, StrVec cls, Xperms xperm) noexcept { void SePolicy::allowxperm(StrVec src, StrVec tgt, StrVec cls, Xperms xperm) noexcept {
expand(src, tgt, cls, xperm, [this](auto ...args) { expand(src, tgt, cls, xperm, [this](auto ...args) {
print_rule("allowxperm", args...); print_rule("allowxperm", args...);
impl->add_xperm_rule(args..., AVTAB_XPERMS_ALLOWED); impl->add_xperm_rule(args..., AVTAB_XPERMS_ALLOWED);
}); });
} }
void sepolicy::auditallowxperm(StrVec src, StrVec tgt, StrVec cls, Xperms xperm) noexcept { void SePolicy::auditallowxperm(StrVec src, StrVec tgt, StrVec cls, Xperms xperm) noexcept {
expand(src, tgt, cls, xperm, [this](auto ...args) { expand(src, tgt, cls, xperm, [this](auto ...args) {
print_rule("auditallowxperm", args...); print_rule("auditallowxperm", args...);
impl->add_xperm_rule(args..., AVTAB_XPERMS_AUDITALLOW); impl->add_xperm_rule(args..., AVTAB_XPERMS_AUDITALLOW);
}); });
} }
void sepolicy::dontauditxperm(StrVec src, StrVec tgt, StrVec cls, Xperms xperm) noexcept { void SePolicy::dontauditxperm(StrVec src, StrVec tgt, StrVec cls, Xperms xperm) noexcept {
expand(src, tgt, cls, xperm, [this](auto ...args) { expand(src, tgt, cls, xperm, [this](auto ...args) {
print_rule("dontauditxperm", args...); print_rule("dontauditxperm", args...);
impl->add_xperm_rule(args..., AVTAB_XPERMS_DONTAUDIT); impl->add_xperm_rule(args..., AVTAB_XPERMS_DONTAUDIT);

View File

@ -6,6 +6,7 @@
#include <base.hpp> #include <base.hpp>
#include "../policy-rs.hpp" #include "../policy-rs.hpp"
// sepolicy paths // sepolicy paths
#define PLAT_POLICY_DIR "/system/etc/selinux/" #define PLAT_POLICY_DIR "/system/etc/selinux/"
#define VEND_POLICY_DIR "/vendor/etc/selinux/" #define VEND_POLICY_DIR "/vendor/etc/selinux/"

View File

@ -1,14 +1,14 @@
#![feature(format_args_nl)] #![feature(format_args_nl)]
#![feature(try_blocks)] #![feature(try_blocks)]
use std::fmt::Write;
use std::io::{BufRead, BufReader, Cursor};
use cxx::CxxString;
pub use base; pub use base;
use base::libc::{O_CLOEXEC, O_RDONLY}; use base::libc::{O_CLOEXEC, O_RDONLY};
use base::{BufReadExt, FsPath, LoggedResult, Utf8CStr}; use base::{BufReadExt, FsPath, LoggedResult, Utf8CStr};
use cxx::CxxString;
use std::fmt::Write;
use std::io::{BufRead, BufReader, Cursor};
use crate::ffi::sepolicy; use crate::ffi::SePolicy;
mod rules; mod rules;
mod statement; mod statement;
@ -21,7 +21,7 @@ pub mod ffi {
reset: bool, reset: bool,
} }
pub struct sepolicy { struct SePolicy {
#[cxx_name = "impl"] #[cxx_name = "impl"]
_impl: UniquePtr<sepol_impl>, _impl: UniquePtr<sepol_impl>,
} }
@ -36,88 +36,70 @@ pub mod ffi {
type sepol_impl; type sepol_impl;
fn allow(self: &mut sepolicy, s: Vec<&str>, t: Vec<&str>, c: Vec<&str>, p: Vec<&str>); fn allow(self: &mut SePolicy, s: Vec<&str>, t: Vec<&str>, c: Vec<&str>, p: Vec<&str>);
fn deny(self: &mut sepolicy, s: Vec<&str>, t: Vec<&str>, c: Vec<&str>, p: Vec<&str>); fn deny(self: &mut SePolicy, s: Vec<&str>, t: Vec<&str>, c: Vec<&str>, p: Vec<&str>);
fn auditallow( fn auditallow(self: &mut SePolicy, s: Vec<&str>, t: Vec<&str>, c: Vec<&str>, p: Vec<&str>);
self: &mut sepolicy, fn dontaudit(self: &mut SePolicy, s: Vec<&str>, t: Vec<&str>, c: Vec<&str>, p: Vec<&str>);
s: Vec<&str>, fn allowxperm(self: &mut SePolicy, s: Vec<&str>, t: Vec<&str>, c: Vec<&str>, p: Vec<Xperm>);
t: Vec<&str>,
c: Vec<&str>,
p: Vec<&str>,
);
fn dontaudit(
self: &mut sepolicy,
s: Vec<&str>,
t: Vec<&str>,
c: Vec<&str>,
p: Vec<&str>,
);
fn allowxperm(
self: &mut sepolicy,
s: Vec<&str>,
t: Vec<&str>,
c: Vec<&str>,
p: Vec<Xperm>,
);
fn auditallowxperm( fn auditallowxperm(
self: &mut sepolicy, self: &mut SePolicy,
s: Vec<&str>, s: Vec<&str>,
t: Vec<&str>, t: Vec<&str>,
c: Vec<&str>, c: Vec<&str>,
p: Vec<Xperm>, p: Vec<Xperm>,
); );
fn dontauditxperm( fn dontauditxperm(
self: &mut sepolicy, self: &mut SePolicy,
s: Vec<&str>, s: Vec<&str>,
t: Vec<&str>, t: Vec<&str>,
c: Vec<&str>, c: Vec<&str>,
p: Vec<Xperm>, p: Vec<Xperm>,
); );
fn permissive(self: &mut sepolicy, t: Vec<&str>); fn permissive(self: &mut SePolicy, t: Vec<&str>);
fn enforce(self: &mut sepolicy, t: Vec<&str>); fn enforce(self: &mut SePolicy, t: Vec<&str>);
fn typeattribute(self: &mut sepolicy, t: Vec<&str>, a: Vec<&str>); fn typeattribute(self: &mut SePolicy, t: Vec<&str>, a: Vec<&str>);
#[cxx_name = "type"] #[cxx_name = "type"]
fn type_(self: &mut sepolicy, t: &str, a: Vec<&str>); fn type_(self: &mut SePolicy, t: &str, a: Vec<&str>);
fn attribute(self: &mut sepolicy, t: &str); fn attribute(self: &mut SePolicy, t: &str);
fn type_transition(self: &mut sepolicy, s: &str, t: &str, c: &str, d: &str, o: &str); fn type_transition(self: &mut SePolicy, s: &str, t: &str, c: &str, d: &str, o: &str);
fn type_change(self: &mut sepolicy, s: &str, t: &str, c: &str, d: &str); fn type_change(self: &mut SePolicy, s: &str, t: &str, c: &str, d: &str);
fn type_member(self: &mut sepolicy, s: &str, t: &str, c: &str, d: &str); fn type_member(self: &mut SePolicy, s: &str, t: &str, c: &str, d: &str);
fn genfscon(self: &mut sepolicy, s: &str, t: &str, c: &str); fn genfscon(self: &mut SePolicy, s: &str, t: &str, c: &str);
#[allow(dead_code)] #[allow(dead_code)]
fn strip_dontaudit(self: &mut sepolicy); fn strip_dontaudit(self: &mut SePolicy);
fn print_rules(self: &sepolicy); fn print_rules(self: &SePolicy);
fn to_file(self: &sepolicy, file: Utf8CStrRef) -> bool; fn to_file(self: &SePolicy, file: Utf8CStrRef) -> bool;
#[Self = sepolicy] #[Self = SePolicy]
fn from_file(file: Utf8CStrRef) -> UniquePtr<sepolicy>; fn from_file(file: Utf8CStrRef) -> SePolicy;
#[Self = sepolicy] #[Self = SePolicy]
fn from_split() -> UniquePtr<sepolicy>; fn from_split() -> SePolicy;
#[Self = sepolicy] #[Self = SePolicy]
fn compile_split() -> UniquePtr<sepolicy>; fn compile_split() -> SePolicy;
#[Self = sepolicy] #[Self = SePolicy]
unsafe fn from_data(data: *mut c_char, len: usize) -> UniquePtr<sepolicy>; unsafe fn from_data(data: *mut c_char, len: usize) -> SePolicy;
} }
extern "Rust" { extern "Rust" {
fn parse_statement(self: &mut sepolicy, statement: Utf8CStrRef); fn parse_statement(self: &mut SePolicy, statement: Utf8CStrRef);
fn magisk_rules(self: &mut sepolicy); fn magisk_rules(self: &mut SePolicy);
fn load_rule_file(self: &mut sepolicy, filename: Utf8CStrRef); fn load_rule_file(self: &mut SePolicy, filename: Utf8CStrRef);
fn load_rules(self: &mut sepolicy, rules: &CxxString); fn load_rules(self: &mut SePolicy, rules: &CxxString);
#[Self = sepolicy] #[Self = SePolicy]
fn xperm_to_string(perm: &Xperm) -> String; fn xperm_to_string(perm: &Xperm) -> String;
#[Self = sepolicy] #[Self = SePolicy]
fn print_statement_help(); fn print_statement_help();
} }
} }
impl sepolicy { impl SePolicy {
fn load_rules(self: &mut sepolicy, rules: &CxxString) { fn load_rules(self: &mut SePolicy, rules: &CxxString) {
let mut cursor = Cursor::new(rules.as_bytes()); let mut cursor = Cursor::new(rules.as_bytes());
self.load_rules_from_reader(&mut cursor); self.load_rules_from_reader(&mut cursor);
} }
pub fn load_rule_file(self: &mut sepolicy, filename: &Utf8CStr) { pub fn load_rule_file(self: &mut SePolicy, filename: &Utf8CStr) {
let result: LoggedResult<()> = try { let result: LoggedResult<()> = try {
let file = FsPath::from(filename).open(O_RDONLY | O_CLOEXEC)?; let file = FsPath::from(filename).open(O_RDONLY | O_CLOEXEC)?;
let mut reader = BufReader::new(file); let mut reader = BufReader::new(file);
@ -126,7 +108,7 @@ impl sepolicy {
result.ok(); result.ok();
} }
fn load_rules_from_reader<T: BufRead>(self: &mut sepolicy, reader: &mut T) { fn load_rules_from_reader<T: BufRead>(self: &mut SePolicy, reader: &mut T) {
reader.foreach_lines(|line| { reader.foreach_lines(|line| {
self.parse_statement(line); self.parse_statement(line);
true true

View File

@ -36,7 +36,7 @@ int main(int argc, char *argv[]) {
cmdline_logging(); cmdline_logging();
const char *out_file = nullptr; const char *out_file = nullptr;
vector<string_view> rule_files; vector<string_view> rule_files;
std::unique_ptr<sepolicy> sepol; SePolicy sepol;
bool magisk = false; bool magisk = false;
bool live = false; bool live = false;
bool print = false; bool print = false;
@ -56,21 +56,21 @@ int main(int argc, char *argv[]) {
else if (option == "load"sv) { else if (option == "load"sv) {
if (argv[i + 1] == nullptr) if (argv[i + 1] == nullptr)
usage(argv[0]); usage(argv[0]);
sepol = sepolicy::from_file(argv[i + 1]); sepol = SePolicy::from_file(argv[i + 1]);
if (!sepol) { if (!sepol.impl) {
fprintf(stderr, "Cannot load policy from %s\n", argv[i + 1]); fprintf(stderr, "Cannot load policy from %s\n", argv[i + 1]);
return 1; return 1;
} }
++i; ++i;
} else if (option == "load-split"sv) { } else if (option == "load-split"sv) {
sepol = sepolicy::from_split(); sepol = SePolicy::from_split();
if (!sepol) { if (!sepol.impl) {
fprintf(stderr, "Cannot load split cil\n"); fprintf(stderr, "Cannot load split cil\n");
return 1; return 1;
} }
} else if (option == "compile-split"sv) { } else if (option == "compile-split"sv) {
sepol = sepolicy::compile_split(); sepol = SePolicy::compile_split();
if (!sepol) { if (!sepol.impl) {
fprintf(stderr, "Cannot compile split cil\n"); fprintf(stderr, "Cannot compile split cil\n");
return 1; return 1;
} }
@ -85,7 +85,7 @@ int main(int argc, char *argv[]) {
rule_files.emplace_back(argv[i + 1]); rule_files.emplace_back(argv[i + 1]);
++i; ++i;
} else if (option == "help"sv) { } else if (option == "help"sv) {
sepolicy::print_statement_help(); SePolicy::print_statement_help();
exit(0); exit(0);
} else { } else {
usage(argv[0]); usage(argv[0]);
@ -96,32 +96,32 @@ int main(int argc, char *argv[]) {
} }
// Use current policy if nothing is loaded // Use current policy if nothing is loaded
if (sepol == nullptr && !(sepol = sepolicy::from_file(SELINUX_POLICY))) { if (!sepol.impl && !(sepol = SePolicy::from_file(SELINUX_POLICY)).impl) {
fprintf(stderr, "Cannot load policy from " SELINUX_POLICY "\n"); fprintf(stderr, "Cannot load policy from " SELINUX_POLICY "\n");
return 1; return 1;
} }
if (print) { if (print) {
sepol->print_rules(); sepol.print_rules();
return 0; return 0;
} }
if (magisk) if (magisk)
sepol->magisk_rules(); sepol.magisk_rules();
if (!rule_files.empty()) if (!rule_files.empty())
for (const auto &rule_file : rule_files) for (const auto &rule_file : rule_files)
sepol->load_rule_file(rule_file.data()); sepol.load_rule_file(rule_file.data());
for (; i < argc; ++i) for (; i < argc; ++i)
sepol->parse_statement(argv[i]); sepol.parse_statement(argv[i]);
if (live && !sepol->to_file(SELINUX_LOAD)) { if (live && !sepol.to_file(SELINUX_LOAD)) {
fprintf(stderr, "Cannot apply policy\n"); fprintf(stderr, "Cannot apply policy\n");
return 1; return 1;
} }
if (out_file && !sepol->to_file(out_file)) { if (out_file && !sepol.to_file(out_file)) {
fprintf(stderr, "Cannot dump policy to %s\n", out_file); fprintf(stderr, "Cannot dump policy to %s\n", out_file);
return 1; return 1;
} }

View File

@ -29,14 +29,13 @@ class sepol_impl {
void add_typeattribute(type_datum_t *type, type_datum_t *attr); void add_typeattribute(type_datum_t *type, type_datum_t *attr);
bool add_typeattribute(const char *type, const char *attr); bool add_typeattribute(const char *type, const char *attr);
sepol_impl(policydb *db) : db(db) {}
policydb *db; policydb *db;
std::map<std::string_view, std::array<const char *, 32>> class_perm_names; std::map<std::string_view, std::array<const char *, 32>> class_perm_names;
friend struct sepolicy; friend struct SePolicy;
public: public:
sepol_impl(policydb *db) : db(db) {}
~sepol_impl(); ~sepol_impl();
}; };

View File

@ -79,7 +79,7 @@ static void load_cil(struct cil_db *db, const char *file) {
LOGD("cil_add [%s]\n", file); LOGD("cil_add [%s]\n", file);
} }
std::unique_ptr<sepolicy> sepolicy::from_data(char *data, size_t len) noexcept { SePolicy SePolicy::from_data(char *data, size_t len) noexcept {
LOGD("Load policy from data\n"); LOGD("Load policy from data\n");
policy_file_t pf; policy_file_t pf;
@ -92,12 +92,13 @@ std::unique_ptr<sepolicy> sepolicy::from_data(char *data, size_t len) noexcept {
if (policydb_init(db) || policydb_read(db, &pf, 0)) { if (policydb_init(db) || policydb_read(db, &pf, 0)) {
LOGE("Fail to load policy from data\n"); LOGE("Fail to load policy from data\n");
free(db); free(db);
return nullptr; return {};
} }
return std::make_unique<sepolicy>(sepolicy{.impl{new sepol_impl(db)}});
return {std::make_unique<sepol_impl>(db)};
} }
std::unique_ptr<sepolicy> sepolicy::from_file(::rust::Utf8CStr file) noexcept { SePolicy SePolicy::from_file(::rust::Utf8CStr file) noexcept {
LOGD("Load policy from: %.*s\n", static_cast<int>(file.size()), file.data()); LOGD("Load policy from: %.*s\n", static_cast<int>(file.size()), file.data());
policy_file_t pf; policy_file_t pf;
@ -110,13 +111,13 @@ std::unique_ptr<sepolicy> sepolicy::from_file(::rust::Utf8CStr file) noexcept {
if (policydb_init(db) || policydb_read(db, &pf, 0)) { if (policydb_init(db) || policydb_read(db, &pf, 0)) {
LOGE("Fail to load policy from %.*s\n", static_cast<int>(file.size()), file.data()); LOGE("Fail to load policy from %.*s\n", static_cast<int>(file.size()), file.data());
free(db); free(db);
return nullptr; return {};
} }
return std::make_unique<sepolicy>(sepolicy{.impl{new sepol_impl(db)}}); return {std::make_unique<sepol_impl>(db)};
} }
std::unique_ptr<sepolicy> sepolicy::compile_split() noexcept { SePolicy SePolicy::compile_split() noexcept {
char path[128], plat_ver[10]; char path[128], plat_ver[10];
cil_db_t *db = nullptr; cil_db_t *db = nullptr;
sepol_policydb_t *pdb = nullptr; sepol_policydb_t *pdb = nullptr;
@ -207,21 +208,21 @@ std::unique_ptr<sepolicy> sepolicy::compile_split() noexcept {
load_cil(db, cil_file); load_cil(db, cil_file);
if (cil_compile(db)) if (cil_compile(db))
return nullptr; return {};
if (cil_build_policydb(db, &pdb)) if (cil_build_policydb(db, &pdb))
return nullptr; return {};
return std::make_unique<sepolicy>(sepolicy{.impl{new sepol_impl(&pdb->p)}}); return {std::make_unique<sepol_impl>(&pdb->p)};
} }
std::unique_ptr<sepolicy> sepolicy::from_split() noexcept { SePolicy SePolicy::from_split() noexcept {
const char *odm_pre = ODM_POLICY_DIR "precompiled_sepolicy"; const char *odm_pre = ODM_POLICY_DIR "precompiled_sepolicy";
const char *vend_pre = VEND_POLICY_DIR "precompiled_sepolicy"; const char *vend_pre = VEND_POLICY_DIR "precompiled_sepolicy";
if (access(odm_pre, R_OK) == 0 && check_precompiled(odm_pre)) if (access(odm_pre, R_OK) == 0 && check_precompiled(odm_pre))
return sepolicy::from_file(odm_pre); return SePolicy::from_file(odm_pre);
else if (access(vend_pre, R_OK) == 0 && check_precompiled(vend_pre)) else if (access(vend_pre, R_OK) == 0 && check_precompiled(vend_pre))
return sepolicy::from_file(vend_pre); return SePolicy::from_file(vend_pre);
else else
return sepolicy::compile_split(); return SePolicy::compile_split();
} }
sepol_impl::~sepol_impl() { sepol_impl::~sepol_impl() {
@ -229,7 +230,7 @@ sepol_impl::~sepol_impl() {
free(db); free(db);
} }
bool sepolicy::to_file(::rust::Utf8CStr file) const noexcept { bool SePolicy::to_file(::rust::Utf8CStr file) const noexcept {
// No partial writes are allowed to /sys/fs/selinux/load, thus the reason why we // No partial writes are allowed to /sys/fs/selinux/load, thus the reason why we
// first dump everything into memory, then directly call write system call // first dump everything into memory, then directly call write system call
heap_data data; heap_data data;

View File

@ -1,4 +1,4 @@
use crate::{ffi::Xperm, sepolicy}; use crate::{ffi::Xperm, SePolicy};
use base::{set_log_level_state, LogLevel}; use base::{set_log_level_state, LogLevel};
macro_rules! rules { macro_rules! rules {
@ -45,7 +45,7 @@ macro_rules! rules {
}}; }};
} }
impl sepolicy { impl SePolicy {
pub fn magisk_rules(&mut self) { pub fn magisk_rules(&mut self) {
// Temp suppress warnings // Temp suppress warnings
set_log_level_state(LogLevel::Warn, false); set_log_level_state(LogLevel::Warn, false);

View File

@ -653,14 +653,14 @@ bool sepol_impl::add_typeattribute(const char *type, const char *attr) {
return true; return true;
} }
void sepolicy::strip_dontaudit() noexcept { void SePolicy::strip_dontaudit() noexcept {
avtab_for_each(&impl->db->te_avtab, [=, this](avtab_ptr_t node) { avtab_for_each(&impl->db->te_avtab, [=, this](avtab_ptr_t node) {
if (node->key.specified == AVTAB_AUDITDENY || node->key.specified == AVTAB_XPERMS_DONTAUDIT) if (node->key.specified == AVTAB_AUDITDENY || node->key.specified == AVTAB_XPERMS_DONTAUDIT)
avtab_remove_node(&impl->db->te_avtab, node); avtab_remove_node(&impl->db->te_avtab, node);
}); });
} }
void sepolicy::print_rules() const noexcept { void SePolicy::print_rules() const noexcept {
hashtab_for_each(impl->db->p_types.table, [&](hashtab_ptr_t node) { hashtab_for_each(impl->db->p_types.table, [&](hashtab_ptr_t node) {
type_datum_t *type = auto_cast(node->datum); type_datum_t *type = auto_cast(node->datum);
if (type->flavor == TYPE_ATTRIB) { if (type->flavor == TYPE_ATTRIB) {

View File

@ -3,7 +3,7 @@ use std::io::stderr;
use std::{iter::Peekable, vec::IntoIter}; use std::{iter::Peekable, vec::IntoIter};
use crate::ffi::Xperm; use crate::ffi::Xperm;
use crate::sepolicy; use crate::SePolicy;
use base::{error, warn, FmtAdaptor}; use base::{error, warn, FmtAdaptor};
pub enum Token<'a> { pub enum Token<'a> {
@ -227,10 +227,7 @@ fn match_string<'a>(tokens: &mut Tokens<'a>, pattern: &str) -> ParseResult<'a, (
// statement ::= TC ID(s) ID(t) ID(c) ID(d) { sepolicy.type_change(s, t, c, d); }; // statement ::= TC ID(s) ID(t) ID(c) ID(d) { sepolicy.type_change(s, t, c, d); };
// statement ::= TM ID(s) ID(t) ID(c) ID(d) { sepolicy.type_member(s, t, c, d);}; // statement ::= TM ID(s) ID(t) ID(c) ID(d) { sepolicy.type_member(s, t, c, d);};
// statement ::= GF ID(s) ID(t) ID(c) { sepolicy.genfscon(s, t, c); }; // statement ::= GF ID(s) ID(t) ID(c) { sepolicy.genfscon(s, t, c); };
fn exec_statement<'a>( fn exec_statement<'a>(sepolicy: &mut SePolicy, tokens: &mut Tokens<'a>) -> ParseResult<'a, ()> {
sepolicy: &mut sepolicy,
tokens: &mut Tokens<'a>,
) -> ParseResult<'a, ()> {
let action = match tokens.next() { let action = match tokens.next() {
Some(token) => token, Some(token) => token,
_ => Err(ParseError::ShowHelp)?, _ => Err(ParseError::ShowHelp)?,
@ -444,8 +441,8 @@ fn tokenize_statement(statement: &str) -> Vec<Token> {
tokens tokens
} }
impl sepolicy { impl SePolicy {
pub fn parse_statement(self: &mut sepolicy, statement: &str) { pub fn parse_statement(self: &mut SePolicy, statement: &str) {
let statement = statement.trim(); let statement = statement.trim();
if statement.is_empty() || statement.starts_with('#') { if statement.is_empty() || statement.starts_with('#') {
return; return;
@ -600,7 +597,7 @@ allowxperm source target class ioctl *
) )
} }
impl sepolicy { impl SePolicy {
pub fn print_statement_help() { pub fn print_statement_help() {
format_statement_help(&mut FmtAdaptor(&mut stderr())).ok(); format_statement_help(&mut FmtAdaptor(&mut stderr())).ok();
eprintln!(); eprintln!();