Several code cleanups in sepolicy

This commit is contained in:
topjohnwu 2024-03-20 23:09:22 -07:00
parent 4d2921e742
commit d654b9cb97
6 changed files with 145 additions and 141 deletions

View File

@ -1,12 +1,17 @@
#include <base.hpp>
#include "flags.h"
#include "policy.hpp"
using Str = rust::Str;
#if MAGISK_DEBUG
template<typename Arg>
auto as_str(Arg arg) {
std::string as_str(const Arg &arg) {
if constexpr (std::is_same_v<Arg, const char *> || std::is_same_v<Arg, char *>) {
return arg == nullptr ? std::string("*") : std::string(arg);
return arg == nullptr ? "*" : arg;
} else if constexpr (std::is_same_v<Arg, Xperm>) {
return std::string(rust::xperm_to_string(arg));
} else {
return std::to_string(arg);
}
@ -14,13 +19,13 @@ auto as_str(Arg arg) {
// Print out all rules going through public API for debugging
template<typename ...Args>
static void dprint(const char *action, Args ...args) {
static void print_rule(const char *action, Args ...args) {
std::string s;
s = (... + (" " + as_str(args)));
LOGD("%s%s", action, s.data());
LOGD("%s%s\n", action, s.data());
}
#else
#define dprint(...) ((void) 0)
#define print_rule(...) ((void) 0)
#endif
bool sepolicy::exists(const char *type) {
@ -45,107 +50,109 @@ void sepolicy::load_rules(const std::string &rules) {
template<typename F, typename ...T>
requires(std::invocable<F, T...>)
inline void expand(F &&f, T &&...args) {
static inline void expand(F &&f, T &&...args) {
f(std::forward<T>(args)...);
}
template<typename ...T>
inline void expand(const rust::Vec<rust::Str> &vec, T &&...args) {
for (auto i = vec.begin(); i != vec.end() || vec.empty(); ++i) {
expand(std::forward<T>(args)..., vec.empty() ? nullptr : std::string(*i).data());
if (vec.empty()) break;
static inline void expand(const StrVec &vec, T &&...args) {
if (vec.empty()) {
expand(std::forward<T>(args)..., (char *) nullptr);
} else {
char buf[64];
for (auto &s : vec) {
if (s.length() >= sizeof(buf)) continue;
memcpy(buf, s.data(), s.length());
buf[s.length()] = '\0';
expand(std::forward<T>(args)..., buf);
}
}
}
template<typename ...T>
inline void expand(const rust::Vec<Xperm> &vec, T &&...args) {
static inline void expand(const Xperms &vec, T &&...args) {
for (auto &p : vec) {
expand(std::forward<T>(args)..., p.low, p.high, p.reset);
expand(std::forward<T>(args)..., p);
}
}
template<typename ...T>
inline void expand(const rust::Str &s, T &&...args) {
expand(std::forward<T>(args)..., std::string(s).data());
static inline void expand(const Str &s, T &&...args) {
char buf[64];
if (s.length() >= sizeof(buf)) return;
memcpy(buf, s.data(), s.length());
buf[s.length()] = '\0';
expand(std::forward<T>(args)..., buf);
}
void
sepolicy::allow(rust::Vec<rust::Str> src, rust::Vec<rust::Str> tgt, rust::Vec<rust::Str> cls,
rust::Vec<rust::Str> perm) {
void sepolicy::allow(StrVec src, StrVec tgt, StrVec cls, StrVec perm) {
expand(src, tgt, cls, perm, [this](auto ...args) {
dprint("allow", args...);
print_rule("allow", args...);
impl->add_rule(args..., AVTAB_ALLOWED, false);
});
}
void
sepolicy::deny(rust::Vec<rust::Str> src, rust::Vec<rust::Str> tgt, rust::Vec<rust::Str> cls,
rust::Vec<rust::Str> perm) {
void sepolicy::deny(StrVec src, StrVec tgt, StrVec cls, StrVec perm) {
expand(src, tgt, cls, perm, [this](auto ...args) {
dprint("deny", args...);
print_rule("deny", args...);
impl->add_rule(args..., AVTAB_ALLOWED, true);
});
}
void sepolicy::auditallow(rust::Vec<rust::Str> src, rust::Vec<rust::Str> tgt,
rust::Vec<rust::Str> cls,
rust::Vec<rust::Str> perm) {
void sepolicy::auditallow(StrVec src, StrVec tgt, StrVec cls, StrVec perm) {
expand(src, tgt, cls, perm, [this](auto ...args) {
dprint("auditallow", args...);
print_rule("auditallow", args...);
impl->add_rule(args..., AVTAB_AUDITALLOW, false);
});
}
void sepolicy::dontaudit(rust::Vec<rust::Str> src, rust::Vec<rust::Str> tgt,
rust::Vec<rust::Str> cls,
rust::Vec<rust::Str> perm) {
void sepolicy::dontaudit(StrVec src, StrVec tgt, StrVec cls, StrVec perm) {
expand(src, tgt, cls, perm, [this](auto ...args) {
dprint("dontaudit", args...);
print_rule("dontaudit", args...);
impl->add_rule(args..., AVTAB_AUDITDENY, true);
});
}
void sepolicy::permissive(rust::Vec<rust::Str> types) {
void sepolicy::permissive(StrVec types) {
expand(types, [this](auto ...args) {
dprint("permissive", args...);
print_rule("permissive", args...);
impl->set_type_state(args..., true);
});
}
void sepolicy::enforce(rust::Vec<rust::Str> types) {
void sepolicy::enforce(StrVec types) {
expand(types, [this](auto ...args) {
dprint("enforce", args...);
print_rule("enforce", args...);
impl->set_type_state(args..., false);
});
}
void sepolicy::typeattribute(rust::Vec<rust::Str> types, rust::Vec<rust::Str> attrs) {
void sepolicy::typeattribute(StrVec types, StrVec attrs) {
expand(types, attrs, [this](auto ...args) {
dprint("typeattribute", args...);
print_rule("typeattribute", args...);
impl->add_typeattribute(args...);
});
}
void sepolicy::type(rust::Str type, rust::Vec<rust::Str> attrs) {
void sepolicy::type(Str type, StrVec attrs) {
expand(type, attrs, [this](auto name, auto attr) {
dprint("type", name, attr);
print_rule("type", name, attr);
impl->add_type(name, TYPE_TYPE) && impl->add_typeattribute(name, attr);
});
}
void sepolicy::attribute(rust::Str name) {
void sepolicy::attribute(Str name) {
expand(name, [this](auto ...args) {
dprint("name", args...);
print_rule("name", args...);
impl->add_type(args..., TYPE_ATTRIB);
});
}
void sepolicy::type_transition(rust::Str src, rust::Str tgt, rust::Str cls, rust::Str def,
rust::Vec<rust::Str> obj) {
void sepolicy::type_transition(Str src, Str tgt, Str cls, Str def, StrVec obj) {
auto obj_str = obj.empty() ? std::string() : std::string(obj[0]);
auto o = obj.empty() ? nullptr : obj_str.data();
expand(src, tgt, cls, def, [this, &o](auto ...args) {
dprint("type_transition", args..., o);
print_rule("type_transition", args..., o);
if (o) {
impl->add_filename_trans(args..., o);
} else {
@ -154,54 +161,44 @@ void sepolicy::type_transition(rust::Str src, rust::Str tgt, rust::Str cls, rust
});
}
void sepolicy::type_change(rust::Str src, rust::Str tgt, rust::Str cls, rust::Str def) {
void sepolicy::type_change(Str src, Str tgt, Str cls, Str def) {
expand(src, tgt, cls, def, [this](auto ...args) {
dprint("type_change", args...);
print_rule("type_change", args...);
impl->add_type_rule(args..., AVTAB_CHANGE);
});
}
void sepolicy::type_member(rust::Str src, rust::Str tgt, rust::Str cls, rust::Str def) {
void sepolicy::type_member(Str src, Str tgt, Str cls, Str def) {
expand(src, tgt, cls, def, [this](auto ...args) {
dprint("type_member", args...);
print_rule("type_member", args...);
impl->add_type_rule(args..., AVTAB_MEMBER);
});
}
void sepolicy::genfscon(rust::Str fs_name, rust::Str path, rust::Str ctx) {
void sepolicy::genfscon(Str fs_name, Str path, Str ctx) {
expand(fs_name, path, ctx, [this](auto ...args) {
dprint("genfscon", args...);
print_rule("genfscon", args...);
impl->add_genfscon(args...);
});
}
void
sepolicy::allowxperm(rust::Vec<rust::Str> src, rust::Vec<rust::Str> tgt, rust::Vec<rust::Str> cls,
rust::Vec<Xperm> xperm) {
void sepolicy::allowxperm(StrVec src, StrVec tgt, StrVec cls, Xperms xperm) {
expand(src, tgt, cls, xperm, [this](auto ...args) {
dprint("allowxperm", args...);
print_rule("allowxperm", args...);
impl->add_xperm_rule(args..., AVTAB_XPERMS_ALLOWED);
});
}
void sepolicy::auditallowxperm(rust::Vec<rust::Str> src, rust::Vec<rust::Str> tgt,
rust::Vec<rust::Str> cls,
rust::Vec<Xperm> xperm) {
void sepolicy::auditallowxperm(StrVec src, StrVec tgt, StrVec cls, Xperms xperm) {
expand(src, tgt, cls, xperm, [this](auto ...args) {
dprint("auditallowxperm", args...);
print_rule("auditallowxperm", args...);
impl->add_xperm_rule(args..., AVTAB_XPERMS_AUDITALLOW);
});
}
void sepolicy::dontauditxperm(rust::Vec<rust::Str> src, rust::Vec<rust::Str> tgt,
rust::Vec<rust::Str> cls,
rust::Vec<Xperm> xperm) {
void sepolicy::dontauditxperm(StrVec src, StrVec tgt, StrVec cls, Xperms xperm) {
expand(src, tgt, cls, xperm, [this](auto ...args) {
dprint("dontauditxperm", args...);
print_rule("dontauditxperm", args...);
impl->add_xperm_rule(args..., AVTAB_XPERMS_DONTAUDIT);
});
}
void sepolicy::strip_dontaudit() {
impl->strip_dontaudit();
}

View File

@ -20,22 +20,21 @@
#define SELINUX_LOAD SELINUX_MNT "/load"
#define SELINUX_VERSION SELINUX_MNT "/policyvers"
using token_list = std::vector<const char *>;
using argument = std::pair<token_list, bool>;
using argument_list = std::vector<argument>;
struct Xperm;
#define ALL nullptr
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);
@ -44,31 +43,31 @@ struct sepolicy {
void parse_statement(c_str statement);
// Operation on types
void type(rust::Str type, rust::Vec<rust::Str> attrs);
void attribute(rust::Str names);
void permissive(rust::Vec<rust::Str> types);
void enforce(rust::Vec<rust::Str> types);
void typeattribute(rust::Vec<rust::Str> types, rust::Vec<rust::Str> attrs);
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(rust::Vec<rust::Str> src, rust::Vec<rust::Str> tgt, rust::Vec<rust::Str> cls, rust::Vec<rust::Str> perm);
void deny(rust::Vec<rust::Str> src, rust::Vec<rust::Str> tgt, rust::Vec<rust::Str> cls, rust::Vec<rust::Str> perm);
void auditallow(rust::Vec<rust::Str> src, rust::Vec<rust::Str> tgt, rust::Vec<rust::Str> cls, rust::Vec<rust::Str> perm);
void dontaudit(rust::Vec<rust::Str> src, rust::Vec<rust::Str> tgt, rust::Vec<rust::Str> cls, rust::Vec<rust::Str> perm);
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(rust::Vec<rust::Str> src, rust::Vec<rust::Str> tgt, rust::Vec<rust::Str> cls, rust::Vec<Xperm> xperm);
void auditallowxperm(rust::Vec<rust::Str> src, rust::Vec<rust::Str> tgt, rust::Vec<rust::Str> cls, rust::Vec<Xperm> xperm);
void dontauditxperm(rust::Vec<rust::Str> src, rust::Vec<rust::Str> tgt, rust::Vec<rust::Str> cls, rust::Vec<Xperm> xperm);
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(rust::Str src, rust::Str tgt, rust::Str cls, rust::Str def, rust::Vec<rust::Str> obj);
void type_change(rust::Str src, rust::Str tgt, rust::Str cls, rust::Str def);
void type_member(rust::Str src, rust::Str tgt, rust::Str cls, rust::Str def);
void type_transition(Str src, Str tgt, Str cls, Str def, StrVec 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(rust::Str fs_name, rust::Str path, rust::Str ctx);
void genfscon(Str fs_name, Str path, Str ctx);
// Magisk
void magisk_rules();

View File

@ -1,6 +1,7 @@
#![feature(format_args_nl)]
use io::Cursor;
use std::fmt::Write;
use std::io;
use std::io::{BufRead, BufReader};
use std::pin::Pin;
@ -11,9 +12,8 @@ use base::{error, BufReadExt, FsPath, LoggedResult, Utf8CStr};
use crate::ffi::sepolicy;
mod statement;
mod rules;
mod statement;
#[cxx::bridge]
mod ffi {
@ -94,6 +94,7 @@ mod ffi {
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 xperm_to_string(perm: &Xperm) -> String;
}
}
@ -104,10 +105,6 @@ trait SepolicyExt {
fn parse_statement(self: Pin<&mut Self>, statement: &str);
}
trait SepolicyMagisk {
fn magisk_rules(self: Pin<&mut Self>);
}
impl SepolicyExt for sepolicy {
fn load_rules(self: Pin<&mut sepolicy>, rules: &[u8]) {
let mut cursor = Cursor::new(rules);
@ -136,24 +133,38 @@ impl SepolicyExt for sepolicy {
}
fn parse_statement(self: Pin<&mut Self>, statement: &str) {
if let Err(_) = statement::parse_statement(self, statement) {
if statement::parse_statement(self, statement).is_err() {
error!("sepolicy rule syntax error: {statement}");
}
}
}
pub fn load_rule_file(sepol: Pin<&mut sepolicy>, filename: &Utf8CStr) {
fn load_rule_file(sepol: Pin<&mut sepolicy>, filename: &Utf8CStr) {
sepol.load_rule_file(filename);
}
pub fn load_rules(sepol: Pin<&mut sepolicy>, rules: &[u8]) {
fn load_rules(sepol: Pin<&mut sepolicy>, rules: &[u8]) {
sepol.load_rules(rules);
}
pub fn parse_statement(sepol: Pin<&mut sepolicy>, statement: &Utf8CStr) {
fn parse_statement(sepol: Pin<&mut sepolicy>, statement: &Utf8CStr) {
sepol.parse_statement(statement.as_str());
}
pub fn magisk_rules(sepol: Pin<&mut sepolicy>) {
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('~');
}
s.write_fmt(format_args!("{{ {:#06x}-{:#06x} }}", perm.low, perm.high))
.ok();
s
}

View File

@ -20,8 +20,8 @@ struct sepol_impl : public sepolicy {
bool add_rule(const char *s, const char *t, const char *c, const char *p, int effect, bool invert);
void add_rule(type_datum_t *src, type_datum_t *tgt, class_datum_t *cls, perm_datum_t *perm, int effect, bool invert);
void add_xperm_rule(type_datum_t *src, type_datum_t *tgt, class_datum_t *cls, uint16_t low, uint16_t high, bool reset, int effect);
bool add_xperm_rule(const char *s, const char *t, const char *c, uint16_t low, uint16_t high, bool reset, int effect);
void add_xperm_rule(type_datum_t *src, type_datum_t *tgt, class_datum_t *cls, const Xperm &p, int effect);
bool add_xperm_rule(const char *s, const char *t, const char *c, const Xperm &p, int effect);
bool add_type_rule(const char *s, const char *t, const char *c, const char *d, int effect);
bool add_filename_trans(const char *s, const char *t, const char *c, const char *d, const char *o);
bool add_genfscon(const char *fs_name, const char *path, const char *context);
@ -29,7 +29,6 @@ struct sepol_impl : public sepolicy {
bool set_type_state(const char *type_name, bool permissive);
void add_typeattribute(type_datum_t *type, type_datum_t *attr);
bool add_typeattribute(const char *type, const char *attr);
void strip_dontaudit();
sepol_impl(policydb *db) : db(db) {}
~sepol_impl();
@ -42,8 +41,4 @@ private:
#define impl reinterpret_cast<sepol_impl *>(this)
const char *as_str(const argument &arg);
const char *as_str(const char *arg);
void statement_help();
void test_parse_statements();

View File

@ -270,18 +270,18 @@ bool sepol_impl::add_rule(const char *s, const char *t, const char *c, const cha
#define ioctl_driver(x) (x>>8 & 0xFF)
#define ioctl_func(x) (x & 0xFF)
void sepol_impl::add_xperm_rule(type_datum_t *src, type_datum_t *tgt, class_datum_t *cls, uint16_t low, uint16_t high, bool reset, int effect) {
void sepol_impl::add_xperm_rule(type_datum_t *src, type_datum_t *tgt, class_datum_t *cls, const Xperm &p, int effect) {
if (src == nullptr) {
for_each_attr(db->p_types.table, [&](type_datum_t *type) {
add_xperm_rule(type, tgt, cls, low, high, reset, effect);
add_xperm_rule(type, tgt, cls, p, effect);
});
} else if (tgt == nullptr) {
for_each_attr(db->p_types.table, [&](type_datum_t *type) {
add_xperm_rule(src, type, cls, low, high, reset, effect);
add_xperm_rule(src, type, cls, p, effect);
});
} else if (cls == nullptr) {
hashtab_for_each(db->p_classes.table, [&](hashtab_ptr_t node) {
add_xperm_rule(src, tgt, auto_cast(node->datum), low, high, reset, effect);
add_xperm_rule(src, tgt, auto_cast(node->datum), p, effect);
});
} else {
avtab_key_t key;
@ -304,7 +304,7 @@ void sepol_impl::add_xperm_rule(type_datum_t *src, type_datum_t *tgt, class_datu
node = avtab_search_node_next(node, key.specified);
}
if (reset) {
if (p.reset) {
for (int i = 0; i <= 0xFF; ++i) {
if (node_list[i]) {
avtab_remove_node(&db->te_avtab, node_list[i]);
@ -332,22 +332,22 @@ void sepol_impl::add_xperm_rule(type_datum_t *src, type_datum_t *tgt, class_datu
return node;
};
if (!reset) {
if (ioctl_driver(low) != ioctl_driver(high)) {
if (!p.reset) {
if (ioctl_driver(p.low) != ioctl_driver(p.high)) {
if (driver_node == nullptr) {
driver_node = new_driver_node();
}
for (int i = ioctl_driver(low); i <= ioctl_driver(high); ++i) {
for (int i = ioctl_driver(p.low); i <= ioctl_driver(p.high); ++i) {
xperm_set(i, driver_node->datum.xperms->perms);
}
} else {
uint8_t driver = ioctl_driver(low);
uint8_t driver = ioctl_driver(p.low);
auto node = node_list[driver];
if (node == nullptr) {
node = new_func_node(driver);
node_list[driver] = node;
}
for (int i = ioctl_func(low); i <= ioctl_func(high); ++i) {
for (int i = ioctl_func(p.low); i <= ioctl_func(p.high); ++i) {
xperm_set(i, node->datum.xperms->perms);
}
}
@ -358,12 +358,12 @@ void sepol_impl::add_xperm_rule(type_datum_t *src, type_datum_t *tgt, class_datu
// Fill the driver perms
memset(driver_node->datum.xperms->perms, ~0, sizeof(avtab_extended_perms_t::perms));
if (ioctl_driver(low) != ioctl_driver(high)) {
for (int i = ioctl_driver(low); i <= ioctl_driver(high); ++i) {
if (ioctl_driver(p.low) != ioctl_driver(p.high)) {
for (int i = ioctl_driver(p.low); i <= ioctl_driver(p.high); ++i) {
xperm_clear(i, driver_node->datum.xperms->perms);
}
} else {
uint8_t driver = ioctl_driver(low);
uint8_t driver = ioctl_driver(p.low);
auto node = node_list[driver];
if (node == nullptr) {
node = new_func_node(driver);
@ -372,7 +372,7 @@ void sepol_impl::add_xperm_rule(type_datum_t *src, type_datum_t *tgt, class_datu
node_list[driver] = node;
}
xperm_clear(driver, driver_node->datum.xperms->perms);
for (int i = ioctl_func(low); i <= ioctl_func(high); ++i) {
for (int i = ioctl_func(p.low); i <= ioctl_func(p.high); ++i) {
xperm_clear(i, node->datum.xperms->perms);
}
}
@ -380,7 +380,7 @@ void sepol_impl::add_xperm_rule(type_datum_t *src, type_datum_t *tgt, class_datu
}
}
bool sepol_impl::add_xperm_rule(const char *s, const char *t, const char *c, uint16_t low, uint16_t high, bool reset, int effect) {
bool sepol_impl::add_xperm_rule(const char *s, const char *t, const char *c, const Xperm &p, int effect) {
type_datum_t *src = nullptr, *tgt = nullptr;
class_datum_t *cls = nullptr;
@ -408,7 +408,7 @@ bool sepol_impl::add_xperm_rule(const char *s, const char *t, const char *c, uin
}
}
add_xperm_rule(src, tgt, cls, low, high, reset, effect);
add_xperm_rule(src, tgt, cls, p, effect);
return true;
}
@ -649,10 +649,10 @@ bool sepol_impl::add_typeattribute(const char *type, const char *attr) {
return true;
}
void sepol_impl::strip_dontaudit() {
avtab_for_each(&db->te_avtab, [=, this](avtab_ptr_t node) {
void sepolicy::strip_dontaudit() {
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(&db->te_avtab, node);
avtab_remove_node(&impl->db->te_avtab, node);
});
}

View File

@ -1,7 +1,9 @@
use std::{iter::Peekable, pin::Pin, vec::IntoIter};
use base::{LoggedError, LoggedResult};
use crate::ffi::Xperm;
use crate::sepolicy;
use base::{LoggedError, LoggedResult};
use std::{iter::Peekable, pin::Pin, vec::IntoIter};
pub enum Token<'a> {
AL,
@ -52,7 +54,7 @@ fn parse_id<'a>(tokens: &mut Tokens<'a>) -> LoggedResult<&'a str> {
// term ::= LB names(n) RB { n };
fn parse_term<'a>(tokens: &mut Tokens<'a>) -> LoggedResult<Vec<&'a str>> {
match tokens.next() {
Some(Token::ID(name)) => return Ok(vec![name]),
Some(Token::ID(name)) => Ok(vec![name]),
Some(Token::LB) => {
let mut names = Vec::new();
loop {
@ -87,7 +89,7 @@ fn parse_terms<'a>(tokens: &mut Tokens<'a>) -> LoggedResult<Vec<&'a str>> {
// xperm ::= HX(low) { Xperm{low, high: 0, reset: false} };
// xperm ::= HX(low) HP HX(high) { Xperm{low, high, reset: false} };
fn parse_xperm<'a>(tokens: &mut Tokens<'a>) -> LoggedResult<Xperm> {
fn parse_xperm(tokens: &mut Tokens) -> LoggedResult<Xperm> {
let low = match tokens.next() {
Some(Token::HX(low)) => low,
_ => throw!(),
@ -116,7 +118,7 @@ fn parse_xperm<'a>(tokens: &mut Tokens<'a>) -> LoggedResult<Xperm> {
//
// xperm_list ::= xperm(p) { vec![p] }
// xperm_list ::= xperm_list(mut l) xperm(p) { l.push(p); l }
fn parse_xperms<'a>(tokens: &mut Tokens<'a>) -> LoggedResult<Vec<Xperm>> {
fn parse_xperms(tokens: &mut Tokens) -> LoggedResult<Vec<Xperm>> {
let mut xperms = Vec::new();
let reset = match tokens.peek() {
Some(Token::TL) => {
@ -186,7 +188,7 @@ fn parse_xperms<'a>(tokens: &mut Tokens<'a>) -> LoggedResult<Vec<Xperm>> {
// statement ::= TC ID(s) ID(t) ID(c) ID(d) { extra.as_mut().type_change(s, t, c, d); };
// statement ::= TM ID(s) ID(t) ID(c) ID(d) { extra.as_mut().type_member(s, t, c, d);};
// statement ::= GF ID(s) ID(t) ID(c) { extra.as_mut().genfscon(s, t, c); };
fn exec_statement<'a>(sepolicy: Pin<&mut sepolicy>, tokens: &mut Tokens<'a>) -> LoggedResult<()> {
fn exec_statement(sepolicy: Pin<&mut sepolicy>, tokens: &mut Tokens) -> LoggedResult<()> {
let action = match tokens.next() {
Some(token) => token,
_ => throw!(),
@ -236,7 +238,7 @@ fn exec_statement<'a>(sepolicy: Pin<&mut sepolicy>, tokens: &mut Tokens<'a>) ->
}
Token::TY => {
let t = parse_id(tokens)?;
let a = if matches!(tokens.peek(), None) {
let a = if tokens.peek().is_none() {
vec![]
} else {
parse_term(tokens)?
@ -254,7 +256,7 @@ fn exec_statement<'a>(sepolicy: Pin<&mut sepolicy>, tokens: &mut Tokens<'a>) ->
let d = parse_id(tokens)?;
match action {
Token::TT => {
let o = if matches!(tokens.peek(), None) {
let o = if tokens.peek().is_none() {
vec![]
} else {
vec![parse_id(tokens)?]
@ -274,16 +276,16 @@ fn exec_statement<'a>(sepolicy: Pin<&mut sepolicy>, tokens: &mut Tokens<'a>) ->
}
_ => throw!(),
}
if matches!(tokens.peek(), None) {
if tokens.peek().is_none() {
Ok(())
} else {
throw!()
}
}
fn tokenize_statement<'a>(statement: &'a str) -> Vec<Token<'a>> {
fn tokenize_statement(statement: &str) -> Vec<Token> {
let mut tokens = Vec::new();
for s in statement.trim().split_whitespace() {
for s in statement.split_whitespace() {
let mut res = Some(s);
while let Some(s) = res {
match s {
@ -306,27 +308,27 @@ fn tokenize_statement<'a>(statement: &'a str) -> Vec<Token<'a>> {
"ioctl" => tokens.push(Token::IO),
"" => {}
_ => {
if let Some(s) = s.strip_prefix("{") {
if let Some(s) = s.strip_prefix('{') {
tokens.push(Token::LB);
res = Some(s);
continue;
} else if let Some(s) = s.strip_prefix("}") {
} else if let Some(s) = s.strip_prefix('}') {
tokens.push(Token::RB);
res = Some(s);
continue;
} else if let Some(s) = s.strip_prefix(",") {
} else if let Some(s) = s.strip_prefix(',') {
tokens.push(Token::CM);
res = Some(s);
continue;
} else if let Some(s) = s.strip_prefix("*") {
} else if let Some(s) = s.strip_prefix('*') {
tokens.push(Token::ST);
res = Some(s);
continue;
} else if let Some(s) = s.strip_prefix("~") {
} else if let Some(s) = s.strip_prefix('~') {
res = Some(s);
tokens.push(Token::TL);
continue;
} else if let Some(s) = s.strip_prefix("-") {
} else if let Some(s) = s.strip_prefix('-') {
res = Some(s);
tokens.push(Token::HP);
continue;
@ -343,7 +345,7 @@ fn tokenize_statement<'a>(statement: &'a str) -> Vec<Token<'a>> {
tokens
}
pub fn parse_statement<'a>(sepolicy: Pin<&mut sepolicy>, statement: &'a str) -> LoggedResult<()> {
pub fn parse_statement(sepolicy: Pin<&mut sepolicy>, statement: &str) -> LoggedResult<()> {
let mut tokens = tokenize_statement(statement).into_iter().peekable();
exec_statement(sepolicy, &mut tokens)
}