Support compiling split cils via magiskpolicy CLI
This commit is contained in:
parent
6263d684d9
commit
91818cfa1a
@ -37,7 +37,6 @@
|
||||
#include <sys/sysmacros.h>
|
||||
|
||||
#include <lzma.h>
|
||||
#include <cil/cil.h>
|
||||
|
||||
#include "binaries_xz.h"
|
||||
#include "binaries_arch_xz.h"
|
||||
@ -50,14 +49,13 @@
|
||||
#include "magisk.h"
|
||||
|
||||
#ifdef MAGISK_DEBUG
|
||||
#define VLOG(fmt, ...) printf(fmt, __VA_ARGS__)
|
||||
#define VLOG(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__)
|
||||
#else
|
||||
#define VLOG(fmt, ...)
|
||||
#endif
|
||||
|
||||
#define DEFAULT_DT_DIR "/proc/device-tree/firmware/android"
|
||||
|
||||
extern policydb_t *policydb;
|
||||
int (*init_applet_main[]) (int, char *[]) = { magiskpolicy_main, magiskpolicy_main, NULL };
|
||||
|
||||
struct cmdline {
|
||||
@ -149,12 +147,6 @@ static int setup_block(struct device *dev, const char *partname) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int strend(const char *s1, const char *s2) {
|
||||
size_t l1 = strlen(s1);
|
||||
size_t l2 = strlen(s2);
|
||||
return strcmp(s1 + l1 - l2, s2);
|
||||
}
|
||||
|
||||
static int read_fstab_dt(const struct cmdline *cmd, const char *mnt_point, char *partname) {
|
||||
char buf[128];
|
||||
struct stat st;
|
||||
@ -175,65 +167,6 @@ static int read_fstab_dt(const struct cmdline *cmd, const char *mnt_point, char
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int compile_cil() {
|
||||
DIR *dir;
|
||||
struct dirent *entry;
|
||||
char path[128];
|
||||
|
||||
struct cil_db *db = NULL;
|
||||
sepol_policydb_t *pdb = NULL;
|
||||
void *addr;
|
||||
size_t size;
|
||||
|
||||
cil_db_init(&db);
|
||||
cil_set_mls(db, 1);
|
||||
cil_set_multiple_decls(db, 1);
|
||||
cil_set_disable_neverallow(db, 1);
|
||||
cil_set_target_platform(db, SEPOL_TARGET_SELINUX);
|
||||
cil_set_policy_version(db, POLICYDB_VERSION_XPERMS_IOCTL);
|
||||
cil_set_attrs_expand_generated(db, 0);
|
||||
|
||||
// plat
|
||||
mmap_ro(SPLIT_PLAT_CIL, &addr, &size);
|
||||
VLOG("cil_add[%s]\n", SPLIT_PLAT_CIL);
|
||||
cil_add_file(db, SPLIT_PLAT_CIL, addr, size);
|
||||
munmap(addr, size);
|
||||
|
||||
// mapping
|
||||
char plat[10];
|
||||
int fd = open(SPLIT_NONPLAT_VER, O_RDONLY | O_CLOEXEC);
|
||||
plat[read(fd, plat, sizeof(plat)) - 1] = '\0';
|
||||
sprintf(path, SPLIT_PLAT_MAPPING, plat);
|
||||
mmap_ro(path, &addr, &size);
|
||||
VLOG("cil_add[%s]\n", path);
|
||||
cil_add_file(db, path, addr, size);
|
||||
munmap(addr, size);
|
||||
close(fd);
|
||||
|
||||
// nonplat
|
||||
dir = opendir(NONPLAT_POLICY_DIR);
|
||||
while ((entry = readdir(dir))) {
|
||||
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
|
||||
continue;
|
||||
if (strend(entry->d_name, ".cil") == 0) {
|
||||
sprintf(path, NONPLAT_POLICY_DIR "%s", entry->d_name);
|
||||
mmap_ro(path, &addr, &size);
|
||||
VLOG("cil_add[%s]\n", path);
|
||||
cil_add_file(db, path, addr, size);
|
||||
munmap(addr, size);
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
|
||||
cil_compile(db);
|
||||
cil_build_policydb(db, &pdb);
|
||||
cil_db_destroy(&db);
|
||||
|
||||
policydb = &pdb->p;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int verify_precompiled() {
|
||||
DIR *dir;
|
||||
struct dirent *entry;
|
||||
@ -279,7 +212,7 @@ static int patch_sepolicy() {
|
||||
load_policydb(SPLIT_PRECOMPILE);
|
||||
} else if (access(SPLIT_PLAT_CIL, R_OK) == 0) {
|
||||
init_patch = 1;
|
||||
compile_cil();
|
||||
compile_split_cil();
|
||||
} else if (access("/sepolicy", R_OK) == 0) {
|
||||
load_policydb("/sepolicy");
|
||||
} else {
|
||||
|
@ -42,14 +42,6 @@
|
||||
#define SELINUX_LOAD SELINUX_PATH "/load"
|
||||
#define SELINUX_CONTEXT SELINUX_PATH "/context"
|
||||
|
||||
// split policy paths
|
||||
#define PLAT_POLICY_DIR "/system/etc/selinux/"
|
||||
#define NONPLAT_POLICY_DIR "/vendor/etc/selinux/"
|
||||
#define SPLIT_PLAT_CIL PLAT_POLICY_DIR "plat_sepolicy.cil"
|
||||
#define SPLIT_PLAT_MAPPING PLAT_POLICY_DIR "mapping/%s.cil"
|
||||
#define SPLIT_PRECOMPILE NONPLAT_POLICY_DIR "precompiled_sepolicy"
|
||||
#define SPLIT_NONPLAT_VER NONPLAT_POLICY_DIR "plat_sepolicy_vers.txt"
|
||||
|
||||
#define MAGISKHIDE_PROP "persist.magisk.hide"
|
||||
|
||||
extern char *argv0; /* For changing process name */
|
||||
|
@ -107,6 +107,7 @@ int switch_mnt_ns(int pid);
|
||||
int fork_dont_care();
|
||||
void wait_till_exists(const char *target);
|
||||
void gen_rand_str(char *buf, int len);
|
||||
int strend(const char *s1, const char *s2);
|
||||
|
||||
// file.c
|
||||
|
||||
|
@ -3,8 +3,11 @@
|
||||
* Includes all the parsing logic for the policy statements
|
||||
*/
|
||||
|
||||
#include "magiskpolicy.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#include "sepolicy.h"
|
||||
#include "vector.h"
|
||||
#include "magiskpolicy.h"
|
||||
#include "magisk.h"
|
||||
|
||||
static int syntax_err = 0;
|
||||
@ -59,14 +62,20 @@ static void statements() {
|
||||
static void usage(char *arg0) {
|
||||
fprintf(stderr,
|
||||
"MagiskPolicy v" xstr(MAGISK_VERSION) "(" xstr(MAGISK_VER_CODE) ") (by topjohnwu)\n\n"
|
||||
"Usage: %s [--options...] [policystatements...]\n\n"
|
||||
"Usage: %s [--options...] [policy statements...]\n"
|
||||
"\n"
|
||||
"Options:\n"
|
||||
" --live directly apply patched policy live\n"
|
||||
" --magisk built-in rules for a Magisk selinux environment\n"
|
||||
" --load FILE load policies from <infile>\n"
|
||||
" --save FILE save policies to <outfile>\n\n"
|
||||
"If no input file is specified, it will load from current policies\n"
|
||||
"If neither --live nor --save is specified, nothing will happen\n\n"
|
||||
" --live directly apply sepolicy live\n"
|
||||
" --magisk inject built-in rules for a Magisk\n"
|
||||
" selinux environment\n"
|
||||
" --load FILE load policies from FILE\n"
|
||||
" --compile-split compile and load split cil policies\n"
|
||||
" from system and vendor just like init\n"
|
||||
" --save FILE save policies to FILE\n"
|
||||
"\n"
|
||||
"If neither --load or --compile-split is specified, it will load\n"
|
||||
"from current live policies (" SELINUX_POLICY ")\n"
|
||||
"\n"
|
||||
, arg0);
|
||||
statements();
|
||||
exit(1);
|
||||
@ -381,8 +390,8 @@ static void syntax_error_msg() {
|
||||
}
|
||||
|
||||
int magiskpolicy_main(int argc, char *argv[]) {
|
||||
char *infile = NULL, *outfile = NULL, *tok, *saveptr;
|
||||
int live = 0, magisk = 0;
|
||||
char *outfile = NULL, *tok, *saveptr;
|
||||
int magisk = 0;
|
||||
struct vector rules;
|
||||
|
||||
vec_init(&rules);
|
||||
@ -390,31 +399,39 @@ int magiskpolicy_main(int argc, char *argv[]) {
|
||||
if (argc < 2) usage(argv[0]);
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
if (argv[i][0] == '-' && argv[i][1] == '-') {
|
||||
if (strcmp(argv[i], "--live") == 0)
|
||||
live = 1;
|
||||
else if (strcmp(argv[i], "--magisk") == 0)
|
||||
if (strcmp(argv[i] + 2, "live") == 0)
|
||||
outfile = SELINUX_LOAD;
|
||||
else if (strcmp(argv[i] + 2, "magisk") == 0)
|
||||
magisk = 1;
|
||||
else if (strcmp(argv[i], "--load") == 0) {
|
||||
if (i + 1 >= argc) usage(argv[0]);
|
||||
infile = argv[i + 1];
|
||||
i += 1;
|
||||
} else if (strcmp(argv[i], "--save") == 0) {
|
||||
if (i + 1 >= argc) usage(argv[0]);
|
||||
else if (strcmp(argv[i] + 2, "load") == 0) {
|
||||
if (i + 1 >= argc)
|
||||
usage(argv[0]);
|
||||
if (load_policydb(argv[i + 1])) {
|
||||
fprintf(stderr, "Cannot load policy from %s\n", argv[i + 1]);
|
||||
return 1;
|
||||
}
|
||||
++i;
|
||||
} else if (strcmp(argv[i] + 2, "compile-split") == 0) {
|
||||
if (compile_split_cil()) {
|
||||
fprintf(stderr, "Cannot compile split cil\n");
|
||||
return 1;
|
||||
}
|
||||
} else if (strcmp(argv[i] + 2, "save") == 0) {
|
||||
if (i + 1 >= argc)
|
||||
usage(argv[0]);
|
||||
outfile = argv[i + 1];
|
||||
i += 1;
|
||||
} else
|
||||
++i;
|
||||
} else {
|
||||
usage(argv[0]);
|
||||
}
|
||||
} else {
|
||||
vec_push_back(&rules, argv[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Use current policy if not specified
|
||||
if(!infile)
|
||||
infile = SELINUX_POLICY;
|
||||
|
||||
if (load_policydb(infile)) {
|
||||
fprintf(stderr, "Cannot load policy from %s\n", infile);
|
||||
// Use current policy if nothing is loaded
|
||||
if(policydb == NULL && load_policydb(SELINUX_POLICY)) {
|
||||
fprintf(stderr, "Cannot load policy from " SELINUX_POLICY "\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -471,9 +488,6 @@ int magiskpolicy_main(int argc, char *argv[]) {
|
||||
|
||||
vec_destroy(&rules);
|
||||
|
||||
if (live)
|
||||
outfile = SELINUX_LOAD;
|
||||
|
||||
if (outfile && dump_policydb(outfile)) {
|
||||
fprintf(stderr, "Cannot dump policy to %s\n", outfile);
|
||||
return 1;
|
||||
|
@ -10,8 +10,17 @@
|
||||
#define SEPOL_PROC_DOMAIN "magisk"
|
||||
#define SEPOL_FILE_DOMAIN "magisk_file"
|
||||
|
||||
// split policy paths
|
||||
#define PLAT_POLICY_DIR "/system/etc/selinux/"
|
||||
#define NONPLAT_POLICY_DIR "/vendor/etc/selinux/"
|
||||
#define SPLIT_PLAT_CIL PLAT_POLICY_DIR "plat_sepolicy.cil"
|
||||
#define SPLIT_PLAT_MAPPING PLAT_POLICY_DIR "mapping/%s.cil"
|
||||
#define SPLIT_PRECOMPILE NONPLAT_POLICY_DIR "precompiled_sepolicy"
|
||||
#define SPLIT_NONPLAT_VER NONPLAT_POLICY_DIR "plat_sepolicy_vers.txt"
|
||||
|
||||
// policydb functions
|
||||
int load_policydb(const char *filename);
|
||||
int compile_split_cil();
|
||||
int dump_policydb(const char *filename);
|
||||
void destroy_policydb();
|
||||
|
||||
|
@ -1,7 +1,31 @@
|
||||
#include <dirent.h>
|
||||
#include <getopt.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <cil/cil.h>
|
||||
#include <sepol/debug.h>
|
||||
#include <sepol/policydb/policydb.h>
|
||||
#include <sepol/policydb/expand.h>
|
||||
#include <sepol/policydb/link.h>
|
||||
#include <sepol/policydb/services.h>
|
||||
#include <sepol/policydb/avrule_block.h>
|
||||
#include <sepol/policydb/conditional.h>
|
||||
#include <sepol/policydb/constraint.h>
|
||||
|
||||
#include "utils.h"
|
||||
#include "magiskpolicy.h"
|
||||
#include "sepolicy.h"
|
||||
#include "vector.h"
|
||||
|
||||
policydb_t *policydb = NULL;
|
||||
extern int policydb_index_decls(sepol_handle_t * handle, policydb_t * p);
|
||||
|
||||
static void *cmalloc(size_t s) {
|
||||
void *t = calloc(s, 1);
|
||||
@ -245,6 +269,69 @@ int load_policydb(const char *filename) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int compile_split_cil() {
|
||||
DIR *dir;
|
||||
struct dirent *entry;
|
||||
char path[128];
|
||||
|
||||
struct cil_db *db = NULL;
|
||||
sepol_policydb_t *pdb = NULL;
|
||||
void *addr;
|
||||
size_t size;
|
||||
|
||||
cil_db_init(&db);
|
||||
cil_set_mls(db, 1);
|
||||
cil_set_multiple_decls(db, 1);
|
||||
cil_set_disable_neverallow(db, 1);
|
||||
cil_set_target_platform(db, SEPOL_TARGET_SELINUX);
|
||||
cil_set_policy_version(db, POLICYDB_VERSION_XPERMS_IOCTL);
|
||||
cil_set_attrs_expand_generated(db, 0);
|
||||
|
||||
// plat
|
||||
mmap_ro(SPLIT_PLAT_CIL, &addr, &size);
|
||||
if (cil_add_file(db, SPLIT_PLAT_CIL, addr, size))
|
||||
return 1;
|
||||
fprintf(stderr, "cil_add[%s]\n", SPLIT_PLAT_CIL);
|
||||
munmap(addr, size);
|
||||
|
||||
// mapping
|
||||
char plat[10];
|
||||
int fd = open(SPLIT_NONPLAT_VER, O_RDONLY | O_CLOEXEC);
|
||||
plat[read(fd, plat, sizeof(plat)) - 1] = '\0';
|
||||
sprintf(path, SPLIT_PLAT_MAPPING, plat);
|
||||
mmap_ro(path, &addr, &size);
|
||||
if (cil_add_file(db, path, addr, size))
|
||||
return 1;
|
||||
fprintf(stderr, "cil_add[%s]\n", path);
|
||||
munmap(addr, size);
|
||||
close(fd);
|
||||
|
||||
// nonplat
|
||||
dir = opendir(NONPLAT_POLICY_DIR);
|
||||
while ((entry = readdir(dir))) {
|
||||
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
|
||||
continue;
|
||||
if (strend(entry->d_name, ".cil") == 0) {
|
||||
sprintf(path, NONPLAT_POLICY_DIR "%s", entry->d_name);
|
||||
mmap_ro(path, &addr, &size);
|
||||
if (cil_add_file(db, path, addr, size))
|
||||
return 1;
|
||||
fprintf(stderr, "cil_add[%s]\n", path);
|
||||
munmap(addr, size);
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
|
||||
if (cil_compile(db))
|
||||
return 1;
|
||||
if (cil_build_policydb(db, &pdb))
|
||||
return 1;
|
||||
|
||||
cil_db_destroy(&db);
|
||||
policydb = &pdb->p;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dump_policydb(const char *filename) {
|
||||
int fd, ret;
|
||||
void *data = NULL;
|
||||
|
@ -4,35 +4,16 @@
|
||||
#ifndef _SEPOLICY_H
|
||||
#define _SEPOLICY_H
|
||||
|
||||
#include <getopt.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <sepol/debug.h>
|
||||
#include <sepol/policydb/policydb.h>
|
||||
#include <sepol/policydb/expand.h>
|
||||
#include <sepol/policydb/link.h>
|
||||
#include <sepol/policydb/services.h>
|
||||
#include <sepol/policydb/avrule_block.h>
|
||||
#include <sepol/policydb/conditional.h>
|
||||
#include <sepol/policydb/constraint.h>
|
||||
|
||||
#include "vector.h"
|
||||
// Global policydb
|
||||
extern policydb_t *policydb;
|
||||
|
||||
// hashtab traversal macro
|
||||
#define hashtab_for_each(table, ptr) \
|
||||
for (int _i = 0; _i < table->size; ++_i) \
|
||||
for (*ptr = table->htable[_i]; *ptr != NULL; *ptr = (*ptr)->next)
|
||||
|
||||
// Global policydb
|
||||
extern policydb_t *policydb;
|
||||
|
||||
// sepolicy manipulation functions
|
||||
int create_domain(char *d);
|
||||
int set_domain_state(char* s, int state);
|
||||
@ -42,6 +23,4 @@ int add_typeattribute(char *domainS, char *attr);
|
||||
int add_rule(char *s, char *t, char *c, char *p, int effect, int not);
|
||||
int add_xperm_rule(char *s, char *t, char *c, char *range, int effect, int not);
|
||||
|
||||
extern int policydb_index_decls(sepol_handle_t * handle, policydb_t * p);
|
||||
|
||||
#endif
|
||||
|
@ -477,3 +477,9 @@ void gen_rand_str(char *buf, int len) {
|
||||
}
|
||||
buf[len - 1] = '\0';
|
||||
}
|
||||
|
||||
int strend(const char *s1, const char *s2) {
|
||||
size_t l1 = strlen(s1);
|
||||
size_t l2 = strlen(s2);
|
||||
return strcmp(s1 + l1 - l2, s2);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user