mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-12-24 04:47:39 +00:00
Dynamic patch verity and forceencrypt flag
This commit is contained in:
parent
b4c0a255fc
commit
baff9256c5
@ -47,10 +47,15 @@
|
||||
#include "cpio.h"
|
||||
#include "magisk.h"
|
||||
|
||||
// #define VLOG(fmt, ...) printf(fmt, __VA_ARGS__) /* Enable to debug */
|
||||
#ifdef MAGISK_DEBUG
|
||||
#define VLOG(fmt, ...) printf(fmt, __VA_ARGS__)
|
||||
#else
|
||||
#define VLOG(fmt, ...)
|
||||
#endif
|
||||
|
||||
extern policydb_t *policydb;
|
||||
int (*init_applet_main[]) (int, char *[]) = { magiskpolicy_main, magiskpolicy_main, NULL };
|
||||
static int keepverity = 0, keepencrypt = 0;
|
||||
|
||||
struct cmdline {
|
||||
int skip_initramfs;
|
||||
@ -65,8 +70,6 @@ struct device {
|
||||
char path[64];
|
||||
};
|
||||
|
||||
extern policydb_t *policydb;
|
||||
|
||||
static void parse_cmdline(struct cmdline *cmd) {
|
||||
// cleanup
|
||||
cmd->skip_initramfs = 0;
|
||||
@ -143,7 +146,24 @@ static int setup_block(struct device *dev, const char *partname) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void patch_ramdisk() {
|
||||
static void fstab_patch_cb(int dirfd, struct dirent *entry) {
|
||||
if (entry->d_type == DT_REG && strstr(entry->d_name, "fstab")) {
|
||||
void *buf;
|
||||
size_t _size;
|
||||
uint32_t size;
|
||||
full_read_at(dirfd, entry->d_name, &buf, &_size);
|
||||
size = _size; /* Type conversion */
|
||||
if (!keepverity)
|
||||
patch_verity(&buf, &size, 1);
|
||||
if (!keepencrypt)
|
||||
patch_encryption(&buf, &size);
|
||||
int fstab = xopenat(dirfd, entry->d_name, O_WRONLY | O_CLOEXEC);
|
||||
write(fstab, buf, size);
|
||||
close(fstab);
|
||||
}
|
||||
}
|
||||
|
||||
static void patch_ramdisk(int root) {
|
||||
void *addr;
|
||||
size_t size;
|
||||
mmap_rw("/init", &addr, &size);
|
||||
@ -161,6 +181,23 @@ static void patch_ramdisk() {
|
||||
write(fd, addr, size);
|
||||
close(fd);
|
||||
free(addr);
|
||||
|
||||
char *key, *value;
|
||||
full_read("/.backup/.magisk", &addr, &size);
|
||||
for (char *tok = strtok(addr, "\n"); tok; tok = strtok(NULL, "\n")) {
|
||||
key = tok;
|
||||
value = strchr(tok, '=') + 1;
|
||||
value[-1] = '\0';
|
||||
if (strcmp(key, "KEEPVERITY") == 0)
|
||||
keepverity = strcmp(value, "true") == 0;
|
||||
else if (strcmp(key, "KEEPFORCEENCRYPT") == 0)
|
||||
keepencrypt = strcmp(value, "true") == 0;
|
||||
}
|
||||
|
||||
excl_list = (char *[]) { "system_root", "system", "vendor", NULL };
|
||||
in_order_walk(root, fstab_patch_cb);
|
||||
if (!keepverity)
|
||||
unlink("/verity_key");
|
||||
}
|
||||
|
||||
static int strend(const char *s1, const char *s2) {
|
||||
@ -456,17 +493,13 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
}
|
||||
|
||||
// Only patch initramfs if not intended to run in recovery (legacy devices)
|
||||
int overlay = open("/overlay", O_RDONLY | O_CLOEXEC);
|
||||
|
||||
// Only patch rootfs if not intended to run in recovery
|
||||
if (access("/etc/recovery.fstab", F_OK) != 0) {
|
||||
int overlay = open("/overlay", O_RDONLY | O_CLOEXEC);
|
||||
mv_dir(overlay, root);
|
||||
|
||||
// Clean up
|
||||
rmdir("/overlay");
|
||||
close(overlay);
|
||||
close(root);
|
||||
|
||||
patch_ramdisk();
|
||||
patch_ramdisk(root);
|
||||
patch_sepolicy();
|
||||
|
||||
if (fork_dont_care() == 0) {
|
||||
@ -475,7 +508,12 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
}
|
||||
|
||||
// Clean up
|
||||
close(overlay);
|
||||
close(root);
|
||||
umount("/vendor");
|
||||
rmdir("/overlay");
|
||||
|
||||
// Finally, give control back!
|
||||
execv("/init", argv);
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ typedef struct cpio_entry {
|
||||
// uint32_t namesize;
|
||||
// uint32_t check;
|
||||
char *filename;
|
||||
char *data;
|
||||
void *data;
|
||||
int remove;
|
||||
} cpio_entry;
|
||||
|
||||
|
@ -102,6 +102,7 @@ struct file_attr {
|
||||
|
||||
int fd_getpath(int fd, char *path, size_t size);
|
||||
int mkdir_p(const char *pathname, mode_t mode);
|
||||
void in_order_walk(int dirfd, void (*callback)(int, struct dirent*));
|
||||
void rm_rf(const char *path);
|
||||
void frm_rf(int dirfd);
|
||||
void mv_f(const char *source, const char *destination);
|
||||
@ -119,7 +120,9 @@ void clone_attr(const char *source, const char *target);
|
||||
void restorecon(int dirfd, int force);
|
||||
int mmap_ro(const char *filename, void **buf, size_t *size);
|
||||
int mmap_rw(const char *filename, void **buf, size_t *size);
|
||||
void fd_full_read(int fd, void **buf, size_t *size);
|
||||
void full_read(const char *filename, void **buf, size_t *size);
|
||||
void full_read_at(int dirfd, const char *filename, void **buf, size_t *size);
|
||||
void stream_full_read(int fd, void **buf, size_t *size);
|
||||
void write_zero(int fd, size_t size);
|
||||
void mem_align(size_t *pos, size_t align);
|
||||
@ -142,7 +145,7 @@ void trim_img(const char *img);
|
||||
// pattern.c
|
||||
|
||||
void patch_init_rc(void **buf, size_t *size);
|
||||
int patch_verity(char **buf, uint32_t *size, int patch);
|
||||
void patch_encryption(char **buf, uint32_t *size);
|
||||
int patch_verity(void **buf, uint32_t *size, int patch);
|
||||
void patch_encryption(void **buf, uint32_t *size);
|
||||
|
||||
#endif
|
||||
|
@ -78,7 +78,7 @@ static void dtb_patch(const char *file, int patch) {
|
||||
fdt_for_each_subnode(block, fdt, fstab) {
|
||||
fprintf(stderr, "Found block [%s] in fstab\n", fdt_get_name(fdt, block, NULL));
|
||||
uint32_t value_size;
|
||||
char *value = (char *) fdt_getprop(fdt, block, "fsmgr_flags", &value_size);
|
||||
void *value = (char *) fdt_getprop(fdt, block, "fsmgr_flags", &value_size);
|
||||
found |= patch_verity(&value, &value_size, patch);
|
||||
}
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ static char *cpio_stocksha1(struct vector *v) {
|
||||
vec_for_each(v, f) {
|
||||
if (strcmp(f->filename, "init.magisk.rc") == 0
|
||||
|| strcmp(f->filename, "overlay/init.magisk.rc") == 0) {
|
||||
for (char *pos = f->data; pos < f->data + f->filesize; pos = strchr(pos + 1, '\n') + 1) {
|
||||
for (void *pos = f->data; pos < f->data + f->filesize; pos = strchr(pos + 1, '\n') + 1) {
|
||||
if (memcmp(pos, "# STOCKSHA1=", 12) == 0) {
|
||||
pos += 12;
|
||||
memcpy(sha1, pos, 40);
|
||||
|
@ -17,13 +17,13 @@
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
char **excl_list = (char *[]) { NULL };
|
||||
char **excl_list = NULL;
|
||||
|
||||
static int is_excl(const char *name) {
|
||||
for (int i = 0; excl_list[i]; ++i) {
|
||||
if (strcmp(name, excl_list[i]) == 0)
|
||||
return 1;
|
||||
}
|
||||
if (excl_list)
|
||||
for (int i = 0; excl_list[i]; ++i)
|
||||
if (strcmp(name, excl_list[i]) == 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -55,6 +55,36 @@ int mkdir_p(const char *pathname, mode_t mode) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void in_order_walk(int dirfd, void (*callback)(int, struct dirent*)) {
|
||||
struct dirent *entry;
|
||||
int newfd;
|
||||
DIR *dir = xfdopendir(dirfd);
|
||||
|
||||
while ((entry = xreaddir(dir))) {
|
||||
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
|
||||
continue;
|
||||
if (is_excl(entry->d_name))
|
||||
continue;
|
||||
if (entry->d_type == DT_DIR) {
|
||||
newfd = xopenat(dirfd, entry->d_name, O_RDONLY | O_CLOEXEC);
|
||||
in_order_walk(newfd, callback);
|
||||
close(newfd);
|
||||
}
|
||||
callback(dirfd, entry);
|
||||
}
|
||||
}
|
||||
|
||||
static void rm_cb(int dirfd, struct dirent *entry) {
|
||||
switch (entry->d_type) {
|
||||
case DT_DIR:
|
||||
unlinkat(dirfd, entry->d_name, AT_REMOVEDIR);
|
||||
break;
|
||||
default:
|
||||
unlinkat(dirfd, entry->d_name, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void rm_rf(const char *path) {
|
||||
int fd = xopen(path, O_RDONLY | O_CLOEXEC);
|
||||
if (fd < 0)
|
||||
@ -65,27 +95,7 @@ void rm_rf(const char *path) {
|
||||
}
|
||||
|
||||
void frm_rf(int dirfd) {
|
||||
struct dirent *entry;
|
||||
int newfd;
|
||||
DIR *dir = xfdopendir(dirfd);
|
||||
|
||||
while ((entry = xreaddir(dir))) {
|
||||
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
|
||||
continue;
|
||||
if (is_excl(entry->d_name))
|
||||
continue;
|
||||
switch (entry->d_type) {
|
||||
case DT_DIR:
|
||||
newfd = xopenat(dirfd, entry->d_name, O_RDONLY | O_CLOEXEC);
|
||||
frm_rf(newfd);
|
||||
close(newfd);
|
||||
unlinkat(dirfd, entry->d_name, AT_REMOVEDIR);
|
||||
break;
|
||||
default:
|
||||
unlinkat(dirfd, entry->d_name, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
in_order_walk(dirfd, rm_cb);
|
||||
}
|
||||
|
||||
/* This will only on the same file system */
|
||||
@ -360,6 +370,13 @@ int mmap_rw(const char *filename, void **buf, size_t *size) {
|
||||
return _mmap(1, filename, buf, size);
|
||||
}
|
||||
|
||||
void fd_full_read(int fd, void **buf, size_t *size) {
|
||||
*size = lseek(fd, 0, SEEK_END);
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
*buf = xmalloc(*size);
|
||||
xxread(fd, *buf, *size);
|
||||
}
|
||||
|
||||
void full_read(const char *filename, void **buf, size_t *size) {
|
||||
int fd = xopen(filename, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
@ -367,10 +384,18 @@ void full_read(const char *filename, void **buf, size_t *size) {
|
||||
*size = 0;
|
||||
return;
|
||||
}
|
||||
*size = lseek(fd, 0, SEEK_END);
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
*buf = xmalloc(*size);
|
||||
xxread(fd, *buf, *size);
|
||||
fd_full_read(fd, buf, size);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
void full_read_at(int dirfd, const char *filename, void **buf, size_t *size) {
|
||||
int fd = xopenat(dirfd, filename, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
*buf = NULL;
|
||||
*size = 0;
|
||||
return;
|
||||
}
|
||||
fd_full_read(fd, buf, size);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
|
@ -58,12 +58,12 @@ void patch_init_rc(void **buf, size_t *size) {
|
||||
*buf = new_data;
|
||||
}
|
||||
|
||||
int patch_verity(char **buf, uint32_t *size, int patch) {
|
||||
int patch_verity(void **buf, uint32_t *size, int patch) {
|
||||
int skip, found = 0;
|
||||
for (int pos = 0; pos < *size; ++pos) {
|
||||
if ((skip = check_verity_pattern(*buf + pos)) > 0) {
|
||||
found = 1;
|
||||
fprintf(stderr, "%s pattern [%.*s]\n", patch ? "Remove" : "Found", skip, *buf + pos);
|
||||
fprintf(stderr, "%s pattern [%.*s]\n", patch ? "Remove" : "Found", skip, (char *) *buf + pos);
|
||||
if (patch) {
|
||||
memcpy(*buf + pos, *buf + pos + skip, *size - pos - skip);
|
||||
memset(*buf + *size - skip, '\0', skip);
|
||||
@ -76,11 +76,11 @@ int patch_verity(char **buf, uint32_t *size, int patch) {
|
||||
return found;
|
||||
}
|
||||
|
||||
void patch_encryption(char **buf, uint32_t *size) {
|
||||
void patch_encryption(void **buf, uint32_t *size) {
|
||||
int skip;
|
||||
for (int pos = 0; pos < *size; ++pos) {
|
||||
if ((skip = check_encryption_pattern(*buf + pos)) > 0) {
|
||||
fprintf(stderr, "Replace pattern [%.*s] with [encryptable]\n", skip, *buf + pos);
|
||||
fprintf(stderr, "Replace pattern [%.*s] with [encryptable]\n", skip, (char *) *buf + pos);
|
||||
memcpy(*buf + pos, "encryptable", 11);
|
||||
memcpy(*buf + pos + 11, *buf + pos + skip, *size - pos - skip);
|
||||
memset(*buf + *size - skip + 11, '\0', skip - 11);
|
||||
|
@ -64,7 +64,7 @@ BOOTIMAGE="$1"
|
||||
# Presets
|
||||
[ -z $KEEPVERITY ] && KEEPVERITY=false
|
||||
[ -z $KEEPFORCEENCRYPT ] && KEEPFORCEENCRYPT=false
|
||||
[ -z $HIGH_COMP ] && HIGH_COMP=false
|
||||
[ -z $HIGHCOMP ] && HIGHCOMP=false
|
||||
|
||||
chmod -R 755 .
|
||||
|
||||
@ -89,7 +89,7 @@ case $? in
|
||||
2 )
|
||||
ui_print "! Insufficient boot partition size detected"
|
||||
ui_print "- Enable high compression mode"
|
||||
HIGH_COMP=true
|
||||
HIGHCOMP=true
|
||||
;;
|
||||
3 )
|
||||
ui_print "- ChromeOS boot image detected"
|
||||
@ -139,11 +139,10 @@ esac
|
||||
|
||||
ui_print "- Patching ramdisk"
|
||||
|
||||
[ -f /sdcard/ramdisk-recovery.img ] && HIGH_COMP=true
|
||||
[ -f /sdcard/ramdisk-recovery.img ] && HIGHCOMP=true
|
||||
|
||||
./magiskboot --cpio-patch ramdisk.cpio $KEEPVERITY $KEEPFORCEENCRYPT
|
||||
./magiskboot --cpio-add ramdisk.cpio 750 init magiskinit
|
||||
./magiskboot --cpio-backup ramdisk.cpio ramdisk.cpio.orig $HIGH_COMP $SHA1
|
||||
./magiskboot --cpio-backup ramdisk.cpio ramdisk.cpio.orig $HIGHCOMP $KEEPVERITY $KEEPFORCEENCRYPT $SHA1
|
||||
|
||||
rm -f ramdisk.cpio.orig
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user