mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-12-22 07:57:39 +00:00
Cleanup cpio codebase
This commit is contained in:
parent
feb44f875e
commit
57afae3425
@ -463,11 +463,21 @@ bool byte_data::contains(string_view pattern, bool log) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool byte_data::equals(const byte_data &o) const {
|
||||
return sz == o.sz && memcmp(buf, o.buf, sz) == 0;
|
||||
}
|
||||
|
||||
void byte_data::swap(byte_data &o) {
|
||||
std::swap(buf, o.buf);
|
||||
std::swap(sz, o.sz);
|
||||
}
|
||||
|
||||
heap_data byte_data::clone() const {
|
||||
heap_data copy(sz);
|
||||
memcpy(copy.buf, buf, sz);
|
||||
return copy;
|
||||
}
|
||||
|
||||
mmap_data::mmap_data(const char *name, bool rw) {
|
||||
int fd = xopen(name, (rw ? O_RDWR : O_RDONLY) | O_CLOEXEC);
|
||||
if (fd < 0)
|
||||
|
@ -43,15 +43,23 @@ struct mount_info {
|
||||
std::string fs_option;
|
||||
};
|
||||
|
||||
struct heap_data;
|
||||
|
||||
struct byte_data {
|
||||
using str_pairs = std::initializer_list<std::pair<std::string_view, std::string_view>>;
|
||||
|
||||
uint8_t *buf = nullptr;
|
||||
size_t sz = 0;
|
||||
uint8_t *buf;
|
||||
size_t sz;
|
||||
|
||||
byte_data() : buf(nullptr), sz(0) {}
|
||||
byte_data(void *buf, size_t sz) : buf(static_cast<uint8_t *>(buf)), sz(sz) {}
|
||||
explicit byte_data(std::string_view str) : buf((uint8_t *) str.data()), sz(str.length()) {}
|
||||
|
||||
int patch(str_pairs list) { return patch(true, list); }
|
||||
int patch(bool log, str_pairs list);
|
||||
bool contains(std::string_view pattern, bool log = true) const;
|
||||
bool equals(const byte_data &o) const;
|
||||
heap_data clone() const;
|
||||
protected:
|
||||
void swap(byte_data &o);
|
||||
};
|
||||
@ -65,7 +73,8 @@ clazz& operator=(clazz &&o) { swap(o); return *this; }
|
||||
struct heap_data : public byte_data {
|
||||
MOVE_ONLY(heap_data)
|
||||
|
||||
explicit heap_data(size_t sz) { this->sz = sz; buf = new uint8_t[sz]; }
|
||||
explicit heap_data(size_t sz) : byte_data(new uint8_t[sz], sz) {}
|
||||
heap_data(const void *buf, size_t sz) : heap_data(sz) { memcpy(this->buf, buf, sz); }
|
||||
~heap_data() { delete[] buf; }
|
||||
};
|
||||
|
||||
|
@ -43,11 +43,13 @@ static uint32_t x8u(const char *hex) {
|
||||
return val;
|
||||
}
|
||||
|
||||
cpio_entry::cpio_entry(uint32_t mode) : mode(mode), uid(0), gid(0), filesize(0), data(nullptr) {}
|
||||
cpio_entry::cpio_entry(uint32_t mode) : mode(mode), uid(0), gid(0), data(0) {}
|
||||
|
||||
cpio_entry::cpio_entry(uint32_t mode, const byte_data &data) :
|
||||
mode(mode), uid(0), gid(0), data(data.clone()) {}
|
||||
|
||||
cpio_entry::cpio_entry(const cpio_newc_header *h) :
|
||||
mode(x8u(h->mode)), uid(x8u(h->uid)), gid(x8u(h->gid)), filesize(x8u(h->filesize)), data(nullptr)
|
||||
{}
|
||||
mode(x8u(h->mode)), uid(x8u(h->uid)), gid(x8u(h->gid)), data(x8u(h->filesize)) {}
|
||||
|
||||
void cpio::dump(const char *file) {
|
||||
fprintf(stderr, "Dump cpio: [%s]\n", file);
|
||||
@ -87,13 +89,13 @@ static void extract_entry(const cpio::entry_map::value_type &e, const char *file
|
||||
xmkdir(file, e.second->mode & 0777);
|
||||
} else if (S_ISREG(e.second->mode)) {
|
||||
int fd = xopen(file, O_CREAT | O_WRONLY | O_TRUNC, e.second->mode & 0777);
|
||||
xwrite(fd, e.second->data, e.second->filesize);
|
||||
xwrite(fd, e.second->data.buf, e.second->data.sz);
|
||||
fchown(fd, e.second->uid, e.second->gid);
|
||||
close(fd);
|
||||
} else if (S_ISLNK(e.second->mode) && e.second->filesize < 4096) {
|
||||
} else if (S_ISLNK(e.second->mode) && e.second->data.sz < 4096) {
|
||||
char target[4096];
|
||||
memcpy(target, e.second->data, e.second->filesize);
|
||||
target[e.second->filesize] = '\0';
|
||||
memcpy(target, e.second->data.buf, e.second->data.sz);
|
||||
target[e.second->data.sz] = '\0';
|
||||
symlink(target, file);
|
||||
}
|
||||
}
|
||||
@ -132,7 +134,7 @@ void cpio::dump(FILE *out) {
|
||||
e.second->gid,
|
||||
1, // e->nlink
|
||||
0, // e->mtime
|
||||
e.second->filesize,
|
||||
(uint32_t) e.second->data.sz,
|
||||
0, // e->devmajor
|
||||
0, // e->devminor
|
||||
0, // e->rdevmajor
|
||||
@ -143,8 +145,8 @@ void cpio::dump(FILE *out) {
|
||||
do_out(header, 110);
|
||||
do_out(e.first.data(), e.first.size() + 1);
|
||||
out_align();
|
||||
if (e.second->filesize) {
|
||||
do_out(e.second->data, e.second->filesize);
|
||||
if (e.second->data.sz) {
|
||||
do_out(e.second->data.buf, e.second->data.sz);
|
||||
out_align();
|
||||
}
|
||||
}
|
||||
@ -173,11 +175,8 @@ void cpio::insert(string_view name, cpio_entry *e) {
|
||||
}
|
||||
|
||||
void cpio::add(mode_t mode, const char *name, const char *file) {
|
||||
auto m = mmap_data(file);
|
||||
auto e = new cpio_entry(S_IFREG | mode);
|
||||
e->filesize = m.sz;
|
||||
e->data = malloc(m.sz);
|
||||
memcpy(e->data, m.buf, m.sz);
|
||||
mmap_data m(file);
|
||||
auto e = new cpio_entry(S_IFREG | mode, m);
|
||||
insert(name, e);
|
||||
fprintf(stderr, "Add entry [%s] (%04o)\n", name, mode);
|
||||
}
|
||||
@ -188,9 +187,8 @@ void cpio::mkdir(mode_t mode, const char *name) {
|
||||
}
|
||||
|
||||
void cpio::ln(const char *target, const char *name) {
|
||||
auto e = new cpio_entry(S_IFLNK);
|
||||
e->filesize = strlen(target);
|
||||
e->data = strdup(target);
|
||||
byte_data link(target);
|
||||
auto e = new cpio_entry(S_IFLNK, link);
|
||||
insert(name, e);
|
||||
fprintf(stderr, "Create symlink [%s] -> [%s]\n", name, target);
|
||||
}
|
||||
@ -236,9 +234,8 @@ void cpio::load_cpio(const char *buf, size_t sz) {
|
||||
continue;
|
||||
}
|
||||
auto entry = new cpio_entry(hdr);
|
||||
entry->data = malloc(entry->filesize);
|
||||
memcpy(entry->data, buf + pos, entry->filesize);
|
||||
pos += entry->filesize;
|
||||
memcpy(entry->data.buf, buf + pos, entry->data.sz);
|
||||
pos += entry->data.sz;
|
||||
insert(name, entry);
|
||||
pos_align(pos);
|
||||
}
|
||||
|
@ -6,18 +6,19 @@
|
||||
#include <map>
|
||||
#include <string_view>
|
||||
|
||||
#include <base.hpp>
|
||||
|
||||
struct cpio_newc_header;
|
||||
|
||||
struct cpio_entry {
|
||||
uint32_t mode;
|
||||
uint32_t uid;
|
||||
uint32_t gid;
|
||||
uint32_t filesize;
|
||||
void *data;
|
||||
heap_data data;
|
||||
|
||||
explicit cpio_entry(uint32_t mode = 0);
|
||||
explicit cpio_entry(uint32_t mode);
|
||||
explicit cpio_entry(uint32_t mode, const byte_data &data);
|
||||
explicit cpio_entry(const cpio_newc_header *h);
|
||||
~cpio_entry() { free(data); }
|
||||
};
|
||||
|
||||
class cpio {
|
||||
|
@ -150,7 +150,8 @@ static bool dtb_patch(const char *file) {
|
||||
fdt_for_each_subnode(node, fdt, fstab) {
|
||||
int len;
|
||||
char *value = (char *) fdt_getprop(fdt, node, "fsmgr_flags", &len);
|
||||
patched |= patch_verity(value, len) != len;
|
||||
byte_data data(value, len);
|
||||
patched |= patch_verity(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -221,12 +222,11 @@ static bool fdt_patch(void *fdt) {
|
||||
const char *name = fdt_get_name(fdt, node, nullptr);
|
||||
// Force remove AVB for 2SI since it may bootloop some devices
|
||||
int len;
|
||||
auto value = (const char *) fdt_getprop(fdt, node, "fsmgr_flags", &len);
|
||||
string copy(value, len);
|
||||
uint32_t new_len = patch_verity(copy.data(), len);
|
||||
if (new_len != len) {
|
||||
const void *value = fdt_getprop(fdt, node, "fsmgr_flags", &len);
|
||||
heap_data copy(value, len);
|
||||
if (patch_verity(copy)) {
|
||||
modified = true;
|
||||
fdt_setprop(fdt, node, "fsmgr_flags", copy.data(), new_len);
|
||||
fdt_setprop(fdt, node, "fsmgr_flags", copy.buf, copy.sz);
|
||||
}
|
||||
if (name == "system"sv) {
|
||||
fprintf(stderr, "Setting [mnt_point] to [/system_root]\n");
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <base.hpp>
|
||||
|
||||
#include "boot-rs.hpp"
|
||||
|
||||
#define HEADER_FILE "header"
|
||||
@ -21,6 +23,7 @@ int hexpatch(const char *file, const char *from, const char *to);
|
||||
int cpio_commands(int argc, char *argv[]);
|
||||
int dtb_commands(int argc, char *argv[]);
|
||||
|
||||
uint32_t patch_verity(void *buf, uint32_t size);
|
||||
uint32_t patch_encryption(void *buf, uint32_t size);
|
||||
bool patch_verity(byte_data &data);
|
||||
bool patch_encryption(byte_data &data);
|
||||
|
||||
bool check_env(const char *name);
|
||||
|
@ -39,26 +39,28 @@ static int skip_encryption_pattern(const char *s) {
|
||||
return skip;
|
||||
}
|
||||
|
||||
static uint32_t remove_pattern(char *src, uint32_t size, int(*pattern_skip)(const char *)) {
|
||||
int orig_sz = size;
|
||||
static bool remove_pattern(byte_data &data, int(*pattern_skip)(const char *)) {
|
||||
char *src = reinterpret_cast<char *>(data.buf);
|
||||
size_t orig_sz = data.sz;
|
||||
int write = 0;
|
||||
for (int read = 0; read < orig_sz;) {
|
||||
int read = 0;
|
||||
while (read < orig_sz) {
|
||||
if (int skip = pattern_skip(src + read); skip > 0) {
|
||||
fprintf(stderr, "Remove pattern [%.*s]\n", skip, src + read);
|
||||
size -= skip;
|
||||
data.sz -= skip;
|
||||
read += skip;
|
||||
} else {
|
||||
src[write++] = src[read++];
|
||||
}
|
||||
}
|
||||
memset(src + write, 0, orig_sz - write);
|
||||
return size;
|
||||
return data.sz != orig_sz;
|
||||
}
|
||||
|
||||
uint32_t patch_verity(void *buf, uint32_t size) {
|
||||
return remove_pattern(static_cast<char *>(buf), size, skip_verity_pattern);
|
||||
bool patch_verity(byte_data &data) {
|
||||
return remove_pattern(data, skip_verity_pattern);
|
||||
}
|
||||
|
||||
uint32_t patch_encryption(void *buf, uint32_t size) {
|
||||
return remove_pattern(static_cast<char *>(buf), size, skip_encryption_pattern);
|
||||
bool patch_encryption(byte_data &data) {
|
||||
return remove_pattern(data, skip_encryption_pattern);
|
||||
}
|
||||
|
@ -44,16 +44,14 @@ void magisk_cpio::patch() {
|
||||
if (!keepverity) {
|
||||
if (fstab) {
|
||||
fprintf(stderr, "Found fstab file [%s]\n", cur->first.data());
|
||||
cur->second->filesize = patch_verity(cur->second->data, cur->second->filesize);
|
||||
patch_verity(cur->second->data);
|
||||
} else if (cur->first == "verity_key") {
|
||||
rm(cur);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!keepforceencrypt) {
|
||||
if (fstab) {
|
||||
cur->second->filesize = patch_encryption(cur->second->data, cur->second->filesize);
|
||||
}
|
||||
if (!keepforceencrypt && fstab) {
|
||||
patch_encryption(cur->second->data);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -113,7 +111,7 @@ void magisk_cpio::restore() {
|
||||
rm(bk);
|
||||
rm(mg);
|
||||
if (rl != entries.end()) {
|
||||
for_each_str(file, rl->second->data, rl->second->filesize) {
|
||||
for_each_str(file, rl->second->data.buf, rl->second->data.sz) {
|
||||
rm(file);
|
||||
}
|
||||
rm(rl);
|
||||
@ -158,8 +156,7 @@ void magisk_cpio::backup(const char *orig) {
|
||||
do_backup = true;
|
||||
fprintf(stderr, "Backup missing entry: ");
|
||||
} else if (res == 0) {
|
||||
if (lhs->second->filesize != rhs->second->filesize ||
|
||||
memcmp(lhs->second->data, rhs->second->data, lhs->second->filesize) != 0) {
|
||||
if (!lhs->second->data.equals(rhs->second->data)) {
|
||||
// Not the same!
|
||||
do_backup = true;
|
||||
fprintf(stderr, "Backup mismatch entry: ");
|
||||
@ -189,10 +186,8 @@ void magisk_cpio::backup(const char *orig) {
|
||||
}
|
||||
|
||||
if (!rm_list.empty()) {
|
||||
auto rm_list_file = new cpio_entry(S_IFREG);
|
||||
rm_list_file->filesize = rm_list.length();
|
||||
rm_list_file->data = malloc(rm_list.length());
|
||||
memcpy(rm_list_file->data, rm_list.data(), rm_list.length());
|
||||
byte_data rm(rm_list);
|
||||
auto rm_list_file = new cpio_entry(S_IFREG, rm);
|
||||
backups.emplace(".backup/.rmlist", rm_list_file);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user