Reorganize magiskpolicy source code

This commit is contained in:
topjohnwu
2022-03-29 22:26:38 -07:00
parent efb3239cbd
commit 704f91545e
11 changed files with 171 additions and 168 deletions

View File

@@ -0,0 +1,105 @@
#include <utils.hpp>
#include "policy.hpp"
#if 0
// Print out all rules going through public API for debugging
template <typename ...Args>
static void dprint(const char *action, Args ...args) {
std::string s(action);
for (int i = 0; i < sizeof...(args); ++i) s += " %s";
s += "\n";
LOGD(s.data(), (args ? args : "*")...);
}
#else
#define dprint(...)
#endif
bool sepolicy::allow(const char *s, const char *t, const char *c, const char *p) {
dprint(__FUNCTION__, s, t, c, p);
return impl->add_rule(s, t, c, p, AVTAB_ALLOWED, false);
}
bool sepolicy::deny(const char *s, const char *t, const char *c, const char *p) {
dprint(__FUNCTION__, s, t, c, p);
return impl->add_rule(s, t, c, p, AVTAB_ALLOWED, true);
}
bool sepolicy::auditallow(const char *s, const char *t, const char *c, const char *p) {
dprint(__FUNCTION__, s, t, c, p);
return impl->add_rule(s, t, c, p, AVTAB_AUDITALLOW, false);
}
bool sepolicy::dontaudit(const char *s, const char *t, const char *c, const char *p) {
dprint(__FUNCTION__, s, t, c, p);
return impl->add_rule(s, t, c, p, AVTAB_AUDITDENY, true);
}
bool sepolicy::allowxperm(const char *s, const char *t, const char *c, const char *range) {
dprint(__FUNCTION__, s, t, c, "ioctl", range);
return impl->add_xperm_rule(s, t, c, range, AVTAB_XPERMS_ALLOWED, false);
}
bool sepolicy::auditallowxperm(const char *s, const char *t, const char *c, const char *range) {
dprint(__FUNCTION__, s, t, c, "ioctl", range);
return impl->add_xperm_rule(s, t, c, range, AVTAB_XPERMS_AUDITALLOW, false);
}
bool sepolicy::dontauditxperm(const char *s, const char *t, const char *c, const char *range) {
dprint(__FUNCTION__, s, t, c, "ioctl", range);
return impl->add_xperm_rule(s, t, c, range, AVTAB_XPERMS_DONTAUDIT, false);
}
bool sepolicy::type_change(const char *s, const char *t, const char *c, const char *d) {
dprint(__FUNCTION__, s, t, c, d);
return impl->add_type_rule(s, t, c, d, AVTAB_CHANGE);
}
bool sepolicy::type_member(const char *s, const char *t, const char *c, const char *d) {
dprint(__FUNCTION__, s, t, c, d);
return impl->add_type_rule(s, t, c, d, AVTAB_MEMBER);
}
bool sepolicy::type_transition(const char *s, const char *t, const char *c, const char *d, const char *o) {
if (o) {
dprint(__FUNCTION__, s, t, c, d, o);
return impl->add_filename_trans(s, t, c, d, o);
} else {
dprint(__FUNCTION__, s, t, c, d);
return impl->add_type_rule(s, t, c, d, AVTAB_TRANSITION);
}
}
bool sepolicy::permissive(const char *s) {
dprint(__FUNCTION__, s);
return impl->set_type_state(s, true);
}
bool sepolicy::enforce(const char *s) {
dprint(__FUNCTION__, s);
return impl->set_type_state(s, false);
}
bool sepolicy::type(const char *name, const char *attr) {
dprint(__FUNCTION__, name, attr);
return impl->add_type(name, TYPE_TYPE) && impl->add_typeattribute(name, attr);
}
bool sepolicy::attribute(const char *name) {
dprint(__FUNCTION__, name);
return impl->add_type(name, TYPE_ATTRIB);
}
bool sepolicy::typeattribute(const char *type, const char *attr) {
dprint(__FUNCTION__, type, attr);
return impl->add_typeattribute(type, attr);
}
bool sepolicy::genfscon(const char *fs_name, const char *path, const char *ctx) {
dprint(__FUNCTION__, fs_name, path, ctx);
return impl->add_genfscon(fs_name, path, ctx);
}
bool sepolicy::exists(const char *type) {
return hashtab_search(impl->db->p_types.table, type) != nullptr;
}

View File

@@ -0,0 +1,60 @@
#pragma once
#include <stdlib.h>
#include <selinux.hpp>
#include <string>
#define ALL nullptr
struct sepolicy {
using c_str = const char *;
// 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 parse_statement(c_str stmt);
void load_rules(const std::string &rules);
void load_rule_file(c_str file);
// Operation on types
bool type(c_str name, c_str attr);
bool attribute(c_str name);
bool permissive(c_str type);
bool enforce(c_str type);
bool typeattribute(c_str type, c_str attr);
bool exists(c_str type);
// Access vector rules
bool allow(c_str src, c_str tgt, c_str cls, c_str perm);
bool deny(c_str src, c_str tgt, c_str cls, c_str perm);
bool auditallow(c_str src, c_str tgt, c_str cls, c_str perm);
bool dontaudit(c_str src, c_str tgt, c_str cls, c_str perm);
// Extended permissions access vector rules
bool allowxperm(c_str src, c_str tgt, c_str cls, c_str range);
bool auditallowxperm(c_str src, c_str tgt, c_str cls, c_str range);
bool dontauditxperm(c_str src, c_str tgt, c_str cls, c_str range);
// Type rules
bool type_transition(c_str src, c_str tgt, c_str cls, c_str def, c_str obj = nullptr);
bool type_change(c_str src, c_str tgt, c_str cls, c_str def);
bool type_member(c_str src, c_str tgt, c_str cls, c_str def);
// File system labeling
bool genfscon(c_str fs_name, c_str path, c_str ctx);
// Magisk
void magisk_rules();
// Deprecate
bool create(c_str name) { return type(name, "domain"); }
protected:
// Prevent anyone from accidentally creating an instance
sepolicy() = default;
};

View File

@@ -1,8 +1,7 @@
#include <utils.hpp>
#include <vector>
#include <magiskpolicy.hpp>
#include "sepolicy.hpp"
#include "policy.hpp"
using namespace std;

View File

@@ -1,11 +1,11 @@
#pragma once
#include <sepol/policydb/policydb.h>
#include <magiskpolicy.hpp>
// libse internal APIs, do not use directly
#include <sepol/policydb/policydb.h>
#include <sepolicy.hpp>
// Internal APIs, do not use directly
struct sepol_impl : public sepolicy {
void check_avtab_node(avtab_ptr_t node);
avtab_ptr_t get_avtab_node(avtab_key_t *key, avtab_extended_perms_t *xperms);
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);
@@ -20,8 +20,13 @@ struct sepol_impl : public sepolicy {
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();
policydb *db;
};
#define impl static_cast<sepol_impl *>(this)
#define impl reinterpret_cast<sepol_impl *>(this)
void statement_help();

View File

@@ -7,9 +7,8 @@
#include <utils.hpp>
#include <stream.hpp>
#include <magiskpolicy.hpp>
#include "sepolicy.hpp"
#include "policy.hpp"
#define SHALEN 64
static bool cmp_sha256(const char *a, const char *b) {
@@ -95,8 +94,7 @@ sepolicy *sepolicy::from_data(char *data, size_t len) {
return nullptr;
}
auto sepol = new sepolicy();
sepol->db = db;
auto sepol = new sepol_impl(db);
return sepol;
}
@@ -116,8 +114,7 @@ sepolicy *sepolicy::from_file(const char *file) {
return nullptr;
}
auto sepol = new sepolicy();
sepol->db = db;
auto sepol = new sepol_impl(db);
return sepol;
}
@@ -216,8 +213,7 @@ sepolicy *sepolicy::compile_split() {
if (cil_build_policydb(db, &pdb))
return nullptr;
auto sepol = new sepolicy();
sepol->db = &pdb->p;
auto sepol = new sepol_impl(&pdb->p);
return sepol;
}
@@ -232,7 +228,7 @@ sepolicy *sepolicy::from_split() {
return sepolicy::compile_split();
}
sepolicy::~sepolicy() {
sepol_impl::~sepol_impl() {
policydb_destroy(db);
free(db);
}
@@ -241,8 +237,8 @@ bool sepolicy::to_file(const char *file) {
uint8_t *data;
size_t len;
/* 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 */
// 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
auto fp = make_stream_fp<byte_stream>(data, len);
run_finally fin([=]{ free(data); });
@@ -251,7 +247,7 @@ bool sepolicy::to_file(const char *file) {
policy_file_init(&pf);
pf.type = PF_USE_STDIO;
pf.fp = fp.get();
if (policydb_write(db, &pf)) {
if (policydb_write(impl->db, &pf)) {
LOGE("Fail to create policy image\n");
return false;
}

View File

@@ -1,7 +1,6 @@
#include <utils.hpp>
#include <magiskpolicy.hpp>
#include "sepolicy.hpp"
#include "policy.hpp"
using namespace std;
@@ -27,7 +26,7 @@ void sepolicy::magisk_rules() {
// Make our root domain unconstrained
allow(SEPOL_PROC_DOMAIN, ALL, ALL, ALL);
// Allow us to do any ioctl
if (db->policyvers >= POLICYDB_VERSION_XPERMS_IOCTL) {
if (impl->db->policyvers >= POLICYDB_VERSION_XPERMS_IOCTL) {
allowxperm(SEPOL_PROC_DOMAIN, ALL, "blk_file", ALL);
allowxperm(SEPOL_PROC_DOMAIN, ALL, "fifo_file", ALL);
allowxperm(SEPOL_PROC_DOMAIN, ALL, "chr_file", ALL);

View File

@@ -1,22 +1,6 @@
#include <sepol/policydb/policydb.h>
#include <magiskpolicy.hpp>
#include <utils.hpp>
#include "sepolicy.hpp"
#if 0
// Print out all rules going through public API for debugging
template <typename ...Args>
static void dprint(const char *action, Args ...args) {
std::string s(action);
for (int i = 0; i < sizeof...(args); ++i) s += " %s";
s += "\n";
LOGD(s.data(), (args ? args : "*")...);
}
#else
#define dprint(...)
#endif
#include "policy.hpp"
// Invert is adding rules for auditdeny; in other cases, invert is removing rules
#define strip_av(effect, invert) ((effect == AVTAB_AUDITDENY) == !invert)
@@ -106,16 +90,15 @@ static int avtab_remove_node(avtab_t *h, avtab_ptr_t node) {
return 0;
}
void sepol_impl::check_avtab_node(avtab_ptr_t node) {
bool redundant;
if (node->key.specified == AVTAB_AUDITDENY)
redundant = node->datum.data == ~0U;
else if (node->key.specified & AVTAB_XPERMS)
redundant = node->datum.xperms == nullptr;
else
redundant = node->datum.data == 0U;
if (redundant)
avtab_remove_node(&db->te_avtab, node);
static bool is_redundant(avtab_ptr_t node) {
switch (node->key.specified) {
case AVTAB_AUDITDENY:
return node->datum.data == ~0U;
case AVTAB_XPERMS:
return node->datum.xperms == nullptr;
default:
return node->datum.data == 0U;
}
}
avtab_ptr_t sepol_impl::get_avtab_node(avtab_key_t *key, avtab_extended_perms_t *xperms) {
@@ -199,7 +182,9 @@ void sepol_impl::add_rule(type_datum_t *src, type_datum_t *tgt, class_datum_t *c
else
node->datum.data = ~0U;
}
check_avtab_node(node);
if (is_redundant(node))
avtab_remove_node(&db->te_avtab, node);
}
}
@@ -622,92 +607,3 @@ void sepol_impl::strip_dontaudit() {
avtab_remove_node(&db->te_avtab, node);
});
}
bool sepolicy::allow(const char *s, const char *t, const char *c, const char *p) {
dprint(__FUNCTION__, s, t, c, p);
return impl->add_rule(s, t, c, p, AVTAB_ALLOWED, false);
}
bool sepolicy::deny(const char *s, const char *t, const char *c, const char *p) {
dprint(__FUNCTION__, s, t, c, p);
return impl->add_rule(s, t, c, p, AVTAB_ALLOWED, true);
}
bool sepolicy::auditallow(const char *s, const char *t, const char *c, const char *p) {
dprint(__FUNCTION__, s, t, c, p);
return impl->add_rule(s, t, c, p, AVTAB_AUDITALLOW, false);
}
bool sepolicy::dontaudit(const char *s, const char *t, const char *c, const char *p) {
dprint(__FUNCTION__, s, t, c, p);
return impl->add_rule(s, t, c, p, AVTAB_AUDITDENY, true);
}
bool sepolicy::allowxperm(const char *s, const char *t, const char *c, const char *range) {
dprint(__FUNCTION__, s, t, c, "ioctl", range);
return impl->add_xperm_rule(s, t, c, range, AVTAB_XPERMS_ALLOWED, false);
}
bool sepolicy::auditallowxperm(const char *s, const char *t, const char *c, const char *range) {
dprint(__FUNCTION__, s, t, c, "ioctl", range);
return impl->add_xperm_rule(s, t, c, range, AVTAB_XPERMS_AUDITALLOW, false);
}
bool sepolicy::dontauditxperm(const char *s, const char *t, const char *c, const char *range) {
dprint(__FUNCTION__, s, t, c, "ioctl", range);
return impl->add_xperm_rule(s, t, c, range, AVTAB_XPERMS_DONTAUDIT, false);
}
bool sepolicy::type_change(const char *s, const char *t, const char *c, const char *d) {
dprint(__FUNCTION__, s, t, c, d);
return impl->add_type_rule(s, t, c, d, AVTAB_CHANGE);
}
bool sepolicy::type_member(const char *s, const char *t, const char *c, const char *d) {
dprint(__FUNCTION__, s, t, c, d);
return impl->add_type_rule(s, t, c, d, AVTAB_MEMBER);
}
bool sepolicy::type_transition(const char *s, const char *t, const char *c, const char *d, const char *o) {
if (o) {
dprint(__FUNCTION__, s, t, c, d, o);
return impl->add_filename_trans(s, t, c, d, o);
} else {
dprint(__FUNCTION__, s, t, c, d);
return impl->add_type_rule(s, t, c, d, AVTAB_TRANSITION);
}
}
bool sepolicy::permissive(const char *s) {
dprint(__FUNCTION__, s);
return impl->set_type_state(s, true);
}
bool sepolicy::enforce(const char *s) {
dprint(__FUNCTION__, s);
return impl->set_type_state(s, false);
}
bool sepolicy::type(const char *name, const char *attr) {
dprint(__FUNCTION__, name, attr);
return impl->add_type(name, TYPE_TYPE) && impl->add_typeattribute(name, attr);
}
bool sepolicy::attribute(const char *name) {
dprint(__FUNCTION__, name);
return impl->add_type(name, TYPE_ATTRIB);
}
bool sepolicy::typeattribute(const char *type, const char *attr) {
dprint(__FUNCTION__, type, attr);
return impl->add_typeattribute(type, attr);
}
bool sepolicy::genfscon(const char *fs_name, const char *path, const char *ctx) {
dprint(__FUNCTION__, fs_name, path, ctx);
return impl->add_genfscon(fs_name, path, ctx);
}
bool sepolicy::exists(const char *source) {
return hashtab_search(db->p_types.table, source) != nullptr;
}

View File

@@ -2,10 +2,9 @@
#include <vector>
#include <string>
#include <magiskpolicy.hpp>
#include <utils.hpp>
#include "sepolicy.hpp"
#include "policy.hpp"
using namespace std;