mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-04-29 22:14:27 +02:00
Directly deal with Rust &str in sepolicy.cpp
This commit is contained in:
parent
5e35703091
commit
8a80eea597
@ -9,12 +9,10 @@ using Xperms = rust::Vec<Xperm>;
|
||||
#if 0
|
||||
template<typename 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 ? "*" : arg;
|
||||
} else if constexpr (std::is_same_v<Arg, Xperm>) {
|
||||
return std::string(rust::xperm_to_string(arg));
|
||||
} else {
|
||||
return std::to_string(arg);
|
||||
if constexpr (std::is_same_v<Arg, Xperm>) {
|
||||
return (std::string) SePolicy::xperm_to_string(arg);
|
||||
} else if constexpr (std::is_same_v<Arg, rust::Str>) {
|
||||
return arg.empty() ? "*" : (std::string) arg;
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,21 +34,17 @@ static inline void expand(F &&f, T &&...args) {
|
||||
}
|
||||
|
||||
template<typename ...T>
|
||||
static inline void expand(const Str &s, T &&...args) {
|
||||
if (s.empty()) {
|
||||
expand(std::forward<T>(args)..., (char *) nullptr);
|
||||
} else {
|
||||
expand(std::forward<T>(args)..., std::string(s).data());
|
||||
}
|
||||
static inline void expand(Str s, T &&...args) {
|
||||
expand(std::forward<T>(args)..., s);
|
||||
}
|
||||
|
||||
template<typename ...T>
|
||||
static inline void expand(const StrVec &vec, T &&...args) {
|
||||
if (vec.empty()) {
|
||||
expand(std::forward<T>(args)..., (char *) nullptr);
|
||||
expand(std::forward<T>(args)..., rust::Str{});
|
||||
} else {
|
||||
for (auto &s : vec) {
|
||||
expand(s, std::forward<T>(args)...);
|
||||
for (auto s : vec) {
|
||||
expand(std::forward<T>(args)..., s);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -127,7 +121,7 @@ void SePolicy::attribute(Str name) 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) {
|
||||
if (o) {
|
||||
if (!o.empty()) {
|
||||
print_rule("type_transition", s, t, c, d, o);
|
||||
impl->add_filename_trans(s, t, c, d, o);
|
||||
} else {
|
||||
|
@ -4,9 +4,12 @@
|
||||
|
||||
#include <map>
|
||||
#include <string_view>
|
||||
#include <cxx.h>
|
||||
|
||||
#include <sepol/policydb/policydb.h>
|
||||
|
||||
using Str = rust::Str;
|
||||
|
||||
struct Xperm;
|
||||
|
||||
class sepol_impl {
|
||||
@ -17,17 +20,17 @@ class sepol_impl {
|
||||
void print_avtab(FILE *fp, avtab_ptr_t node);
|
||||
void print_filename_trans(FILE *fp, hashtab_ptr_t node);
|
||||
|
||||
bool add_rule(const char *s, const char *t, const char *c, const char *p, int effect, bool invert);
|
||||
bool add_rule(Str s, Str t, Str c, Str 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, 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);
|
||||
bool add_type(const char *type_name, uint32_t flavor);
|
||||
bool set_type_state(const char *type_name, bool permissive);
|
||||
bool add_xperm_rule(Str s, Str t, Str c, const Xperm &p, int effect);
|
||||
bool add_type_rule(Str s, Str t, Str c, Str d, int effect);
|
||||
bool add_filename_trans(Str s, Str t, Str c, Str d, Str o);
|
||||
bool add_genfscon(Str fs_name, Str path, Str context);
|
||||
bool add_type(Str type_name, uint32_t flavor);
|
||||
bool set_type_state(Str type_name, bool permissive);
|
||||
void add_typeattribute(type_datum_t *type, type_datum_t *attr);
|
||||
bool add_typeattribute(const char *type, const char *attr);
|
||||
bool add_typeattribute(Str type, Str attr);
|
||||
|
||||
policydb *db;
|
||||
|
||||
|
@ -25,8 +25,7 @@ int context_to_string(
|
||||
__END_DECLS
|
||||
|
||||
template <typename T>
|
||||
struct auto_cast_wrapper
|
||||
{
|
||||
struct auto_cast_wrapper {
|
||||
auto_cast_wrapper(T *ptr) : ptr(ptr) {}
|
||||
template <typename U>
|
||||
operator U*() const { return static_cast<U*>(ptr); }
|
||||
@ -39,8 +38,31 @@ static auto_cast_wrapper<T> auto_cast(T *p) {
|
||||
return auto_cast_wrapper<T>(p);
|
||||
}
|
||||
|
||||
static auto hashtab_find(hashtab_t h, const_hashtab_key_t key) {
|
||||
return auto_cast(hashtab_search(h, key));
|
||||
template <size_t T>
|
||||
static size_t copy_str(std::array<char, T> &dest, rust::Str src) {
|
||||
if (T == 0) return 0;
|
||||
size_t len = std::min(T - 1, src.size());
|
||||
memcpy(dest.data(), src.data(), len);
|
||||
dest[len] = '\0';
|
||||
return len;
|
||||
}
|
||||
|
||||
static char *dup_str(rust::Str src) {
|
||||
size_t len = src.size();
|
||||
char *s = static_cast<char *>(malloc(len + 1));
|
||||
memcpy(s, src.data(), len);
|
||||
s[len] = '\0';
|
||||
return s;
|
||||
}
|
||||
|
||||
static bool str_eq(string_view a, rust::Str b) {
|
||||
return a.size() == b.size() && memcmp(a.data(), b.data(), a.size()) == 0;
|
||||
}
|
||||
|
||||
static auto hashtab_find(hashtab_t h, Str key) {
|
||||
array<char, 256> buf{};
|
||||
copy_str(buf, key);
|
||||
return auto_cast(hashtab_search(h, buf.data()));
|
||||
}
|
||||
|
||||
template <class Node, class Func>
|
||||
@ -219,38 +241,38 @@ void sepol_impl::add_rule(type_datum_t *src, type_datum_t *tgt, class_datum_t *c
|
||||
}
|
||||
}
|
||||
|
||||
bool sepol_impl::add_rule(const char *s, const char *t, const char *c, const char *p, int effect, bool invert) {
|
||||
bool sepol_impl::add_rule(Str s, Str t, Str c, Str p, int effect, bool invert) {
|
||||
type_datum_t *src = nullptr, *tgt = nullptr;
|
||||
class_datum_t *cls = nullptr;
|
||||
perm_datum_t *perm = nullptr;
|
||||
|
||||
if (s) {
|
||||
if (!s.empty()) {
|
||||
src = hashtab_find(db->p_types.table, s);
|
||||
if (src == nullptr) {
|
||||
LOGW("source type %s does not exist\n", s);
|
||||
LOGW("source type %.*s does not exist\n", (int) s.size(), s.data());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (t) {
|
||||
if (!t.empty()) {
|
||||
tgt = hashtab_find(db->p_types.table, t);
|
||||
if (tgt == nullptr) {
|
||||
LOGW("target type %s does not exist\n", t);
|
||||
LOGW("target type %.*s does not exist\n", (int) t.size(), t.data());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (c) {
|
||||
if (!c.empty()) {
|
||||
cls = hashtab_find(db->p_classes.table, c);
|
||||
if (cls == nullptr) {
|
||||
LOGW("class %s does not exist\n", c);
|
||||
LOGW("class %.*s does not exist\n", (int) c.size(), c.data());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (p) {
|
||||
if (c == nullptr) {
|
||||
LOGW("No class is specified, cannot add perm [%s] \n", p);
|
||||
if (!p.empty()) {
|
||||
if (c.empty()) {
|
||||
LOGW("No class is specified, cannot add perm [%.*s] \n", (int) p.size(), p.data());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -259,7 +281,8 @@ bool sepol_impl::add_rule(const char *s, const char *t, const char *c, const cha
|
||||
perm = hashtab_find(cls->comdatum->permissions.table, p);
|
||||
}
|
||||
if (perm == nullptr) {
|
||||
LOGW("perm %s does not exist in class %s\n", p, c);
|
||||
LOGW("perm %.*s does not exist in class %.*s\n",
|
||||
(int) p.size(), p.data(), (int) c.size(), c.data());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -384,30 +407,30 @@ 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, const Xperm &p, int effect) {
|
||||
bool sepol_impl::add_xperm_rule(Str s, Str t, Str c, const Xperm &p, int effect) {
|
||||
type_datum_t *src = nullptr, *tgt = nullptr;
|
||||
class_datum_t *cls = nullptr;
|
||||
|
||||
if (s) {
|
||||
if (!s.empty()) {
|
||||
src = hashtab_find(db->p_types.table, s);
|
||||
if (src == nullptr) {
|
||||
LOGW("source type %s does not exist\n", s);
|
||||
LOGW("source type %.*s does not exist\n", (int) s.size(), s.data());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (t) {
|
||||
if (!t.empty()) {
|
||||
tgt = hashtab_find(db->p_types.table, t);
|
||||
if (tgt == nullptr) {
|
||||
LOGW("target type %s does not exist\n", t);
|
||||
LOGW("target type %.*s does not exist\n", (int) t.size(), t.data());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (c) {
|
||||
if (!c.empty()) {
|
||||
cls = hashtab_find(db->p_classes.table, c);
|
||||
if (cls == nullptr) {
|
||||
LOGW("class %s does not exist\n", c);
|
||||
LOGW("class %.*s does not exist\n", (int) c.size(), c.data());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -416,28 +439,28 @@ bool sepol_impl::add_xperm_rule(const char *s, const char *t, const char *c, con
|
||||
return true;
|
||||
}
|
||||
|
||||
bool sepol_impl::add_type_rule(const char *s, const char *t, const char *c, const char *d, int effect) {
|
||||
bool sepol_impl::add_type_rule(Str s, Str t, Str c, Str d, int effect) {
|
||||
type_datum_t *src, *tgt, *def;
|
||||
class_datum_t *cls;
|
||||
|
||||
src = hashtab_find(db->p_types.table, s);
|
||||
if (src == nullptr) {
|
||||
LOGW("source type %s does not exist\n", s);
|
||||
LOGW("source type %.*s does not exist\n", (int) s.size(), s.data());
|
||||
return false;
|
||||
}
|
||||
tgt = hashtab_find(db->p_types.table, t);
|
||||
if (tgt == nullptr) {
|
||||
LOGW("target type %s does not exist\n", t);
|
||||
LOGW("target type %.*s does not exist\n", (int) t.size(), t.data());
|
||||
return false;
|
||||
}
|
||||
cls = hashtab_find(db->p_classes.table, c);
|
||||
if (cls == nullptr) {
|
||||
LOGW("class %s does not exist\n", c);
|
||||
LOGW("class %.*s does not exist\n", (int) c.size(), c.data());
|
||||
return false;
|
||||
}
|
||||
def = hashtab_find(db->p_types.table, d);
|
||||
if (def == nullptr) {
|
||||
LOGW("default type %s does not exist\n", d);
|
||||
LOGW("default type %.*s does not exist\n", (int) d.size(), d.data());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -453,35 +476,37 @@ bool sepol_impl::add_type_rule(const char *s, const char *t, const char *c, cons
|
||||
return true;
|
||||
}
|
||||
|
||||
bool sepol_impl::add_filename_trans(const char *s, const char *t, const char *c, const char *d, const char *o) {
|
||||
bool sepol_impl::add_filename_trans(Str s, Str t, Str c, Str d, Str o) {
|
||||
type_datum_t *src, *tgt, *def;
|
||||
class_datum_t *cls;
|
||||
|
||||
src = hashtab_find(db->p_types.table, s);
|
||||
if (src == nullptr) {
|
||||
LOGW("source type %s does not exist\n", s);
|
||||
LOGW("source type %.*s does not exist\n", (int) s.size(), s.data());
|
||||
return false;
|
||||
}
|
||||
tgt = hashtab_find(db->p_types.table, t);
|
||||
if (tgt == nullptr) {
|
||||
LOGW("target type %s does not exist\n", t);
|
||||
LOGW("target type %.*s does not exist\n", (int) t.size(), t.data());
|
||||
return false;
|
||||
}
|
||||
cls = hashtab_find(db->p_classes.table, c);
|
||||
if (cls == nullptr) {
|
||||
LOGW("class %s does not exist\n", c);
|
||||
LOGW("class %.*s does not exist\n", (int) c.size(), c.data());
|
||||
return false;
|
||||
}
|
||||
def = hashtab_find(db->p_types.table, d);
|
||||
if (def == nullptr) {
|
||||
LOGW("default type %s does not exist\n", d);
|
||||
LOGW("default type %.*s does not exist\n", (int) d.size(), d.data());
|
||||
return false;
|
||||
}
|
||||
|
||||
array<char, 256> key_name{};
|
||||
copy_str(key_name, o);
|
||||
filename_trans_key_t key;
|
||||
key.ttype = tgt->s.value;
|
||||
key.tclass = cls->s.value;
|
||||
key.name = (char *) o;
|
||||
key.name = key_name.data();
|
||||
|
||||
filename_trans_datum_t *trans = hashtab_find(db->filename_trans, (hashtab_key_t) &key);
|
||||
filename_trans_datum_t *last = nullptr;
|
||||
@ -514,32 +539,32 @@ bool sepol_impl::add_filename_trans(const char *s, const char *t, const char *c,
|
||||
return ebitmap_set_bit(&trans->stypes, src->s.value - 1, 1) == 0;
|
||||
}
|
||||
|
||||
bool sepol_impl::add_genfscon(const char *fs_name, const char *path, const char *context) {
|
||||
bool sepol_impl::add_genfscon(Str fs_name, Str path, Str context) {
|
||||
// First try to create context
|
||||
context_struct_t *ctx;
|
||||
if (context_from_string(nullptr, db, &ctx, context, strlen(context))) {
|
||||
LOGW("Failed to create context from string [%s]\n", context);
|
||||
if (context_from_string(nullptr, db, &ctx, context.data(), context.size())) {
|
||||
LOGW("Failed to create context from string [%.*s]\n", (int) context.size(), context.data());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Find genfs node
|
||||
genfs_t *fs = list_find(db->genfs, [&](genfs_t *n) {
|
||||
return strcmp(n->fstype, fs_name) == 0;
|
||||
return str_eq(n->fstype, fs_name);
|
||||
});
|
||||
if (fs == nullptr) {
|
||||
fs = auto_cast(calloc(sizeof(*fs), 1));
|
||||
fs->fstype = strdup(fs_name);
|
||||
fs->fstype = dup_str(fs_name);
|
||||
fs->next = db->genfs;
|
||||
db->genfs = fs;
|
||||
}
|
||||
|
||||
// Find context node
|
||||
ocontext_t *o_ctx = list_find(fs->head, [&](ocontext_t *n) {
|
||||
return strcmp(n->u.name, path) == 0;
|
||||
return str_eq(n->u.name, path);
|
||||
});
|
||||
if (o_ctx == nullptr) {
|
||||
o_ctx = auto_cast(calloc(sizeof(*o_ctx), 1));
|
||||
o_ctx->u.name = strdup(path);
|
||||
o_ctx->u.name = dup_str(path);
|
||||
o_ctx->next = fs->head;
|
||||
fs->head = o_ctx;
|
||||
}
|
||||
@ -550,21 +575,24 @@ bool sepol_impl::add_genfscon(const char *fs_name, const char *path, const char
|
||||
return true;
|
||||
}
|
||||
|
||||
bool sepol_impl::add_type(const char *type_name, uint32_t flavor) {
|
||||
bool sepol_impl::add_type(Str type_name, uint32_t flavor) {
|
||||
type_datum_t *type = hashtab_find(db->p_types.table, type_name);
|
||||
if (type) {
|
||||
LOGW("Type %s already exists\n", type_name);
|
||||
LOGW("Type %.*s already exists\n", (int) type_name.size(), type_name.data());
|
||||
return true;
|
||||
}
|
||||
|
||||
type = auto_cast(malloc(sizeof(type_datum_t)));
|
||||
type = auto_cast(malloc(sizeof(*type)));
|
||||
type_datum_init(type);
|
||||
type->primary = 1;
|
||||
type->flavor = flavor;
|
||||
|
||||
uint32_t value = 0;
|
||||
if (symtab_insert(db, SYM_TYPES, strdup(type_name), type, SCOPE_DECL, 1, &value))
|
||||
auto ty_name = dup_str(type_name);
|
||||
if (symtab_insert(db, SYM_TYPES, ty_name, type, SCOPE_DECL, 1, &value)) {
|
||||
free(ty_name);
|
||||
return false;
|
||||
}
|
||||
type->s.value = value;
|
||||
ebitmap_set_bit(&db->global->branch_list->declared.p_types_scope, value - 1, 1);
|
||||
|
||||
@ -591,9 +619,9 @@ bool sepol_impl::add_type(const char *type_name, uint32_t flavor) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool sepol_impl::set_type_state(const char *type_name, bool permissive) {
|
||||
bool sepol_impl::set_type_state(Str type_name, bool permissive) {
|
||||
type_datum_t *type;
|
||||
if (type_name == nullptr) {
|
||||
if (type_name.empty()) {
|
||||
hashtab_for_each(db->p_types.table, [&](hashtab_ptr_t node) {
|
||||
type = auto_cast(node->datum);
|
||||
if (ebitmap_set_bit(&db->permissive_map, type->s.value, permissive))
|
||||
@ -602,7 +630,7 @@ bool sepol_impl::set_type_state(const char *type_name, bool permissive) {
|
||||
} else {
|
||||
type = hashtab_find(db->p_types.table, type_name);
|
||||
if (type == nullptr) {
|
||||
LOGW("type %s does not exist\n", type_name);
|
||||
LOGW("type %.*s does not exist\n", (int) type_name.size(), type_name.data());
|
||||
return false;
|
||||
}
|
||||
if (ebitmap_set_bit(&db->permissive_map, type->s.value, permissive)) {
|
||||
@ -630,22 +658,22 @@ void sepol_impl::add_typeattribute(type_datum_t *type, type_datum_t *attr) {
|
||||
});
|
||||
}
|
||||
|
||||
bool sepol_impl::add_typeattribute(const char *type, const char *attr) {
|
||||
bool sepol_impl::add_typeattribute(Str type, Str attr) {
|
||||
type_datum_t *type_d = hashtab_find(db->p_types.table, type);
|
||||
if (type_d == nullptr) {
|
||||
LOGW("type %s does not exist\n", type);
|
||||
LOGW("type %.*s does not exist\n", (int) type.size(), type.data());
|
||||
return false;
|
||||
} else if (type_d->flavor == TYPE_ATTRIB) {
|
||||
LOGW("type %s is an attribute\n", attr);
|
||||
LOGW("type %.*s is an attribute\n", (int) attr.size(), attr.data());
|
||||
return false;
|
||||
}
|
||||
|
||||
type_datum *attr_d = hashtab_find(db->p_types.table, attr);
|
||||
if (attr_d == nullptr) {
|
||||
LOGW("attribute %s does not exist\n", type);
|
||||
LOGW("attribute %.*s does not exist\n", (int) type.size(), type.data());
|
||||
return false;
|
||||
} else if (attr_d->flavor != TYPE_ATTRIB) {
|
||||
LOGW("type %s is not an attribute \n", attr);
|
||||
LOGW("type %.*s is not an attribute \n", (int) attr.size(), attr.data());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -654,32 +682,32 @@ bool sepol_impl::add_typeattribute(const char *type, const char *attr) {
|
||||
}
|
||||
|
||||
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)
|
||||
avtab_remove_node(&impl->db->te_avtab, node);
|
||||
});
|
||||
}
|
||||
|
||||
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, [this](hashtab_ptr_t node) {
|
||||
type_datum_t *type = auto_cast(node->datum);
|
||||
if (type->flavor == TYPE_ATTRIB) {
|
||||
impl->print_type(stdout, type);
|
||||
}
|
||||
});
|
||||
hashtab_for_each(impl->db->p_types.table, [&](hashtab_ptr_t node) {
|
||||
hashtab_for_each(impl->db->p_types.table, [this](hashtab_ptr_t node) {
|
||||
type_datum_t *type = auto_cast(node->datum);
|
||||
if (type->flavor == TYPE_TYPE) {
|
||||
impl->print_type(stdout, type);
|
||||
}
|
||||
});
|
||||
avtab_for_each(&impl->db->te_avtab, [&](avtab_ptr_t node) {
|
||||
avtab_for_each(&impl->db->te_avtab, [this](avtab_ptr_t node) {
|
||||
impl->print_avtab(stdout, node);
|
||||
});
|
||||
hashtab_for_each(impl->db->filename_trans, [&](hashtab_ptr_t node) {
|
||||
hashtab_for_each(impl->db->filename_trans, [this](hashtab_ptr_t node) {
|
||||
impl->print_filename_trans(stdout, node);
|
||||
});
|
||||
list_for_each(impl->db->genfs, [&](genfs_t *genfs) {
|
||||
list_for_each(impl->db->genfs, [this](genfs_t *genfs) {
|
||||
list_for_each(genfs->head, [&](ocontext *context) {
|
||||
char *ctx = nullptr;
|
||||
size_t len = 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user