mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-10-15 13:20:16 +00:00
@@ -28,6 +28,7 @@ int sepol_create(const char *s);
|
|||||||
int sepol_permissive(const char *s);
|
int sepol_permissive(const char *s);
|
||||||
int sepol_enforce(const char *s);
|
int sepol_enforce(const char *s);
|
||||||
int sepol_attradd(const char *s, const char *a);
|
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);
|
int sepol_exists(const char *source);
|
||||||
|
|
||||||
// Built in rules
|
// Built in rules
|
||||||
|
@@ -80,6 +80,11 @@ int sepol_attradd(const char *s, const char *a) {
|
|||||||
return add_typeattribute(s, 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) {
|
int sepol_exists(const char *source) {
|
||||||
return hashtab_search(magisk_policydb->p_types.table, source) != nullptr;
|
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 *xmalloc(size_t size);
|
||||||
extern void *xcalloc(size_t nmemb, size_t size);
|
extern void *xcalloc(size_t nmemb, size_t size);
|
||||||
extern void *xrealloc(void *ptr, 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 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
|
// Generic hash table traversal
|
||||||
#define hash_for_each(node_ptr, n_slots, table, block) \
|
#define hash_for_each(node_ptr, n_slots, table, block) \
|
||||||
for (int __i = 0; __i < (table)->n_slots; ++__i) { \
|
for (int __i = 0; __i < (table)->n_slots; ++__i) { \
|
||||||
__typeof__(*(table)->node_ptr) node; \
|
__typeof__(*(table)->node_ptr) node; \
|
||||||
__typeof__(node) __next; \
|
__typeof__(node) __next; \
|
||||||
for (node = (table)->node_ptr[__i]; node; node = __next) { \
|
for (node = (table)->node_ptr[__i]; node; node = __next) { \
|
||||||
__next = node->next; \
|
__next = node->next; \
|
||||||
block \
|
block \
|
||||||
} \
|
|
||||||
} \
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
// hashtab traversal
|
// hashtab traversal
|
||||||
#define hashtab_for_each(hashtab, block) \
|
#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;
|
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() {
|
void strip_dontaudit() {
|
||||||
avtab_for_each(&mpdb->te_avtab, {
|
avtab_for_each(&mpdb->te_avtab, {
|
||||||
if (node->key.specified == AVTAB_AUDITDENY || node->key.specified == AVTAB_XPERMS_DONTAUDIT)
|
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_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_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_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();
|
void strip_dontaudit();
|
||||||
|
|
||||||
__END_DECLS
|
__END_DECLS
|
||||||
|
@@ -44,6 +44,11 @@ R"EOF(Type 6:
|
|||||||
"name_transition source_type target_type class default_type object_name"
|
"name_transition source_type target_type class default_type object_name"
|
||||||
)EOF";
|
)EOF";
|
||||||
|
|
||||||
|
static const char *type_msg_7 =
|
||||||
|
R"EOF(Type 7:
|
||||||
|
"genfscon fs_name partial_path fs_context"
|
||||||
|
)EOF";
|
||||||
|
|
||||||
void statement_help() {
|
void statement_help() {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
R"EOF(One policy statement should be treated as one parameter;
|
R"EOF(One policy statement should be treated as one parameter;
|
||||||
@@ -63,8 +68,9 @@ Supported policy statements:
|
|||||||
%s
|
%s
|
||||||
%s
|
%s
|
||||||
%s
|
%s
|
||||||
|
%s
|
||||||
Notes:
|
Notes:
|
||||||
* Type 4 - 6 does not support collections
|
* Type 4 - 7 does not support collections
|
||||||
* Object classes cannot be collections
|
* Object classes cannot be collections
|
||||||
* source_type and target_type can also be attributes
|
* 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 t1 class { all-permissions }
|
||||||
allow s2 t2 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);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -371,12 +377,39 @@ static int parse_pattern_6(int action, const char *action_str, char *stmt) {
|
|||||||
}
|
}
|
||||||
++state;
|
++state;
|
||||||
}
|
}
|
||||||
if (state < 4) return 1;
|
if (state < 5) return 1;
|
||||||
if (sepol_nametrans(source, target, cls, def, filename))
|
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);
|
LOGW("Error in: %s %s %s %s %s %s\n", action_str, source, target, cls, def, filename);
|
||||||
return 0;
|
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) \
|
#define add_action(name, type, num) \
|
||||||
else if (strcmp(name, action) == 0) { \
|
else if (strcmp(name, action) == 0) { \
|
||||||
if (parse_pattern_##type(num, name, remain)) \
|
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_change", 5, 1)
|
||||||
add_action("type_member", 5, 2)
|
add_action("type_member", 5, 2)
|
||||||
add_action("name_transition", 6, 0)
|
add_action("name_transition", 6, 0)
|
||||||
|
add_action("genfscon", 7, 0)
|
||||||
else { LOGW("Unknown statement: '%s'\n\n", statement); }
|
else { LOGW("Unknown statement: '%s'\n\n", statement); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user