Create custom cxx binding to Utf8CStr

This commit is contained in:
topjohnwu
2023-12-26 23:08:06 +08:00
parent 062e498bdd
commit 65207f96c8
18 changed files with 142 additions and 68 deletions
+1 -1
View File
@@ -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 -2
View File
@@ -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();
+17 -16
View File
@@ -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);
}
+4 -4
View File
@@ -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;
}