Update dtb patch to not use in-place modification

This commit is contained in:
topjohnwu 2019-09-21 05:30:04 -04:00
parent 120668c7bc
commit 4d91e50d6d
7 changed files with 86 additions and 98 deletions

View File

@ -6,6 +6,7 @@ extern "C" {
} }
#include <utils.h> #include <utils.h>
#include <bitset> #include <bitset>
#include <vector>
#include "magiskboot.h" #include "magiskboot.h"
#include "format.h" #include "format.h"
@ -19,29 +20,17 @@ static void pretty_node(int depth) {
if (depth == 0) if (depth == 0)
return; return;
for (int i = 0; i < depth - 1; ++i) { for (int i = 0; i < depth - 1; ++i)
if (depth_set[i]) printf(depth_set[i] ? "" : " ");
printf("");
else printf(depth_set[depth - 1] ? "├── " : "└── ");
printf(" ");
}
if (depth_set[depth - 1])
printf("├── ");
else
printf("└── ");
} }
static void pretty_prop(int depth) { static void pretty_prop(int depth) {
for (int i = 0; i < depth; ++i) { for (int i = 0; i < depth; ++i)
if (depth_set[i]) printf(depth_set[i] ? "" : " ");
printf("");
else printf(depth_set[depth] ? "" : " ");
printf(" ");
}
if (depth_set[depth])
printf("");
else
printf(" ");
} }
static void print_node(const void *fdt, int node = 0, int depth = 0) { static void print_node(const void *fdt, int node = 0, int depth = 0) {
@ -94,13 +83,13 @@ static void print_node(const void *fdt, int node = 0, int depth = 0) {
} }
} }
static int find_fstab(const void *fdt, int parent = 0) { static int find_fstab(const void *fdt, int node = 0) {
int node, fstab; if (fdt_get_name(fdt, node, nullptr) == "fstab"sv)
fdt_for_each_subnode(node, fdt, parent) { return node;
if (strcmp(fdt_get_name(fdt, node, nullptr), "fstab") == 0) int child;
return node; fdt_for_each_subnode(child, fdt, node) {
fstab = find_fstab(fdt, node); int fstab = find_fstab(fdt, child);
if (fstab != -1) if (fstab >= 0)
return fstab; return fstab;
} }
return -1; return -1;
@ -126,7 +115,7 @@ static void dtb_print(const char *file, bool fstab) {
fprintf(stderr, "Printing dtb.%04d\n", dtb_num); fprintf(stderr, "Printing dtb.%04d\n", dtb_num);
print_node(fdt); print_node(fdt);
} }
dtb_num++; ++dtb_num;
} }
} }
fprintf(stderr, "\n"); fprintf(stderr, "\n");
@ -134,44 +123,50 @@ static void dtb_print(const char *file, bool fstab) {
exit(0); exit(0);
} }
static void dtb_patch(const char *file, int patch) { static void dtb_patch(const char *in, const char *out) {
size_t size ; vector<uint8_t *> fdt_list;
uint8_t *dtb, *fdt; size_t dtb_sz ;
fprintf(stderr, "Loading dtbs from [%s]\n", file); uint8_t *dtb;
if (patch) fprintf(stderr, "Loading dtbs from [%s]\n", in);
mmap_rw(file, dtb, size); mmap_ro(in, dtb, dtb_sz);
else bool modified = false;
mmap_ro(file, dtb, size); for (int i = 0; i < dtb_sz; ++i) {
// Loop through all the dtbs
int dtb_num = 0;
bool found = false;
for (int i = 0; i < size; ++i) {
if (memcmp(dtb + i, DTB_MAGIC, 4) == 0) { if (memcmp(dtb + i, DTB_MAGIC, 4) == 0) {
fdt = dtb + i; // Patched will only be smaller
int fstab = find_fstab(fdt, 0); int len = fdt_totalsize(dtb + i);
if (fstab > 0) { auto fdt = static_cast<uint8_t *>(xmalloc(len));
fprintf(stderr, "Found fstab in dtb.%04d\n", dtb_num++); memcpy(fdt, dtb + i, len);
int block; int fstab = find_fstab(fdt);
fdt_for_each_subnode(block, fdt, fstab) { if (fstab < 0)
fprintf(stderr, "Found block [%s] in fstab\n", fdt_get_name(fdt, block, nullptr)); continue;
uint32_t value_size; fprintf(stderr, "Found fstab in dtb.%04d\n", fdt_list.size());
void *value = (void *) fdt_getprop(fdt, block, "fsmgr_flags", (int *)&value_size); int block;
if (patch) { fdt_for_each_subnode(block, fdt, fstab) {
void *dup = xmalloc(value_size); fprintf(stderr, "Found entry [%s] in fstab\n", fdt_get_name(fdt, block, nullptr));
memcpy(dup, value, value_size); uint32_t size;
memset(value, 0, value_size); auto value = static_cast<const char *>(
found |= patch_verity(&dup, &value_size); fdt_getprop(fdt, block, "fsmgr_flags", reinterpret_cast<int *>(&size)));
memcpy(value, dup, value_size); char *pval = patch_verity(value, size);
free(dup); if (pval) {
} else { modified = true;
found |= patch_verity(&value, &value_size, false); fdt_setprop_string(fdt, block, "fsmgr_flags", pval);
}
} }
} }
fdt_list.push_back(fdt);
} }
} }
munmap(dtb, size); munmap(dtb, dtb_sz);
exit(!found); if (modified) {
if (!out)
out = in;
int fd = xopen(out, O_WRONLY | O_CREAT | O_CLOEXEC);
for (auto fdt : fdt_list) {
fdt_pack(fdt);
xwrite(fd, fdt, fdt_totalsize(fdt));
}
close(fd);
}
exit(!modified);
} }
int dtb_commands(int argc, char *argv[]) { int dtb_commands(int argc, char *argv[]) {
@ -182,9 +177,7 @@ int dtb_commands(int argc, char *argv[]) {
if (argv[0] == "print"sv) { if (argv[0] == "print"sv) {
dtb_print(dtb, argc > 1 && argv[1] == "-f"sv); dtb_print(dtb, argc > 1 && argv[1] == "-f"sv);
} else if (argv[0] == "patch"sv) { } else if (argv[0] == "patch"sv) {
dtb_patch(dtb, 1); dtb_patch(dtb, argv[1]);
} else if (argv[0] == "test"sv) {
dtb_patch(dtb, 0);
} else { } else {
return 1; return 1;
} }

View File

@ -20,5 +20,5 @@ int cpio_commands(int argc, char *argv[]);
int dtb_commands(int argc, char *argv[]); int dtb_commands(int argc, char *argv[]);
// Pattern // Pattern
bool patch_verity(void **buf, uint32_t *size, bool patch = true); char *patch_verity(const void *buf, uint32_t &size);
void patch_encryption(void **buf, uint32_t *size); void patch_encryption(void **buf, uint32_t *size);

View File

@ -70,18 +70,15 @@ Supported actions:
sha1 sha1
Print stock boot SHA1 if previously backed up in ramdisk Print stock boot SHA1 if previously backed up in ramdisk
dtb <dtb> <command> [args...] dtb <input> <action> [args...]
Do commands to <dtb> (modifications are done directly) Do dtb related actions to <input>
Supported commands: Supported actions:
print [-f] print [-f]
Print all contents from dtb for debugging Print all contents of dtb for debugging
Specify [-f] to only print fstab nodes Specify [-f] to only print fstab nodes
test patch [OUT]
Check if fstab has verity/avb flags
Return values:
0:flag exists 1:no flags
patch
Search for fstab and remove verity/avb Search for fstab and remove verity/avb
If [OUT] is not specified, it will directly output to <input>
compress[=method] <infile> [outfile] compress[=method] <infile> [outfile]
Compress <infile> with [method] (default: gzip), optionally to [outfile] Compress <infile> with [method] (default: gzip), optionally to [outfile]

View File

@ -22,7 +22,7 @@ static int check_verity_pattern(const char *s) {
} }
static int check_encryption_pattern(const char *s) { static int check_encryption_pattern(const char *s) {
const char *encrypt_list[] = { "forceencrypt", "forcefdeorfbe", NULL }; const char *encrypt_list[] = { "forceencrypt", "forcefdeorfbe", nullptr };
for (int i = 0 ; encrypt_list[i]; ++i) { for (int i = 0 ; encrypt_list[i]; ++i) {
int len = strlen(encrypt_list[i]); int len = strlen(encrypt_list[i]);
if (strncmp(s, encrypt_list[i], len) == 0) if (strncmp(s, encrypt_list[i], len) == 0)
@ -31,29 +31,23 @@ static int check_encryption_pattern(const char *s) {
return -1; return -1;
} }
bool patch_verity(void **buf, uint32_t *size, bool patch) { char *patch_verity(const void *buf, uint32_t &size) {
int skip, src_size = *size; auto src = static_cast<const char *>(buf);
int src_size = size;
bool found = false; bool found = false;
char *src = (char *) *buf, *patched = patch ? (char *) xcalloc(src_size, 1) : nullptr; char patched[4096];
for (int read = 0, write = 0; read < src_size; ++read, ++write) { int write = 0;
if ((skip = check_verity_pattern(src + read)) > 0) { for (int read = 0; read < src_size; ++read, ++write) {
if (patch) { if (int skip; (skip = check_verity_pattern(src + read)) > 0) {
fprintf(stderr, "Remove pattern [%.*s]\n", skip, src + read); fprintf(stderr, "Found pattern [%.*s]\n", skip, src + read);
*size -= skip; size -= skip;
} else {
fprintf(stderr, "Found pattern [%.*s]\n", skip, src + read);
}
read += skip; read += skip;
found = true; found = true;
} }
if (patch) patched[write] = src[read];
patched[write] = src[read];
} }
if (patch) { patched[write] = '\0';
free(*buf); return found ? strdup(patched) : nullptr;
*buf = patched;
}
return found;
} }
void patch_encryption(void **buf, uint32_t *size) { void patch_encryption(void **buf, uint32_t *size) {

View File

@ -46,7 +46,9 @@ void magisk_cpio::patch(bool keepverity, bool keepforceencrypt) {
str_contains(cur->first, "fstab") && S_ISREG(cur->second->mode); str_contains(cur->first, "fstab") && S_ISREG(cur->second->mode);
if (!keepverity) { if (!keepverity) {
if (fstab) { if (fstab) {
patch_verity(&cur->second->data, &cur->second->filesize); auto buf = patch_verity(cur->second->data, cur->second->filesize);
free(cur->second->data);
cur->second->data = buf;
} else if (cur->first == "verity_key") { } else if (cur->first == "verity_key") {
rm(cur); rm(cur);
continue; continue;

View File

@ -158,7 +158,7 @@ rm -f ramdisk.cpio.orig config
if ! $KEEPVERITY; then if ! $KEEPVERITY; then
for dt in dtb kernel_dtb extra recovery_dtbo; do for dt in dtb kernel_dtb extra recovery_dtbo; do
[ -f $dt ] && ./magiskboot dtb-patch $dt && ui_print "- Removing dm(avb)-verity in $dt" [ -f $dt ] && ./magiskboot dtb $dt patch && ui_print "- Removing dm(avb)-verity in $dt"
done done
fi fi

View File

@ -280,11 +280,13 @@ patch_dtbo_image() {
find_dtbo_image find_dtbo_image
if [ ! -z $DTBOIMAGE ]; then if [ ! -z $DTBOIMAGE ]; then
ui_print "- DTBO image: $DTBOIMAGE" ui_print "- DTBO image: $DTBOIMAGE"
if $MAGISKBIN/magiskboot --dtb-test $DTBOIMAGE; then local PATCHED=$TMPDIR/dtbo
if $MAGISKBIN/magiskboot dtb $DTBOIMAGE patch $PATCHED; then
ui_print "- Backing up stock DTBO image" ui_print "- Backing up stock DTBO image"
$MAGISKBIN/magiskboot --compress $DTBOIMAGE $MAGISKBIN/stock_dtbo.img.gz $MAGISKBIN/magiskboot compress $DTBOIMAGE $MAGISKBIN/stock_dtbo.img.gz
ui_print "- Patching DTBO to remove avb-verity" ui_print "- Patching DTBO to remove avb-verity"
$MAGISKBIN/magiskboot --dtb-patch $DTBOIMAGE cat $PATCHED /dev/zero > $DTBOIMAGE
rm -f $PATCHED
return 0 return 0
fi fi
fi fi