Dynamic patch verity and forceencrypt flag
This commit is contained in:
parent
b4c0a255fc
commit
baff9256c5
@ -47,10 +47,15 @@
|
|||||||
#include "cpio.h"
|
#include "cpio.h"
|
||||||
#include "magisk.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, ...)
|
#define VLOG(fmt, ...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern policydb_t *policydb;
|
||||||
int (*init_applet_main[]) (int, char *[]) = { magiskpolicy_main, magiskpolicy_main, NULL };
|
int (*init_applet_main[]) (int, char *[]) = { magiskpolicy_main, magiskpolicy_main, NULL };
|
||||||
|
static int keepverity = 0, keepencrypt = 0;
|
||||||
|
|
||||||
struct cmdline {
|
struct cmdline {
|
||||||
int skip_initramfs;
|
int skip_initramfs;
|
||||||
@ -65,8 +70,6 @@ struct device {
|
|||||||
char path[64];
|
char path[64];
|
||||||
};
|
};
|
||||||
|
|
||||||
extern policydb_t *policydb;
|
|
||||||
|
|
||||||
static void parse_cmdline(struct cmdline *cmd) {
|
static void parse_cmdline(struct cmdline *cmd) {
|
||||||
// cleanup
|
// cleanup
|
||||||
cmd->skip_initramfs = 0;
|
cmd->skip_initramfs = 0;
|
||||||
@ -143,7 +146,24 @@ static int setup_block(struct device *dev, const char *partname) {
|
|||||||
return 0;
|
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;
|
void *addr;
|
||||||
size_t size;
|
size_t size;
|
||||||
mmap_rw("/init", &addr, &size);
|
mmap_rw("/init", &addr, &size);
|
||||||
@ -161,6 +181,23 @@ static void patch_ramdisk() {
|
|||||||
write(fd, addr, size);
|
write(fd, addr, size);
|
||||||
close(fd);
|
close(fd);
|
||||||
free(addr);
|
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) {
|
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) {
|
if (access("/etc/recovery.fstab", F_OK) != 0) {
|
||||||
int overlay = open("/overlay", O_RDONLY | O_CLOEXEC);
|
|
||||||
mv_dir(overlay, root);
|
mv_dir(overlay, root);
|
||||||
|
|
||||||
// Clean up
|
patch_ramdisk(root);
|
||||||
rmdir("/overlay");
|
|
||||||
close(overlay);
|
|
||||||
close(root);
|
|
||||||
|
|
||||||
patch_ramdisk();
|
|
||||||
patch_sepolicy();
|
patch_sepolicy();
|
||||||
|
|
||||||
if (fork_dont_care() == 0) {
|
if (fork_dont_care() == 0) {
|
||||||
@ -475,7 +508,12 @@ int main(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clean up
|
||||||
|
close(overlay);
|
||||||
|
close(root);
|
||||||
umount("/vendor");
|
umount("/vendor");
|
||||||
|
rmdir("/overlay");
|
||||||
|
|
||||||
// Finally, give control back!
|
// Finally, give control back!
|
||||||
execv("/init", argv);
|
execv("/init", argv);
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ typedef struct cpio_entry {
|
|||||||
// uint32_t namesize;
|
// uint32_t namesize;
|
||||||
// uint32_t check;
|
// uint32_t check;
|
||||||
char *filename;
|
char *filename;
|
||||||
char *data;
|
void *data;
|
||||||
int remove;
|
int remove;
|
||||||
} cpio_entry;
|
} cpio_entry;
|
||||||
|
|
||||||
|
@ -102,6 +102,7 @@ struct file_attr {
|
|||||||
|
|
||||||
int fd_getpath(int fd, char *path, size_t size);
|
int fd_getpath(int fd, char *path, size_t size);
|
||||||
int mkdir_p(const char *pathname, mode_t mode);
|
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 rm_rf(const char *path);
|
||||||
void frm_rf(int dirfd);
|
void frm_rf(int dirfd);
|
||||||
void mv_f(const char *source, const char *destination);
|
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);
|
void restorecon(int dirfd, int force);
|
||||||
int mmap_ro(const char *filename, void **buf, size_t *size);
|
int mmap_ro(const char *filename, void **buf, size_t *size);
|
||||||
int mmap_rw(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(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 stream_full_read(int fd, void **buf, size_t *size);
|
||||||
void write_zero(int fd, size_t size);
|
void write_zero(int fd, size_t size);
|
||||||
void mem_align(size_t *pos, size_t align);
|
void mem_align(size_t *pos, size_t align);
|
||||||
@ -142,7 +145,7 @@ void trim_img(const char *img);
|
|||||||
// pattern.c
|
// pattern.c
|
||||||
|
|
||||||
void patch_init_rc(void **buf, size_t *size);
|
void patch_init_rc(void **buf, size_t *size);
|
||||||
int patch_verity(char **buf, uint32_t *size, int patch);
|
int patch_verity(void **buf, uint32_t *size, int patch);
|
||||||
void patch_encryption(char **buf, uint32_t *size);
|
void patch_encryption(void **buf, uint32_t *size);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -78,7 +78,7 @@ static void dtb_patch(const char *file, int patch) {
|
|||||||
fdt_for_each_subnode(block, fdt, fstab) {
|
fdt_for_each_subnode(block, fdt, fstab) {
|
||||||
fprintf(stderr, "Found block [%s] in fstab\n", fdt_get_name(fdt, block, NULL));
|
fprintf(stderr, "Found block [%s] in fstab\n", fdt_get_name(fdt, block, NULL));
|
||||||
uint32_t value_size;
|
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);
|
found |= patch_verity(&value, &value_size, patch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,7 @@ static char *cpio_stocksha1(struct vector *v) {
|
|||||||
vec_for_each(v, f) {
|
vec_for_each(v, f) {
|
||||||
if (strcmp(f->filename, "init.magisk.rc") == 0
|
if (strcmp(f->filename, "init.magisk.rc") == 0
|
||||||
|| strcmp(f->filename, "overlay/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) {
|
if (memcmp(pos, "# STOCKSHA1=", 12) == 0) {
|
||||||
pos += 12;
|
pos += 12;
|
||||||
memcpy(sha1, pos, 40);
|
memcpy(sha1, pos, 40);
|
||||||
|
@ -17,13 +17,13 @@
|
|||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
char **excl_list = (char *[]) { NULL };
|
char **excl_list = NULL;
|
||||||
|
|
||||||
static int is_excl(const char *name) {
|
static int is_excl(const char *name) {
|
||||||
for (int i = 0; excl_list[i]; ++i) {
|
if (excl_list)
|
||||||
if (strcmp(name, excl_list[i]) == 0)
|
for (int i = 0; excl_list[i]; ++i)
|
||||||
return 1;
|
if (strcmp(name, excl_list[i]) == 0)
|
||||||
}
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,6 +55,36 @@ int mkdir_p(const char *pathname, mode_t mode) {
|
|||||||
return 0;
|
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) {
|
void rm_rf(const char *path) {
|
||||||
int fd = xopen(path, O_RDONLY | O_CLOEXEC);
|
int fd = xopen(path, O_RDONLY | O_CLOEXEC);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
@ -65,27 +95,7 @@ void rm_rf(const char *path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void frm_rf(int dirfd) {
|
void frm_rf(int dirfd) {
|
||||||
struct dirent *entry;
|
in_order_walk(dirfd, rm_cb);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This will only on the same file system */
|
/* 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);
|
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) {
|
void full_read(const char *filename, void **buf, size_t *size) {
|
||||||
int fd = xopen(filename, O_RDONLY);
|
int fd = xopen(filename, O_RDONLY);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
@ -367,10 +384,18 @@ void full_read(const char *filename, void **buf, size_t *size) {
|
|||||||
*size = 0;
|
*size = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
*size = lseek(fd, 0, SEEK_END);
|
fd_full_read(fd, buf, size);
|
||||||
lseek(fd, 0, SEEK_SET);
|
close(fd);
|
||||||
*buf = xmalloc(*size);
|
}
|
||||||
xxread(fd, *buf, *size);
|
|
||||||
|
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);
|
close(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,12 +58,12 @@ void patch_init_rc(void **buf, size_t *size) {
|
|||||||
*buf = new_data;
|
*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;
|
int skip, found = 0;
|
||||||
for (int pos = 0; pos < *size; ++pos) {
|
for (int pos = 0; pos < *size; ++pos) {
|
||||||
if ((skip = check_verity_pattern(*buf + pos)) > 0) {
|
if ((skip = check_verity_pattern(*buf + pos)) > 0) {
|
||||||
found = 1;
|
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) {
|
if (patch) {
|
||||||
memcpy(*buf + pos, *buf + pos + skip, *size - pos - skip);
|
memcpy(*buf + pos, *buf + pos + skip, *size - pos - skip);
|
||||||
memset(*buf + *size - skip, '\0', skip);
|
memset(*buf + *size - skip, '\0', skip);
|
||||||
@ -76,11 +76,11 @@ int patch_verity(char **buf, uint32_t *size, int patch) {
|
|||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
void patch_encryption(char **buf, uint32_t *size) {
|
void patch_encryption(void **buf, uint32_t *size) {
|
||||||
int skip;
|
int skip;
|
||||||
for (int pos = 0; pos < *size; ++pos) {
|
for (int pos = 0; pos < *size; ++pos) {
|
||||||
if ((skip = check_encryption_pattern(*buf + pos)) > 0) {
|
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, "encryptable", 11);
|
||||||
memcpy(*buf + pos + 11, *buf + pos + skip, *size - pos - skip);
|
memcpy(*buf + pos + 11, *buf + pos + skip, *size - pos - skip);
|
||||||
memset(*buf + *size - skip + 11, '\0', skip - 11);
|
memset(*buf + *size - skip + 11, '\0', skip - 11);
|
||||||
|
@ -64,7 +64,7 @@ BOOTIMAGE="$1"
|
|||||||
# Presets
|
# Presets
|
||||||
[ -z $KEEPVERITY ] && KEEPVERITY=false
|
[ -z $KEEPVERITY ] && KEEPVERITY=false
|
||||||
[ -z $KEEPFORCEENCRYPT ] && KEEPFORCEENCRYPT=false
|
[ -z $KEEPFORCEENCRYPT ] && KEEPFORCEENCRYPT=false
|
||||||
[ -z $HIGH_COMP ] && HIGH_COMP=false
|
[ -z $HIGHCOMP ] && HIGHCOMP=false
|
||||||
|
|
||||||
chmod -R 755 .
|
chmod -R 755 .
|
||||||
|
|
||||||
@ -89,7 +89,7 @@ case $? in
|
|||||||
2 )
|
2 )
|
||||||
ui_print "! Insufficient boot partition size detected"
|
ui_print "! Insufficient boot partition size detected"
|
||||||
ui_print "- Enable high compression mode"
|
ui_print "- Enable high compression mode"
|
||||||
HIGH_COMP=true
|
HIGHCOMP=true
|
||||||
;;
|
;;
|
||||||
3 )
|
3 )
|
||||||
ui_print "- ChromeOS boot image detected"
|
ui_print "- ChromeOS boot image detected"
|
||||||
@ -139,11 +139,10 @@ esac
|
|||||||
|
|
||||||
ui_print "- Patching ramdisk"
|
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-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
|
rm -f ramdisk.cpio.orig
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user