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