mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-12-22 16:07:39 +00:00
Create custom cxx binding to Utf8CStr
This commit is contained in:
parent
062e498bdd
commit
65207f96c8
@ -6,10 +6,12 @@ use std::path::Path;
|
||||
use std::str::{Utf8Chunks, Utf8Error};
|
||||
use std::{fmt, mem, slice, str};
|
||||
|
||||
use crate::slice_from_ptr_mut;
|
||||
use cxx::{type_id, ExternType};
|
||||
use libc::c_char;
|
||||
use thiserror::Error;
|
||||
|
||||
use crate::slice_from_ptr_mut;
|
||||
|
||||
// Utf8CStr types are UTF-8 validated and null terminated strings.
|
||||
//
|
||||
// Several Utf8CStr types:
|
||||
@ -380,6 +382,22 @@ impl DerefMut for Utf8CStr {
|
||||
}
|
||||
}
|
||||
|
||||
// Notice that we only implement ExternType on Utf8CStr *reference*
|
||||
unsafe impl ExternType for &Utf8CStr {
|
||||
type Id = type_id!("rust::Utf8CStr");
|
||||
type Kind = cxx::kind::Trivial;
|
||||
}
|
||||
|
||||
macro_rules! const_assert_eq {
|
||||
($left:expr, $right:expr $(,)?) => {
|
||||
const _: [(); $left] = [(); $right];
|
||||
};
|
||||
}
|
||||
|
||||
// Assert ABI layout
|
||||
const_assert_eq!(mem::size_of::<&Utf8CStr>(), mem::size_of::<[usize; 2]>());
|
||||
const_assert_eq!(mem::align_of::<&Utf8CStr>(), mem::align_of::<[usize; 2]>());
|
||||
|
||||
// File system path extensions types
|
||||
|
||||
#[repr(transparent)]
|
||||
|
@ -10,7 +10,8 @@ use libc::mode_t;
|
||||
use crate::logging::CxxResultExt;
|
||||
pub(crate) use crate::xwrap::*;
|
||||
use crate::{
|
||||
clone_attr, fclone_attr, fd_path, map_fd, map_file, Directory, FsPath, Utf8CStr, Utf8CStrBufRef,
|
||||
clone_attr, cstr, fclone_attr, fd_path, map_fd, map_file, slice_from_ptr, Directory, FsPath,
|
||||
Utf8CStr, Utf8CStrBufRef,
|
||||
};
|
||||
|
||||
pub(crate) fn fd_path_for_cxx(fd: RawFd, buf: &mut [u8]) -> isize {
|
||||
@ -57,12 +58,8 @@ unsafe extern "C" fn frm_rf(fd: OwnedFd) -> bool {
|
||||
inner(fd).is_ok()
|
||||
}
|
||||
|
||||
pub(crate) fn map_file_for_cxx(path: &[u8], rw: bool) -> &'static mut [u8] {
|
||||
unsafe {
|
||||
map_file(Utf8CStr::from_bytes_unchecked(path), rw)
|
||||
.log_cxx()
|
||||
.unwrap_or(&mut [])
|
||||
}
|
||||
pub(crate) fn map_file_for_cxx(path: &Utf8CStr, rw: bool) -> &'static mut [u8] {
|
||||
map_file(path, rw).log_cxx().unwrap_or(&mut [])
|
||||
}
|
||||
|
||||
pub(crate) fn map_fd_for_cxx(fd: RawFd, sz: usize, rw: bool) -> &'static mut [u8] {
|
||||
@ -171,3 +168,18 @@ unsafe extern "C" fn fclone_attr_for_cxx(a: RawFd, b: RawFd) -> bool {
|
||||
.log_cxx_with_msg(|w| w.write_str("fclone_attr failed"))
|
||||
.is_ok()
|
||||
}
|
||||
|
||||
#[export_name = "cxx$utf8str$new"]
|
||||
unsafe extern "C" fn str_new(this: &mut &Utf8CStr, s: *const u8, len: usize) {
|
||||
*this = Utf8CStr::from_bytes(slice_from_ptr(s, len)).unwrap_or(cstr!(""));
|
||||
}
|
||||
|
||||
#[export_name = "cxx$utf8str$ptr"]
|
||||
unsafe extern "C" fn str_ptr(this: &&Utf8CStr) -> *const u8 {
|
||||
this.as_ptr().cast()
|
||||
}
|
||||
|
||||
#[export_name = "cxx$utf8str$len"]
|
||||
unsafe extern "C" fn str_len(this: &&Utf8CStr) -> usize {
|
||||
this.len()
|
||||
}
|
||||
|
@ -189,7 +189,7 @@ sFILE make_file(FILE *fp) {
|
||||
}
|
||||
|
||||
mmap_data::mmap_data(const char *name, bool rw) {
|
||||
auto slice = rust::map_file(byte_view(name), rw);
|
||||
auto slice = rust::map_file(name, rw);
|
||||
if (!slice.empty()) {
|
||||
_buf = slice.data();
|
||||
_sz = slice.size();
|
||||
|
@ -34,12 +34,17 @@ pub mod ffi {
|
||||
|
||||
unsafe extern "C++" {
|
||||
include!("misc.hpp");
|
||||
|
||||
#[namespace = "rust"]
|
||||
#[cxx_name = "Utf8CStr"]
|
||||
type Utf8CStrRef<'a> = &'a crate::cstr::Utf8CStr;
|
||||
|
||||
fn mut_u8_patch(buf: &mut [u8], from: &[u8], to: &[u8]) -> Vec<usize>;
|
||||
}
|
||||
|
||||
extern "Rust" {
|
||||
#[cxx_name = "log_with_rs"]
|
||||
fn log_from_cxx(level: LogLevelCxx, msg: &[u8]);
|
||||
fn log_from_cxx(level: LogLevelCxx, msg: Utf8CStrRef);
|
||||
#[cxx_name = "set_log_level_state"]
|
||||
fn set_log_level_state_cxx(level: LogLevelCxx, enabled: bool);
|
||||
fn exit_on_error(b: bool);
|
||||
@ -53,7 +58,7 @@ pub mod ffi {
|
||||
#[cxx_name = "fd_path"]
|
||||
fn fd_path_for_cxx(fd: i32, buf: &mut [u8]) -> isize;
|
||||
#[cxx_name = "map_file"]
|
||||
fn map_file_for_cxx(path: &[u8], rw: bool) -> &'static mut [u8];
|
||||
fn map_file_for_cxx(path: Utf8CStrRef, rw: bool) -> &'static mut [u8];
|
||||
#[cxx_name = "map_fd"]
|
||||
fn map_fd_for_cxx(fd: i32, sz: usize, rw: bool) -> &'static mut [u8];
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ static int fmt_and_log_with_rs(LogLevel level, const char *fmt, va_list ap) {
|
||||
buf[0] = '\0';
|
||||
// Fortify logs when a fatal error occurs. Do not run through fortify again
|
||||
int len = std::min(__call_bypassing_fortify(vsnprintf)(buf, sz, fmt, ap), sz - 1);
|
||||
log_with_rs(level, byte_view(buf, len + 1));
|
||||
log_with_rs(level, rust::Utf8CStr(buf, len + 1));
|
||||
return len;
|
||||
}
|
||||
|
||||
|
@ -101,10 +101,8 @@ fn log_with_writer<F: FnOnce(LogWriter)>(level: LogLevel, f: F) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn log_from_cxx(level: LogLevelCxx, msg: &[u8]) {
|
||||
pub fn log_from_cxx(level: LogLevelCxx, msg: &Utf8CStr) {
|
||||
if let Some(level) = LogLevel::from_i32(level.repr) {
|
||||
// SAFETY: The null termination is handled on the C++ side
|
||||
let msg = unsafe { Utf8CStr::from_bytes_unchecked(msg) };
|
||||
log_with_writer(level, |write| write(level, msg));
|
||||
}
|
||||
}
|
||||
|
@ -274,3 +274,19 @@ int ssprintf(char *dest, size_t size, const char *fmt, ...) {
|
||||
size_t strscpy(char *dest, const char *src, size_t size) {
|
||||
return std::min(strlcpy(dest, src, size), size - 1);
|
||||
}
|
||||
|
||||
extern "C" void cxx$utf8str$new(rust::Utf8CStr *self, const void *s, size_t len);
|
||||
extern "C" const char *cxx$utf8str$ptr(const rust::Utf8CStr *self);
|
||||
extern "C" size_t cxx$utf8str$len(const rust::Utf8CStr *self);
|
||||
|
||||
rust::Utf8CStr::Utf8CStr(const char *s, size_t len) {
|
||||
cxx$utf8str$new(this, s, len);
|
||||
}
|
||||
|
||||
const char *rust::Utf8CStr::data() const {
|
||||
return cxx$utf8str$ptr(this);
|
||||
}
|
||||
|
||||
size_t rust::Utf8CStr::length() const {
|
||||
return cxx$utf8str$len(this);
|
||||
}
|
||||
|
@ -331,3 +331,30 @@ constexpr auto operator+(T e) noexcept ->
|
||||
std::enable_if_t<std::is_enum<T>::value, std::underlying_type_t<T>> {
|
||||
return static_cast<std::underlying_type_t<T>>(e);
|
||||
}
|
||||
|
||||
namespace rust {
|
||||
|
||||
struct Utf8CStr {
|
||||
const char *data() const;
|
||||
size_t length() const;
|
||||
Utf8CStr(const char *s, size_t len);
|
||||
|
||||
Utf8CStr() : Utf8CStr("", 1) {};
|
||||
Utf8CStr(const Utf8CStr &o) = default;
|
||||
Utf8CStr(Utf8CStr &&o) = default;
|
||||
Utf8CStr(const char *s) : Utf8CStr(s, strlen(s) + 1) {};
|
||||
Utf8CStr(std::string_view s) : Utf8CStr(s.data(), s.length() + 1) {};
|
||||
Utf8CStr(std::string s) : Utf8CStr(s.data(), s.length() + 1) {};
|
||||
const char *c_str() const { return this->data(); }
|
||||
size_t size() const { return this->length(); }
|
||||
bool empty() const { return this->length() == 0 ; }
|
||||
operator std::string_view() { return {data(), length()}; }
|
||||
|
||||
private:
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunused-private-field"
|
||||
std::array<std::uintptr_t, 2> repr;
|
||||
#pragma clang diagnostic pop
|
||||
};
|
||||
|
||||
} // namespace rust
|
||||
|
@ -9,7 +9,7 @@ use base::{
|
||||
Utf8CStrBufArr, Utf8CStrBufRef, WalkResult,
|
||||
};
|
||||
|
||||
use crate::ffi::{CxxMagiskD, RequestCode};
|
||||
use crate::ffi::{get_magisk_tmp, CxxMagiskD, RequestCode};
|
||||
use crate::logging::magisk_logging;
|
||||
use crate::{get_prop, MAIN_CONFIG};
|
||||
|
||||
@ -97,10 +97,6 @@ impl MagiskD {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_magisk_tmp() -> &'static Utf8CStr {
|
||||
unsafe { Utf8CStr::from_ptr(super::ffi::get_magisk_tmp()).unwrap_unchecked() }
|
||||
}
|
||||
|
||||
pub fn daemon_entry() {
|
||||
let mut qemu = get_prop(cstr!("ro.kernel.qemu"), false);
|
||||
if qemu.is_empty() {
|
||||
@ -170,13 +166,9 @@ pub fn get_magiskd() -> &'static MagiskD {
|
||||
unsafe { MAGISKD.get().unwrap_unchecked() }
|
||||
}
|
||||
|
||||
pub fn find_apk_path(pkg: &[u8], data: &mut [u8]) -> usize {
|
||||
pub fn find_apk_path(pkg: &Utf8CStr, data: &mut [u8]) -> usize {
|
||||
use WalkResult::*;
|
||||
fn inner(pkg: &[u8], buf: &mut dyn Utf8CStrBuf) -> io::Result<usize> {
|
||||
let pkg = match Utf8CStr::from_bytes(pkg) {
|
||||
Ok(pkg) => pkg,
|
||||
Err(e) => return Err(io::Error::new(io::ErrorKind::Other, e)),
|
||||
};
|
||||
fn inner(pkg: &Utf8CStr, buf: &mut dyn Utf8CStrBuf) -> io::Result<usize> {
|
||||
Directory::open(cstr!("/data/app"))?.pre_order_walk(|e| {
|
||||
if !e.is_dir() {
|
||||
return Ok(Skip);
|
||||
|
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <base.hpp>
|
||||
|
||||
namespace rust {
|
||||
struct MagiskD;
|
||||
}
|
||||
@ -24,3 +26,4 @@ private:
|
||||
};
|
||||
|
||||
const char *get_magisk_tmp();
|
||||
static inline rust::Utf8CStr get_magisk_tmp_rs() { return get_magisk_tmp(); }
|
||||
|
@ -58,9 +58,14 @@ pub mod ffi {
|
||||
}
|
||||
|
||||
unsafe extern "C++" {
|
||||
#[namespace = "rust"]
|
||||
#[cxx_name = "Utf8CStr"]
|
||||
type Utf8CStrRef<'a> = base::ffi::Utf8CStrRef<'a>;
|
||||
|
||||
include!("include/daemon.hpp");
|
||||
|
||||
fn get_magisk_tmp() -> *const c_char;
|
||||
#[cxx_name = "get_magisk_tmp_rs"]
|
||||
fn get_magisk_tmp() -> Utf8CStrRef<'static>;
|
||||
|
||||
#[cxx_name = "MagiskD"]
|
||||
type CxxMagiskD;
|
||||
@ -76,12 +81,12 @@ pub mod ffi {
|
||||
fn zygisk_logging();
|
||||
fn zygisk_close_logd();
|
||||
fn zygisk_get_logd() -> i32;
|
||||
fn find_apk_path(pkg: &[u8], data: &mut [u8]) -> usize;
|
||||
fn find_apk_path(pkg: Utf8CStrRef, data: &mut [u8]) -> usize;
|
||||
fn read_certificate(fd: i32, version: i32) -> Vec<u8>;
|
||||
unsafe fn persist_get_prop(name: *const c_char, prop_cb: Pin<&mut PropCb>);
|
||||
unsafe fn persist_get_prop(name: Utf8CStrRef, prop_cb: Pin<&mut PropCb>);
|
||||
unsafe fn persist_get_props(prop_cb: Pin<&mut PropCb>);
|
||||
unsafe fn persist_delete_prop(name: *const c_char) -> bool;
|
||||
unsafe fn persist_set_prop(name: *const c_char, value: *const c_char) -> bool;
|
||||
unsafe fn persist_delete_prop(name: Utf8CStrRef) -> bool;
|
||||
unsafe fn persist_set_prop(name: Utf8CStrRef, value: Utf8CStrRef) -> bool;
|
||||
}
|
||||
|
||||
#[namespace = "rust"]
|
||||
|
@ -19,7 +19,8 @@ use base::libc::{
|
||||
};
|
||||
use base::*;
|
||||
|
||||
use crate::daemon::{get_magisk_tmp, MagiskD, MAGISKD};
|
||||
use crate::daemon::{MagiskD, MAGISKD};
|
||||
use crate::ffi::get_magisk_tmp;
|
||||
use crate::logging::LogFile::{Actual, Buffer};
|
||||
use crate::{LOGFILE, LOG_PIPE};
|
||||
|
||||
|
@ -176,7 +176,7 @@ int get_manager(int user_id, string *pkg, bool install) {
|
||||
int app_id = to_app_id(st.st_uid);
|
||||
|
||||
byte_array<PATH_MAX> apk;
|
||||
find_apk_path(byte_view(str[SU_MANAGER]), apk);
|
||||
find_apk_path(str[SU_MANAGER], apk);
|
||||
int fd = xopen((const char *) apk.buf(), O_RDONLY | O_CLOEXEC);
|
||||
auto cert = read_certificate(fd, -1);
|
||||
close(fd);
|
||||
@ -230,7 +230,7 @@ int get_manager(int user_id, string *pkg, bool install) {
|
||||
if (stat(app_path, &st) == 0) {
|
||||
#if ENFORCE_SIGNATURE
|
||||
byte_array<PATH_MAX> apk;
|
||||
find_apk_path(byte_view(JAVA_PACKAGE_NAME), apk);
|
||||
find_apk_path(JAVA_PACKAGE_NAME, apk);
|
||||
int fd = xopen((const char *) apk.buf(), O_RDONLY | O_CLOEXEC);
|
||||
auto cert = read_certificate(fd, MAGISK_VER_CODE);
|
||||
close(fd);
|
||||
|
@ -1,4 +1,3 @@
|
||||
use core::ffi::c_char;
|
||||
use std::io::Read;
|
||||
use std::{
|
||||
fs::File,
|
||||
@ -142,9 +141,8 @@ fn proto_write_props(props: &PersistentProperties) -> LoggedResult<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub unsafe fn persist_get_prop(name: *const c_char, prop_cb: Pin<&mut PropCb>) {
|
||||
fn inner(name: *const c_char, mut prop_cb: Pin<&mut PropCb>) -> LoggedResult<()> {
|
||||
let name = unsafe { Utf8CStr::from_ptr(name)? };
|
||||
pub unsafe fn persist_get_prop(name: &Utf8CStr, prop_cb: Pin<&mut PropCb>) {
|
||||
fn inner(name: &Utf8CStr, mut prop_cb: Pin<&mut PropCb>) -> LoggedResult<()> {
|
||||
if check_proto() {
|
||||
let mut props = proto_read_props()?;
|
||||
let prop = props.find(name)?;
|
||||
@ -197,9 +195,8 @@ pub unsafe fn persist_get_props(prop_cb: Pin<&mut PropCb>) {
|
||||
inner(prop_cb).ok();
|
||||
}
|
||||
|
||||
pub unsafe fn persist_delete_prop(name: *const c_char) -> bool {
|
||||
fn inner(name: *const c_char) -> LoggedResult<()> {
|
||||
let name = unsafe { Utf8CStr::from_ptr(name)? };
|
||||
pub unsafe fn persist_delete_prop(name: &Utf8CStr) -> bool {
|
||||
fn inner(name: &Utf8CStr) -> LoggedResult<()> {
|
||||
if check_proto() {
|
||||
let mut props = proto_read_props()?;
|
||||
let idx = props.find_index(name).no_log()?;
|
||||
@ -212,10 +209,8 @@ pub unsafe fn persist_delete_prop(name: *const c_char) -> bool {
|
||||
inner(name).is_ok()
|
||||
}
|
||||
|
||||
pub unsafe fn persist_set_prop(name: *const c_char, value: *const c_char) -> bool {
|
||||
unsafe fn inner(name: *const c_char, value: *const c_char) -> LoggedResult<()> {
|
||||
let name = Utf8CStr::from_ptr(name)?;
|
||||
let value = Utf8CStr::from_ptr(value)?;
|
||||
pub unsafe fn persist_set_prop(name: &Utf8CStr, value: &Utf8CStr) -> bool {
|
||||
unsafe fn inner(name: &Utf8CStr, value: &Utf8CStr) -> LoggedResult<()> {
|
||||
if check_proto() {
|
||||
let mut props = proto_read_props()?;
|
||||
match props.find_index(name) {
|
||||
|
@ -105,7 +105,7 @@ bool sepolicy::exists(const char *type) {
|
||||
}
|
||||
|
||||
void sepolicy::load_rule_file(const char *file) {
|
||||
rust::load_rule_file(*this, byte_view(file, false));
|
||||
rust::load_rule_file(*this, file);
|
||||
}
|
||||
|
||||
void sepolicy::load_rules(const std::string &rules) {
|
||||
|
@ -3,6 +3,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string>
|
||||
|
||||
#include <base.hpp>
|
||||
|
||||
// sepolicy paths
|
||||
#define PLAT_POLICY_DIR "/system/etc/selinux/"
|
||||
#define VEND_POLICY_DIR "/vendor/etc/selinux/"
|
||||
@ -38,8 +40,7 @@ struct sepolicy {
|
||||
|
||||
// External APIs
|
||||
bool to_file(c_str file);
|
||||
void parse_statement(c_str stmt, int len);
|
||||
void parse_statement(c_str stmt) { parse_statement(stmt, strlen(stmt)); }
|
||||
void parse_statement(rust::Str stmt);
|
||||
void load_rules(const std::string &rules);
|
||||
void load_rule_file(c_str file);
|
||||
void print_rules();
|
||||
|
@ -1,33 +1,37 @@
|
||||
use io::Cursor;
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
use std::io::{BufRead, BufReader};
|
||||
use std::pin::Pin;
|
||||
use std::{io, str};
|
||||
|
||||
pub use base;
|
||||
use base::*;
|
||||
use base::libc::{O_CLOEXEC, O_RDONLY};
|
||||
use base::{BufReadExt, FsPath, LoggedResult, Utf8CStr};
|
||||
|
||||
use crate::ffi::sepolicy;
|
||||
|
||||
#[cxx::bridge]
|
||||
mod ffi {
|
||||
unsafe extern "C++" {
|
||||
#[namespace = "rust"]
|
||||
#[cxx_name = "Utf8CStr"]
|
||||
type Utf8CStrRef<'a> = base::ffi::Utf8CStrRef<'a>;
|
||||
|
||||
include!("include/sepolicy.hpp");
|
||||
|
||||
type sepolicy;
|
||||
unsafe fn parse_statement(self: Pin<&mut sepolicy>, stmt: *const c_char, len: i32);
|
||||
fn parse_statement(self: Pin<&mut sepolicy>, stmt: &str);
|
||||
}
|
||||
|
||||
#[namespace = "rust"]
|
||||
extern "Rust" {
|
||||
fn load_rules(sepol: Pin<&mut sepolicy>, rules: &[u8]);
|
||||
fn load_rule_file(sepol: Pin<&mut sepolicy>, filename: &[u8]);
|
||||
fn load_rule_file(sepol: Pin<&mut sepolicy>, filename: Utf8CStrRef);
|
||||
}
|
||||
}
|
||||
|
||||
trait SepolicyExt {
|
||||
fn load_rules(self: Pin<&mut Self>, rules: &[u8]);
|
||||
fn load_rule_file(self: Pin<&mut Self>, filename: &[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);
|
||||
}
|
||||
|
||||
@ -37,10 +41,10 @@ impl SepolicyExt for sepolicy {
|
||||
self.load_rules_from_reader(&mut cursor);
|
||||
}
|
||||
|
||||
fn load_rule_file(self: Pin<&mut sepolicy>, filename: &[u8]) {
|
||||
fn inner(sepol: Pin<&mut sepolicy>, filename: &[u8]) -> LoggedResult<()> {
|
||||
let filename = str::from_utf8(filename)?;
|
||||
let mut reader = BufReader::new(File::open(filename)?);
|
||||
fn load_rule_file(self: Pin<&mut sepolicy>, filename: &Utf8CStr) {
|
||||
fn inner(sepol: Pin<&mut sepolicy>, filename: &Utf8CStr) -> LoggedResult<()> {
|
||||
let file = FsPath::from(filename).open(O_RDONLY | O_CLOEXEC)?;
|
||||
let mut reader = BufReader::new(file);
|
||||
sepol.load_rules_from_reader(&mut reader);
|
||||
Ok(())
|
||||
}
|
||||
@ -49,17 +53,14 @@ impl SepolicyExt for sepolicy {
|
||||
|
||||
fn load_rules_from_reader<T: BufRead>(mut self: Pin<&mut sepolicy>, reader: &mut T) {
|
||||
reader.foreach_lines(|line| {
|
||||
let bytes = line.trim().as_bytes();
|
||||
unsafe {
|
||||
self.as_mut()
|
||||
.parse_statement(bytes.as_ptr().cast(), bytes.len() as i32);
|
||||
}
|
||||
let line = line.trim();
|
||||
self.as_mut().parse_statement(line);
|
||||
true
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
pub fn load_rule_file(sepol: Pin<&mut sepolicy>, filename: &[u8]) {
|
||||
pub fn load_rule_file(sepol: Pin<&mut sepolicy>, filename: &Utf8CStr) {
|
||||
sepol.load_rule_file(filename);
|
||||
}
|
||||
|
||||
|
@ -417,19 +417,19 @@ static bool parse_pattern_9(const Func &fn, const char *action, char *stmt) {
|
||||
else if (strcmp(name, action) == 0) { \
|
||||
auto __fn = [&](auto && ...args){ return (fn)(args...); }; \
|
||||
if (!parse_pattern_##type(__fn, name, remain)) \
|
||||
LOGW("Syntax error in '%.*s'\n\n%s\n", len, stmt, type_msg_##type); \
|
||||
LOGW("Syntax error in '%.*s'\n\n%s\n", (int) stmt.length(), stmt.data(), type_msg_##type); \
|
||||
}
|
||||
|
||||
#define add_action(act, type) add_action_func(#act, type, act)
|
||||
|
||||
void sepolicy::parse_statement(const char *stmt, int len) {
|
||||
void sepolicy::parse_statement(rust::Str stmt) {
|
||||
// strtok modify strings, create a copy
|
||||
string cpy(stmt, len);
|
||||
string cpy(stmt.data(), stmt.length());
|
||||
|
||||
char *remain;
|
||||
char *action = strtok_r(cpy.data(), " ", &remain);
|
||||
if (remain == nullptr) {
|
||||
LOGW("Syntax error in '%.*s'\n\n", len, stmt);
|
||||
LOGW("Syntax error in '%.*s'\n\n", (int) stmt.length(), stmt.data());
|
||||
return;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user