mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-04-29 22:14:27 +02:00
Make sepolicy a shared type between rust and cxx
This commit is contained in:
parent
7f6c9e8411
commit
c913f7ec74
@ -1,8 +1,10 @@
|
||||
#include <base.hpp>
|
||||
|
||||
#include "policy.hpp"
|
||||
#include "include/sepolicy.hpp"
|
||||
|
||||
using Str = rust::Str;
|
||||
using StrVec = rust::Vec<rust::Str>;
|
||||
using Xperms = rust::Vec<Xperm>;
|
||||
|
||||
#if 0
|
||||
template<typename Arg>
|
||||
@ -27,26 +29,6 @@ static void print_rule(const char *action, Args ...args) {
|
||||
#define print_rule(...) ((void) 0)
|
||||
#endif
|
||||
|
||||
bool sepolicy::exists(const char *type) {
|
||||
return hashtab_search(impl->db->p_types.table, type) != nullptr;
|
||||
}
|
||||
|
||||
void sepolicy::load_rule_file(const char *file) {
|
||||
rust::load_rule_file(*this, file);
|
||||
}
|
||||
|
||||
void sepolicy::parse_statement(const char *data) {
|
||||
rust::parse_statement(*this, data);
|
||||
}
|
||||
|
||||
void sepolicy::magisk_rules() {
|
||||
rust::magisk_rules(*this);
|
||||
}
|
||||
|
||||
void sepolicy::load_rules(const std::string &rules) {
|
||||
rust::load_rules(*this, byte_view(rules, false));
|
||||
}
|
||||
|
||||
template<typename F, typename ...T>
|
||||
requires(std::invocable<F, T...>)
|
||||
static inline void expand(F &&f, T &&...args) {
|
||||
@ -80,70 +62,70 @@ static inline void expand(const Xperms &vec, T &&...args) {
|
||||
}
|
||||
}
|
||||
|
||||
void sepolicy::allow(StrVec src, StrVec tgt, StrVec cls, StrVec perm) {
|
||||
void sepolicy::allow(StrVec src, StrVec tgt, StrVec cls, StrVec perm) noexcept {
|
||||
expand(src, tgt, cls, perm, [this](auto ...args) {
|
||||
print_rule("allow", args...);
|
||||
impl->add_rule(args..., AVTAB_ALLOWED, false);
|
||||
});
|
||||
}
|
||||
|
||||
void sepolicy::deny(StrVec src, StrVec tgt, StrVec cls, StrVec perm) {
|
||||
void sepolicy::deny(StrVec src, StrVec tgt, StrVec cls, StrVec perm) noexcept {
|
||||
expand(src, tgt, cls, perm, [this](auto ...args) {
|
||||
print_rule("deny", args...);
|
||||
impl->add_rule(args..., AVTAB_ALLOWED, true);
|
||||
});
|
||||
}
|
||||
|
||||
void sepolicy::auditallow(StrVec src, StrVec tgt, StrVec cls, StrVec perm) {
|
||||
void sepolicy::auditallow(StrVec src, StrVec tgt, StrVec cls, StrVec perm) noexcept {
|
||||
expand(src, tgt, cls, perm, [this](auto ...args) {
|
||||
print_rule("auditallow", args...);
|
||||
impl->add_rule(args..., AVTAB_AUDITALLOW, false);
|
||||
});
|
||||
}
|
||||
|
||||
void sepolicy::dontaudit(StrVec src, StrVec tgt, StrVec cls, StrVec perm) {
|
||||
void sepolicy::dontaudit(StrVec src, StrVec tgt, StrVec cls, StrVec perm) noexcept {
|
||||
expand(src, tgt, cls, perm, [this](auto ...args) {
|
||||
print_rule("dontaudit", args...);
|
||||
impl->add_rule(args..., AVTAB_AUDITDENY, true);
|
||||
});
|
||||
}
|
||||
|
||||
void sepolicy::permissive(StrVec types) {
|
||||
void sepolicy::permissive(StrVec types) noexcept {
|
||||
expand(types, [this](auto ...args) {
|
||||
print_rule("permissive", args...);
|
||||
impl->set_type_state(args..., true);
|
||||
});
|
||||
}
|
||||
|
||||
void sepolicy::enforce(StrVec types) {
|
||||
void sepolicy::enforce(StrVec types) noexcept {
|
||||
expand(types, [this](auto ...args) {
|
||||
print_rule("enforce", args...);
|
||||
impl->set_type_state(args..., false);
|
||||
});
|
||||
}
|
||||
|
||||
void sepolicy::typeattribute(StrVec types, StrVec attrs) {
|
||||
void sepolicy::typeattribute(StrVec types, StrVec attrs) noexcept {
|
||||
expand(types, attrs, [this](auto ...args) {
|
||||
print_rule("typeattribute", args...);
|
||||
impl->add_typeattribute(args...);
|
||||
});
|
||||
}
|
||||
|
||||
void sepolicy::type(Str type, StrVec attrs) {
|
||||
void sepolicy::type(Str type, StrVec attrs) noexcept {
|
||||
expand(type, attrs, [this](auto name, auto attr) {
|
||||
print_rule("type", name, attr);
|
||||
impl->add_type(name, TYPE_TYPE) && impl->add_typeattribute(name, attr);
|
||||
});
|
||||
}
|
||||
|
||||
void sepolicy::attribute(Str name) {
|
||||
void sepolicy::attribute(Str name) noexcept {
|
||||
expand(name, [this](auto ...args) {
|
||||
print_rule("attribute", args...);
|
||||
impl->add_type(args..., TYPE_ATTRIB);
|
||||
});
|
||||
}
|
||||
|
||||
void sepolicy::type_transition(Str src, Str tgt, Str cls, Str def, Str obj) {
|
||||
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) {
|
||||
if (o) {
|
||||
print_rule("type_transition", s, t, c, d, o);
|
||||
@ -155,42 +137,42 @@ void sepolicy::type_transition(Str src, Str tgt, Str cls, Str def, Str obj) {
|
||||
});
|
||||
}
|
||||
|
||||
void sepolicy::type_change(Str src, Str tgt, Str cls, Str def) {
|
||||
void sepolicy::type_change(Str src, Str tgt, Str cls, Str def) noexcept {
|
||||
expand(src, tgt, cls, def, [this](auto ...args) {
|
||||
print_rule("type_change", args...);
|
||||
impl->add_type_rule(args..., AVTAB_CHANGE);
|
||||
});
|
||||
}
|
||||
|
||||
void sepolicy::type_member(Str src, Str tgt, Str cls, Str def) {
|
||||
void sepolicy::type_member(Str src, Str tgt, Str cls, Str def) noexcept {
|
||||
expand(src, tgt, cls, def, [this](auto ...args) {
|
||||
print_rule("type_member", args...);
|
||||
impl->add_type_rule(args..., AVTAB_MEMBER);
|
||||
});
|
||||
}
|
||||
|
||||
void sepolicy::genfscon(Str fs_name, Str path, Str ctx) {
|
||||
void sepolicy::genfscon(Str fs_name, Str path, Str ctx) noexcept {
|
||||
expand(fs_name, path, ctx, [this](auto ...args) {
|
||||
print_rule("genfscon", args...);
|
||||
impl->add_genfscon(args...);
|
||||
});
|
||||
}
|
||||
|
||||
void sepolicy::allowxperm(StrVec src, StrVec tgt, StrVec cls, Xperms xperm) {
|
||||
void sepolicy::allowxperm(StrVec src, StrVec tgt, StrVec cls, Xperms xperm) noexcept {
|
||||
expand(src, tgt, cls, xperm, [this](auto ...args) {
|
||||
print_rule("allowxperm", args...);
|
||||
impl->add_xperm_rule(args..., AVTAB_XPERMS_ALLOWED);
|
||||
});
|
||||
}
|
||||
|
||||
void sepolicy::auditallowxperm(StrVec src, StrVec tgt, StrVec cls, Xperms xperm) {
|
||||
void sepolicy::auditallowxperm(StrVec src, StrVec tgt, StrVec cls, Xperms xperm) noexcept {
|
||||
expand(src, tgt, cls, xperm, [this](auto ...args) {
|
||||
print_rule("auditallowxperm", args...);
|
||||
impl->add_xperm_rule(args..., AVTAB_XPERMS_AUDITALLOW);
|
||||
});
|
||||
}
|
||||
|
||||
void sepolicy::dontauditxperm(StrVec src, StrVec tgt, StrVec cls, Xperms xperm) {
|
||||
void sepolicy::dontauditxperm(StrVec src, StrVec tgt, StrVec cls, Xperms xperm) noexcept {
|
||||
expand(src, tgt, cls, xperm, [this](auto ...args) {
|
||||
print_rule("dontauditxperm", args...);
|
||||
impl->add_xperm_rule(args..., AVTAB_XPERMS_DONTAUDIT);
|
||||
|
@ -1,10 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
|
||||
#include <base.hpp>
|
||||
|
||||
#include "../policy-rs.hpp"
|
||||
// sepolicy paths
|
||||
#define PLAT_POLICY_DIR "/system/etc/selinux/"
|
||||
#define VEND_POLICY_DIR "/vendor/etc/selinux/"
|
||||
@ -19,62 +20,3 @@
|
||||
#define SELINUX_POLICY SELINUX_MNT "/policy"
|
||||
#define SELINUX_LOAD SELINUX_MNT "/load"
|
||||
#define SELINUX_VERSION SELINUX_MNT "/policyvers"
|
||||
|
||||
struct Xperm;
|
||||
|
||||
using StrVec = rust::Vec<rust::Str>;
|
||||
using Xperms = rust::Vec<Xperm>;
|
||||
|
||||
struct sepolicy {
|
||||
using c_str = const char *;
|
||||
using Str = rust::Str;
|
||||
|
||||
// Public static factory functions
|
||||
static sepolicy *from_data(char *data, size_t len);
|
||||
static sepolicy *from_file(c_str file);
|
||||
static sepolicy *from_split();
|
||||
static sepolicy *compile_split();
|
||||
|
||||
// External APIs
|
||||
bool to_file(c_str file);
|
||||
void load_rules(const std::string &rules);
|
||||
void load_rule_file(c_str file);
|
||||
void print_rules();
|
||||
void parse_statement(c_str statement);
|
||||
|
||||
// Operation on types
|
||||
void type(Str type, StrVec attrs);
|
||||
void attribute(Str names);
|
||||
void permissive(StrVec types);
|
||||
void enforce(StrVec types);
|
||||
void typeattribute(StrVec types, StrVec attrs);
|
||||
bool exists(c_str type);
|
||||
|
||||
// Access vector rules
|
||||
void allow(StrVec src, StrVec tgt, StrVec cls, StrVec perm);
|
||||
void deny(StrVec src, StrVec tgt, StrVec cls, StrVec perm);
|
||||
void auditallow(StrVec src, StrVec tgt, StrVec cls, StrVec perm);
|
||||
void dontaudit(StrVec src, StrVec tgt, StrVec cls, StrVec perm);
|
||||
|
||||
// Extended permissions access vector rules
|
||||
void allowxperm(StrVec src, StrVec tgt, StrVec cls, Xperms xperm);
|
||||
void auditallowxperm(StrVec src, StrVec tgt, StrVec cls, Xperms xperm);
|
||||
void dontauditxperm(StrVec src, StrVec tgt, StrVec cls, Xperms xperm);
|
||||
|
||||
// Type rules
|
||||
void type_transition(Str src, Str tgt, Str cls, Str def, Str obj);
|
||||
void type_change(Str src, Str tgt, Str cls, Str def);
|
||||
void type_member(Str src, Str tgt, Str cls, Str def);
|
||||
|
||||
// File system labeling
|
||||
void genfscon(Str fs_name, Str path, Str ctx);
|
||||
|
||||
// Magisk
|
||||
void magisk_rules();
|
||||
|
||||
void strip_dontaudit();
|
||||
|
||||
protected:
|
||||
// Prevent anyone from accidentally creating an instance
|
||||
sepolicy() = default;
|
||||
};
|
||||
|
@ -1,16 +1,12 @@
|
||||
#![feature(format_args_nl)]
|
||||
#![feature(try_blocks)]
|
||||
|
||||
use io::Cursor;
|
||||
use std::fmt::Write;
|
||||
use std::io;
|
||||
use std::io::{BufRead, BufReader};
|
||||
use std::pin::Pin;
|
||||
|
||||
use std::io::{BufRead, BufReader, Cursor};
|
||||
use cxx::CxxString;
|
||||
pub use base;
|
||||
use base::libc::{O_CLOEXEC, O_RDONLY};
|
||||
use base::{BufReadExt, FsPath, LoggedResult, Utf8CStr};
|
||||
use statement::{parse_statement, print_statement_help};
|
||||
|
||||
use crate::ffi::sepolicy;
|
||||
|
||||
@ -18,96 +14,110 @@ mod rules;
|
||||
mod statement;
|
||||
|
||||
#[cxx::bridge]
|
||||
mod ffi {
|
||||
pub mod ffi {
|
||||
struct Xperm {
|
||||
low: u16,
|
||||
high: u16,
|
||||
reset: bool,
|
||||
}
|
||||
|
||||
pub struct sepolicy {
|
||||
#[cxx_name = "impl"]
|
||||
_impl: UniquePtr<sepol_impl>,
|
||||
}
|
||||
|
||||
unsafe extern "C++" {
|
||||
include!("policy.hpp");
|
||||
include!("../base/include/base.hpp");
|
||||
|
||||
#[namespace = "rust"]
|
||||
#[cxx_name = "Utf8CStr"]
|
||||
type Utf8CStrRef<'a> = base::ffi::Utf8CStrRef<'a>;
|
||||
|
||||
include!("include/sepolicy.hpp");
|
||||
type sepol_impl;
|
||||
|
||||
type sepolicy;
|
||||
fn allow(self: Pin<&mut sepolicy>, s: Vec<&str>, t: Vec<&str>, c: Vec<&str>, p: Vec<&str>);
|
||||
fn deny(self: Pin<&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 auditallow(
|
||||
self: Pin<&mut sepolicy>,
|
||||
self: &mut sepolicy,
|
||||
s: Vec<&str>,
|
||||
t: Vec<&str>,
|
||||
c: Vec<&str>,
|
||||
p: Vec<&str>,
|
||||
);
|
||||
fn dontaudit(
|
||||
self: Pin<&mut sepolicy>,
|
||||
self: &mut sepolicy,
|
||||
s: Vec<&str>,
|
||||
t: Vec<&str>,
|
||||
c: Vec<&str>,
|
||||
p: Vec<&str>,
|
||||
);
|
||||
fn allowxperm(
|
||||
self: Pin<&mut sepolicy>,
|
||||
self: &mut sepolicy,
|
||||
s: Vec<&str>,
|
||||
t: Vec<&str>,
|
||||
c: Vec<&str>,
|
||||
p: Vec<Xperm>,
|
||||
);
|
||||
fn auditallowxperm(
|
||||
self: Pin<&mut sepolicy>,
|
||||
self: &mut sepolicy,
|
||||
s: Vec<&str>,
|
||||
t: Vec<&str>,
|
||||
c: Vec<&str>,
|
||||
p: Vec<Xperm>,
|
||||
);
|
||||
fn dontauditxperm(
|
||||
self: Pin<&mut sepolicy>,
|
||||
self: &mut sepolicy,
|
||||
s: Vec<&str>,
|
||||
t: Vec<&str>,
|
||||
c: Vec<&str>,
|
||||
p: Vec<Xperm>,
|
||||
);
|
||||
fn permissive(self: Pin<&mut sepolicy>, t: Vec<&str>);
|
||||
fn enforce(self: Pin<&mut sepolicy>, t: Vec<&str>);
|
||||
fn typeattribute(self: Pin<&mut sepolicy>, t: Vec<&str>, a: Vec<&str>);
|
||||
fn permissive(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>);
|
||||
#[cxx_name = "type"]
|
||||
fn type_(self: Pin<&mut sepolicy>, t: &str, a: Vec<&str>);
|
||||
fn attribute(self: Pin<&mut sepolicy>, t: &str);
|
||||
fn type_transition(self: Pin<&mut sepolicy>, s: &str, t: &str, c: &str, d: &str, o: &str);
|
||||
fn type_change(self: Pin<&mut sepolicy>, s: &str, t: &str, c: &str, d: &str);
|
||||
fn type_member(self: Pin<&mut sepolicy>, s: &str, t: &str, c: &str, d: &str);
|
||||
fn genfscon(self: Pin<&mut sepolicy>, s: &str, t: &str, c: &str);
|
||||
fn type_(self: &mut sepolicy, t: &str, a: Vec<&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_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 genfscon(self: &mut sepolicy, s: &str, t: &str, c: &str);
|
||||
#[allow(dead_code)]
|
||||
fn strip_dontaudit(self: Pin<&mut sepolicy>);
|
||||
fn strip_dontaudit(self: &mut sepolicy);
|
||||
|
||||
fn print_rules(self: &sepolicy);
|
||||
fn to_file(self: &sepolicy, file: Utf8CStrRef) -> bool;
|
||||
|
||||
#[Self = sepolicy]
|
||||
fn from_file(file: Utf8CStrRef) -> UniquePtr<sepolicy>;
|
||||
#[Self = sepolicy]
|
||||
fn from_split() -> UniquePtr<sepolicy>;
|
||||
#[Self = sepolicy]
|
||||
fn compile_split() -> UniquePtr<sepolicy>;
|
||||
#[Self = sepolicy]
|
||||
unsafe fn from_data(data: *mut c_char, len: usize) -> UniquePtr<sepolicy>;
|
||||
}
|
||||
|
||||
#[namespace = "rust"]
|
||||
extern "Rust" {
|
||||
fn load_rules(sepol: Pin<&mut sepolicy>, rules: &[u8]);
|
||||
fn load_rule_file(sepol: Pin<&mut sepolicy>, filename: Utf8CStrRef);
|
||||
fn parse_statement(sepol: Pin<&mut sepolicy>, statement: Utf8CStrRef);
|
||||
fn magisk_rules(sepol: Pin<&mut sepolicy>);
|
||||
fn parse_statement(self: &mut sepolicy, statement: Utf8CStrRef);
|
||||
fn magisk_rules(self: &mut sepolicy);
|
||||
fn load_rule_file(self: &mut sepolicy, filename: Utf8CStrRef);
|
||||
fn load_rules(self: &mut sepolicy, rules: &CxxString);
|
||||
#[Self = sepolicy]
|
||||
fn xperm_to_string(perm: &Xperm) -> String;
|
||||
#[Self = sepolicy]
|
||||
fn print_statement_help();
|
||||
}
|
||||
}
|
||||
|
||||
trait SepolicyExt {
|
||||
fn load_rules(self: Pin<&mut Self>, rules: &[u8]);
|
||||
fn load_rule_file(self: Pin<&mut Self>, filename: &Utf8CStr);
|
||||
fn load_rules_from_reader<T: BufRead>(self: Pin<&mut Self>, reader: &mut T);
|
||||
}
|
||||
|
||||
impl SepolicyExt for sepolicy {
|
||||
fn load_rules(self: Pin<&mut sepolicy>, rules: &[u8]) {
|
||||
let mut cursor = Cursor::new(rules);
|
||||
impl sepolicy {
|
||||
fn load_rules(self: &mut sepolicy, rules: &CxxString) {
|
||||
let mut cursor = Cursor::new(rules.as_bytes());
|
||||
self.load_rules_from_reader(&mut cursor);
|
||||
}
|
||||
|
||||
fn load_rule_file(self: Pin<&mut sepolicy>, filename: &Utf8CStr) {
|
||||
pub fn load_rule_file(self: &mut sepolicy, filename: &Utf8CStr) {
|
||||
let result: LoggedResult<()> = try {
|
||||
let file = FsPath::from(filename).open(O_RDONLY | O_CLOEXEC)?;
|
||||
let mut reader = BufReader::new(file);
|
||||
@ -116,40 +126,24 @@ impl SepolicyExt for sepolicy {
|
||||
result.ok();
|
||||
}
|
||||
|
||||
fn load_rules_from_reader<T: BufRead>(mut self: Pin<&mut sepolicy>, reader: &mut T) {
|
||||
fn load_rules_from_reader<T: BufRead>(self: &mut sepolicy, reader: &mut T) {
|
||||
reader.foreach_lines(|line| {
|
||||
parse_statement(self.as_mut(), line);
|
||||
self.parse_statement(line);
|
||||
true
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
fn load_rule_file(sepol: Pin<&mut sepolicy>, filename: &Utf8CStr) {
|
||||
sepol.load_rule_file(filename);
|
||||
}
|
||||
|
||||
fn load_rules(sepol: Pin<&mut sepolicy>, rules: &[u8]) {
|
||||
sepol.load_rules(rules);
|
||||
}
|
||||
|
||||
trait SepolicyMagisk {
|
||||
fn magisk_rules(self: Pin<&mut Self>);
|
||||
}
|
||||
|
||||
fn magisk_rules(sepol: Pin<&mut sepolicy>) {
|
||||
sepol.magisk_rules();
|
||||
}
|
||||
|
||||
fn xperm_to_string(perm: &ffi::Xperm) -> String {
|
||||
let mut s = String::new();
|
||||
if perm.reset {
|
||||
s.push('~');
|
||||
fn xperm_to_string(perm: &ffi::Xperm) -> String {
|
||||
let mut s = String::new();
|
||||
if perm.reset {
|
||||
s.push('~');
|
||||
}
|
||||
if perm.low == perm.high {
|
||||
s.write_fmt(format_args!("{{ {:#06X} }}", perm.low)).ok();
|
||||
} else {
|
||||
s.write_fmt(format_args!("{{ {:#06X}-{:#06X} }}", perm.low, perm.high))
|
||||
.ok();
|
||||
}
|
||||
s
|
||||
}
|
||||
if perm.low == perm.high {
|
||||
s.write_fmt(format_args!("{{ {:#06X} }}", perm.low)).ok();
|
||||
} else {
|
||||
s.write_fmt(format_args!("{{ {:#06X}-{:#06X} }}", perm.low, perm.high))
|
||||
.ok();
|
||||
}
|
||||
s
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include <base.hpp>
|
||||
#include <vector>
|
||||
|
||||
#include "policy.hpp"
|
||||
#include "include/sepolicy.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -36,7 +36,7 @@ int main(int argc, char *argv[]) {
|
||||
cmdline_logging();
|
||||
const char *out_file = nullptr;
|
||||
vector<string_view> rule_files;
|
||||
sepolicy *sepol = nullptr;
|
||||
std::unique_ptr<sepolicy> sepol;
|
||||
bool magisk = false;
|
||||
bool live = false;
|
||||
bool print = false;
|
||||
@ -85,7 +85,7 @@ int main(int argc, char *argv[]) {
|
||||
rule_files.emplace_back(argv[i + 1]);
|
||||
++i;
|
||||
} else if (option == "help"sv) {
|
||||
rust::print_statement_help();
|
||||
sepolicy::print_statement_help();
|
||||
exit(0);
|
||||
} else {
|
||||
usage(argv[0]);
|
||||
@ -126,6 +126,5 @@ int main(int argc, char *argv[]) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
delete sepol;
|
||||
return 0;
|
||||
}
|
||||
|
@ -6,11 +6,10 @@
|
||||
#include <string_view>
|
||||
|
||||
#include <sepol/policydb/policydb.h>
|
||||
#include <sepolicy.hpp>
|
||||
|
||||
#include "policy-rs.hpp"
|
||||
struct Xperm;
|
||||
|
||||
struct sepol_impl : public sepolicy {
|
||||
class sepol_impl {
|
||||
avtab_ptr_t find_avtab_node(avtab_key_t *key, avtab_extended_perms_t *xperms);
|
||||
avtab_ptr_t insert_avtab_node(avtab_key_t *key);
|
||||
avtab_ptr_t get_avtab_node(avtab_key_t *key, avtab_extended_perms_t *xperms);
|
||||
@ -31,12 +30,13 @@ struct sepol_impl : public sepolicy {
|
||||
bool add_typeattribute(const char *type, const char *attr);
|
||||
|
||||
sepol_impl(policydb *db) : db(db) {}
|
||||
~sepol_impl();
|
||||
|
||||
policydb *db;
|
||||
|
||||
private:
|
||||
std::map<std::string_view, std::array<const char *, 32>> class_perm_names;
|
||||
};
|
||||
|
||||
#define impl reinterpret_cast<sepol_impl *>(this)
|
||||
friend struct sepolicy;
|
||||
|
||||
public:
|
||||
~sepol_impl();
|
||||
};
|
||||
|
@ -1,3 +1,5 @@
|
||||
#include "include/sepolicy.hpp"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
@ -8,7 +10,6 @@
|
||||
#include <base.hpp>
|
||||
#include <stream.hpp>
|
||||
|
||||
#include "policy.hpp"
|
||||
|
||||
#define SHALEN 64
|
||||
static bool cmp_sha256(const char *a, const char *b) {
|
||||
@ -78,7 +79,7 @@ static void load_cil(struct cil_db *db, const char *file) {
|
||||
LOGD("cil_add [%s]\n", file);
|
||||
}
|
||||
|
||||
sepolicy *sepolicy::from_data(char *data, size_t len) {
|
||||
std::unique_ptr<sepolicy> sepolicy::from_data(char *data, size_t len) noexcept {
|
||||
LOGD("Load policy from data\n");
|
||||
|
||||
policy_file_t pf;
|
||||
@ -93,32 +94,29 @@ sepolicy *sepolicy::from_data(char *data, size_t len) {
|
||||
free(db);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto sepol = new sepol_impl(db);
|
||||
return sepol;
|
||||
return std::make_unique<sepolicy>(sepolicy{.impl{new sepol_impl(db)}});
|
||||
}
|
||||
|
||||
sepolicy *sepolicy::from_file(const char *file) {
|
||||
LOGD("Load policy from: %s\n", file);
|
||||
std::unique_ptr<sepolicy> sepolicy::from_file(::rust::Utf8CStr file) noexcept {
|
||||
LOGD("Load policy from: %.*s\n", static_cast<int>(file.size()), file.data());
|
||||
|
||||
policy_file_t pf;
|
||||
policy_file_init(&pf);
|
||||
auto fp = xopen_file(file, "re");
|
||||
auto fp = xopen_file(file.data(), "re");
|
||||
pf.fp = fp.get();
|
||||
pf.type = PF_USE_STDIO;
|
||||
|
||||
auto db = static_cast<policydb_t *>(malloc(sizeof(policydb_t)));
|
||||
if (policydb_init(db) || policydb_read(db, &pf, 0)) {
|
||||
LOGE("Fail to load policy from %s\n", file);
|
||||
LOGE("Fail to load policy from %.*s\n", static_cast<int>(file.size()), file.data());
|
||||
free(db);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto sepol = new sepol_impl(db);
|
||||
return sepol;
|
||||
return std::make_unique<sepolicy>(sepolicy{.impl{new sepol_impl(db)}});
|
||||
}
|
||||
|
||||
sepolicy *sepolicy::compile_split() {
|
||||
std::unique_ptr<sepolicy> sepolicy::compile_split() noexcept {
|
||||
char path[128], plat_ver[10];
|
||||
cil_db_t *db = nullptr;
|
||||
sepol_policydb_t *pdb = nullptr;
|
||||
@ -212,12 +210,10 @@ sepolicy *sepolicy::compile_split() {
|
||||
return nullptr;
|
||||
if (cil_build_policydb(db, &pdb))
|
||||
return nullptr;
|
||||
|
||||
auto sepol = new sepol_impl(&pdb->p);
|
||||
return sepol;
|
||||
return std::make_unique<sepolicy>(sepolicy{.impl{new sepol_impl(&pdb->p)}});
|
||||
}
|
||||
|
||||
sepolicy *sepolicy::from_split() {
|
||||
std::unique_ptr<sepolicy> sepolicy::from_split() noexcept {
|
||||
const char *odm_pre = ODM_POLICY_DIR "precompiled_sepolicy";
|
||||
const char *vend_pre = VEND_POLICY_DIR "precompiled_sepolicy";
|
||||
if (access(odm_pre, R_OK) == 0 && check_precompiled(odm_pre))
|
||||
@ -233,7 +229,7 @@ sepol_impl::~sepol_impl() {
|
||||
free(db);
|
||||
}
|
||||
|
||||
bool sepolicy::to_file(const char *file) {
|
||||
bool sepolicy::to_file(::rust::Utf8CStr file) const noexcept {
|
||||
// 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
|
||||
heap_data data;
|
||||
@ -248,7 +244,7 @@ bool sepolicy::to_file(const char *file) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int fd = xopen(file, O_WRONLY | O_CREAT | O_CLOEXEC, 0644);
|
||||
int fd = xopen(file.data(), O_WRONLY | O_CREAT | O_CLOEXEC, 0644);
|
||||
if (fd < 0)
|
||||
return false;
|
||||
if (struct stat st{}; xfstat(fd, &st) == 0 && st.st_size > 0) {
|
||||
|
@ -1,6 +1,5 @@
|
||||
use crate::{ffi::Xperm, sepolicy, SepolicyMagisk};
|
||||
use crate::{ffi::Xperm, sepolicy};
|
||||
use base::{set_log_level_state, LogLevel};
|
||||
use std::pin::Pin;
|
||||
|
||||
macro_rules! rules {
|
||||
(@args all) => {
|
||||
@ -38,7 +37,7 @@ macro_rules! rules {
|
||||
};
|
||||
(@stmt $self:ident) => {};
|
||||
(@stmt $self:ident $action:ident($($args:tt),*); $($res:tt)*) => {
|
||||
$self.as_mut().$action($(rules!(@args $args)),*);
|
||||
$self.$action($(rules!(@args $args)),*);
|
||||
rules!{@stmt $self $($res)* }
|
||||
};
|
||||
(use $self:ident; $($res:tt)*) => {{
|
||||
@ -46,8 +45,8 @@ macro_rules! rules {
|
||||
}};
|
||||
}
|
||||
|
||||
impl SepolicyMagisk for sepolicy {
|
||||
fn magisk_rules(mut self: Pin<&mut Self>) {
|
||||
impl sepolicy {
|
||||
pub fn magisk_rules(&mut self) {
|
||||
// Temp suppress warnings
|
||||
set_log_level_state(LogLevel::Warn, false);
|
||||
rules! {
|
||||
@ -138,7 +137,7 @@ impl SepolicyMagisk for sepolicy {
|
||||
}
|
||||
|
||||
#[cfg(any())]
|
||||
self.as_mut().strip_dontaudit();
|
||||
self.strip_dontaudit();
|
||||
|
||||
set_log_level_state(LogLevel::Warn, true);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include <base.hpp>
|
||||
|
||||
#include "policy.hpp"
|
||||
#include "include/sepolicy.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -653,14 +653,14 @@ bool sepol_impl::add_typeattribute(const char *type, const char *attr) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void sepolicy::strip_dontaudit() {
|
||||
void sepolicy::strip_dontaudit() noexcept {
|
||||
avtab_for_each(&impl->db->te_avtab, [=, this](avtab_ptr_t node) {
|
||||
if (node->key.specified == AVTAB_AUDITDENY || node->key.specified == AVTAB_XPERMS_DONTAUDIT)
|
||||
avtab_remove_node(&impl->db->te_avtab, node);
|
||||
});
|
||||
}
|
||||
|
||||
void sepolicy::print_rules() {
|
||||
void sepolicy::print_rules() const noexcept {
|
||||
hashtab_for_each(impl->db->p_types.table, [&](hashtab_ptr_t node) {
|
||||
type_datum_t *type = auto_cast(node->datum);
|
||||
if (type->flavor == TYPE_ATTRIB) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
use std::fmt::{Display, Formatter, Write};
|
||||
use std::io::stderr;
|
||||
use std::{iter::Peekable, pin::Pin, vec::IntoIter};
|
||||
use std::{iter::Peekable, vec::IntoIter};
|
||||
|
||||
use crate::ffi::Xperm;
|
||||
use crate::sepolicy;
|
||||
@ -228,7 +228,7 @@ fn match_string<'a>(tokens: &mut Tokens<'a>, pattern: &str) -> ParseResult<'a, (
|
||||
// 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); };
|
||||
fn exec_statement<'a>(
|
||||
sepolicy: Pin<&mut sepolicy>,
|
||||
sepolicy: &mut sepolicy,
|
||||
tokens: &mut Tokens<'a>,
|
||||
) -> ParseResult<'a, ()> {
|
||||
let action = match tokens.next() {
|
||||
@ -444,16 +444,18 @@ fn tokenize_statement(statement: &str) -> Vec<Token> {
|
||||
tokens
|
||||
}
|
||||
|
||||
pub fn parse_statement(sepolicy: Pin<&mut sepolicy>, statement: &str) {
|
||||
let statement = statement.trim();
|
||||
if statement.is_empty() || statement.starts_with('#') {
|
||||
return;
|
||||
}
|
||||
let mut tokens = tokenize_statement(statement).into_iter().peekable();
|
||||
let result = exec_statement(sepolicy, &mut tokens);
|
||||
if let Err(e) = result {
|
||||
warn!("Syntax error in: \"{}\"", statement);
|
||||
error!("Hint: {}", e);
|
||||
impl sepolicy {
|
||||
pub fn parse_statement(self: &mut sepolicy, statement: &str) {
|
||||
let statement = statement.trim();
|
||||
if statement.is_empty() || statement.starts_with('#') {
|
||||
return;
|
||||
}
|
||||
let mut tokens = tokenize_statement(statement).into_iter().peekable();
|
||||
let result = exec_statement(self, &mut tokens);
|
||||
if let Err(e) = result {
|
||||
warn!("Syntax error in: \"{}\"", statement);
|
||||
error!("Hint: {}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -598,7 +600,9 @@ allowxperm source target class ioctl *
|
||||
)
|
||||
}
|
||||
|
||||
pub fn print_statement_help() {
|
||||
format_statement_help(&mut FmtAdaptor(&mut stderr())).ok();
|
||||
eprintln!();
|
||||
impl sepolicy {
|
||||
pub fn print_statement_help() {
|
||||
format_statement_help(&mut FmtAdaptor(&mut stderr())).ok();
|
||||
eprintln!();
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user