mirror of
https://github.com/topjohnwu/Magisk
synced 2024-11-18 03:26:26 +01:00
parent
cf589f8c64
commit
6180558068
@ -28,6 +28,7 @@ int sepol_create(const char *s);
|
||||
int sepol_permissive(const char *s);
|
||||
int sepol_enforce(const char *s);
|
||||
int sepol_attradd(const char *s, const char *a);
|
||||
int sepol_genfscon(const char *name, const char *path, const char *context);
|
||||
int sepol_exists(const char *source);
|
||||
|
||||
// Built in rules
|
||||
|
@ -80,6 +80,11 @@ int sepol_attradd(const char *s, const char *a) {
|
||||
return add_typeattribute(s, a);
|
||||
}
|
||||
|
||||
int sepol_genfscon(const char *name, const char *path, const char *context) {
|
||||
vprint("genfscon %s %s %s\n", name, path, context);
|
||||
return add_genfscon(name, path, context);
|
||||
}
|
||||
|
||||
int sepol_exists(const char *source) {
|
||||
return hashtab_search(magisk_policydb->p_types.table, source) != nullptr;
|
||||
}
|
||||
|
@ -11,18 +11,25 @@ policydb_t *magisk_policydb = NULL;
|
||||
extern void *xmalloc(size_t size);
|
||||
extern void *xcalloc(size_t nmemb, size_t size);
|
||||
extern void *xrealloc(void *ptr, size_t size);
|
||||
|
||||
// Internal libsepol APIs
|
||||
extern int policydb_index_decls(sepol_handle_t * handle, policydb_t * p);
|
||||
extern int context_from_string(
|
||||
sepol_handle_t * handle,
|
||||
const policydb_t * policydb,
|
||||
context_struct_t ** cptr,
|
||||
const char *con_str, size_t con_str_len);
|
||||
|
||||
// Generic hash table traversal
|
||||
#define hash_for_each(node_ptr, n_slots, table, block) \
|
||||
for (int __i = 0; __i < (table)->n_slots; ++__i) { \
|
||||
__typeof__(*(table)->node_ptr) node; \
|
||||
__typeof__(node) __next; \
|
||||
for (node = (table)->node_ptr[__i]; node; node = __next) { \
|
||||
__next = node->next; \
|
||||
block \
|
||||
} \
|
||||
for (int __i = 0; __i < (table)->n_slots; ++__i) { \
|
||||
__typeof__(*(table)->node_ptr) node; \
|
||||
__typeof__(node) __next; \
|
||||
for (node = (table)->node_ptr[__i]; node; node = __next) { \
|
||||
__next = node->next; \
|
||||
block \
|
||||
} \
|
||||
}
|
||||
|
||||
// hashtab traversal
|
||||
#define hashtab_for_each(hashtab, block) \
|
||||
@ -488,6 +495,66 @@ int add_type_rule(const char *s, const char *t, const char *c, const char *d, in
|
||||
return 0;
|
||||
}
|
||||
|
||||
int add_genfscon(const char *name, const char *path, const char *context) {
|
||||
// First try to create context
|
||||
context_struct_t *ctx;
|
||||
if (context_from_string(NULL, mpdb, &ctx, context, strlen(context))) {
|
||||
LOGW("Failed to create context from string [%s]\n", context);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Allocate genfs context
|
||||
ocontext_t *newc = xcalloc(sizeof(*newc), 1);
|
||||
newc->u.name = strdup(path);
|
||||
memcpy(&newc->context[0], ctx, sizeof(*ctx));
|
||||
free(ctx);
|
||||
|
||||
// Find or allocate genfs
|
||||
genfs_t *last_gen = NULL;
|
||||
genfs_t *newfs = NULL;
|
||||
for (genfs_t *node = mpdb->genfs; node; node = node->next) {
|
||||
if (strcmp(node->fstype, name) == 0) {
|
||||
newfs = node;
|
||||
break;
|
||||
}
|
||||
last_gen = node;
|
||||
}
|
||||
if (newfs == NULL) {
|
||||
newfs = xcalloc(sizeof(*newfs), 1);
|
||||
newfs->fstype = strdup(name);
|
||||
// Insert
|
||||
if (last_gen)
|
||||
last_gen->next = newfs;
|
||||
else
|
||||
mpdb->genfs = newfs;
|
||||
}
|
||||
|
||||
// Insert or replace genfs context
|
||||
ocontext_t *last_ctx = NULL;
|
||||
for (ocontext_t *node = newfs->head; node; node = node->next) {
|
||||
if (strcmp(node->u.name, path) == 0) {
|
||||
// Unlink
|
||||
if (last_ctx)
|
||||
last_ctx->next = node->next;
|
||||
else
|
||||
newfs->head = NULL;
|
||||
// Destroy old node
|
||||
free(node->u.name);
|
||||
context_destroy(&node->context[0]);
|
||||
free(node);
|
||||
break;
|
||||
}
|
||||
last_ctx = node;
|
||||
}
|
||||
// Insert
|
||||
if (last_ctx)
|
||||
last_ctx->next = newc;
|
||||
else
|
||||
newfs->head = newc;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void strip_dontaudit() {
|
||||
avtab_for_each(&mpdb->te_avtab, {
|
||||
if (node->key.specified == AVTAB_AUDITDENY || node->key.specified == AVTAB_XPERMS_DONTAUDIT)
|
||||
|
@ -14,6 +14,7 @@ int add_rule(const char *s, const char *t, const char *c, const char *p, int eff
|
||||
int add_xperm_rule(const char *s, const char *t, const char *c, const char *range, int effect, int n);
|
||||
int add_type_rule(const char *s, const char *t, const char *c, const char *d, int effect);
|
||||
int add_filename_trans(const char *s, const char *t, const char *c, const char *d, const char *o);
|
||||
int add_genfscon(const char *name, const char *path, const char *context);
|
||||
void strip_dontaudit();
|
||||
|
||||
__END_DECLS
|
||||
|
@ -44,6 +44,11 @@ R"EOF(Type 6:
|
||||
"name_transition source_type target_type class default_type object_name"
|
||||
)EOF";
|
||||
|
||||
static const char *type_msg_7 =
|
||||
R"EOF(Type 7:
|
||||
"genfscon fs_name partial_path fs_context"
|
||||
)EOF";
|
||||
|
||||
void statement_help() {
|
||||
fprintf(stderr,
|
||||
R"EOF(One policy statement should be treated as one parameter;
|
||||
@ -63,8 +68,9 @@ Supported policy statements:
|
||||
%s
|
||||
%s
|
||||
%s
|
||||
%s
|
||||
Notes:
|
||||
* Type 4 - 6 does not support collections
|
||||
* Type 4 - 7 does not support collections
|
||||
* Object classes cannot be collections
|
||||
* source_type and target_type can also be attributes
|
||||
|
||||
@ -76,7 +82,7 @@ allow s1 t2 class { all-permissions }
|
||||
allow s2 t1 class { all-permissions }
|
||||
allow s2 t2 class { all-permissions }
|
||||
|
||||
)EOF", type_msg_1, type_msg_2, type_msg_3, type_msg_4, type_msg_5, type_msg_6);
|
||||
)EOF", type_msg_1, type_msg_2, type_msg_3, type_msg_4, type_msg_5, type_msg_6, type_msg_7);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
@ -371,12 +377,39 @@ static int parse_pattern_6(int action, const char *action_str, char *stmt) {
|
||||
}
|
||||
++state;
|
||||
}
|
||||
if (state < 4) return 1;
|
||||
if (state < 5) return 1;
|
||||
if (sepol_nametrans(source, target, cls, def, filename))
|
||||
LOGW("Error in: %s %s %s %s %s %s\n", action_str, source, target, cls, def, filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Pattern 7: action name path context
|
||||
static int parse_pattern_7(int action, const char *action_str, char *stmt) {
|
||||
int state = 0;
|
||||
char *cur;
|
||||
char *name, *path, *context;
|
||||
while ((cur = strtok_r(nullptr, " ", &stmt)) != nullptr) {
|
||||
switch(state) {
|
||||
case 0:
|
||||
name = cur;
|
||||
break;
|
||||
case 1:
|
||||
path = cur;
|
||||
break;
|
||||
case 2:
|
||||
context = cur;
|
||||
break;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
++state;
|
||||
}
|
||||
if (state < 3) return 1;
|
||||
if (sepol_genfscon(name, path, context))
|
||||
LOGW("Error in: %s %s %s %s\n", action_str, name, path, context);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define add_action(name, type, num) \
|
||||
else if (strcmp(name, action) == 0) { \
|
||||
if (parse_pattern_##type(num, name, remain)) \
|
||||
@ -412,6 +445,7 @@ void parse_statement(const char *statement) {
|
||||
add_action("type_change", 5, 1)
|
||||
add_action("type_member", 5, 2)
|
||||
add_action("name_transition", 6, 0)
|
||||
add_action("genfscon", 7, 0)
|
||||
else { LOGW("Unknown statement: '%s'\n\n", statement); }
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user