Compare commits

...

17 Commits
v14.6 ... v15.2

Author SHA1 Message Date
topjohnwu
4fd61345af Happy New Year 2018-01-02 01:27:20 +08:00
topjohnwu
66cca24453 Samsung need more rules :) 2018-01-02 00:11:26 +08:00
topjohnwu
e733484fab Some devices don't like all log buffers 2018-01-01 23:58:13 +08:00
topjohnwu
e5c3183025 Update scripts 2018-01-01 16:46:28 +08:00
topjohnwu
930c82316a Slightly change logging style 2017-12-31 21:54:39 +08:00
Shaka Huang
3dc22db265 Support loading split sepolicy on non skip_initramfs devices
For certain device (e.g ZenFone 4 ZE554KL) there’s no sepolicy under rootfs and no a/b partition (implies no vendor partition) Magisk will failed to patch SELinux policy database and the system won’t boot up.

In order to cope with this configuration the status of loading policy db needs to be checked, once it failed we have to mount the system partition and do patch_sepolicy() again.

Signed-off-by: Shaka Huang <shakalaca@gmail.com>
2017-12-31 21:30:56 +08:00
topjohnwu
d8c51cb286 Update sepolicy handling 2017-12-31 19:32:04 +08:00
topjohnwu
2f79d0c3b3 Fix segfault while patching dtb 2017-12-31 19:30:56 +08:00
topjohnwu
d8bb3af06b Miscellaneous 2017-12-29 04:25:30 +08:00
topjohnwu
e139e8777b Fix faulty magiskboot ramdisk patch code 2017-12-29 04:25:03 +08:00
topjohnwu
d52d7cfbd9 Update magiskpolicy 2017-12-26 04:24:48 +08:00
topjohnwu
4f74a259e3 Update Magisk Manager 2017-12-26 04:00:01 +08:00
topjohnwu
74da6e1dc0 Support new 1500 template 2017-12-26 03:23:58 +08:00
topjohnwu
84ffdf0ed5 Eliminate a possbility to cause segfault 2017-12-25 05:21:40 +08:00
topjohnwu
022b18c8ce Properly detect /data status 2017-12-25 05:21:40 +08:00
topjohnwu
b92b1dcddb cil: Allow redeclare types[attributes] and disable neverallow 2017-12-25 05:21:40 +08:00
topjohnwu
1472dbb291 Add cache magisk image merging support 2017-12-22 16:10:38 +08:00
23 changed files with 204 additions and 123 deletions

View File

@@ -43,12 +43,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
**MagiskManager** (`app`) **MagiskManager** (`app`)
* Copyright 2016-2017, John Wu (@topjohnwu) * Copyright 2016-2018, John Wu (@topjohnwu)
* All contributors and translators on Github * All contributors and translators on Github
**MagiskSU** (`core/jni/su`) **MagiskSU** (`core/jni/su`)
* Copyright 2016-2017, John Wu (@topjohnwu) * Copyright 2016-2018, John Wu (@topjohnwu)
* Copyright 2015, Pierre-Hugues Husson (phh@phh.me) * Copyright 2015, Pierre-Hugues Husson (phh@phh.me)
* Copyright 2013, Koushik Dutta (@koush) * Copyright 2013, Koushik Dutta (@koush)
* Copyright 2010, Adam Shanks (@ChainsDD) * Copyright 2010, Adam Shanks (@ChainsDD)
@@ -56,18 +56,18 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
**MagiskPolicy** (`core/jni/magiskpolicy`) **MagiskPolicy** (`core/jni/magiskpolicy`)
* Copyright 2016-2017, John Wu (@topjohnwu) * Copyright 2016-2018, John Wu (@topjohnwu)
* Copyright 2015, Pierre-Hugues Husson (phh@phh.me) * Copyright 2015, Pierre-Hugues Husson (phh@phh.me)
* Copyright 2015, Joshua Brindle (@joshua_brindle) * Copyright 2015, Joshua Brindle (@joshua_brindle)
**MagiskHide** (`core/jni/magiskhide`) **MagiskHide** (`core/jni/magiskhide`)
* Copyright 2016-2017, John Wu (@topjohnwu) * Copyright 2016-2018, John Wu (@topjohnwu)
* Copyright 2016, Pierre-Hugues Husson (phh@phh.me) * Copyright 2016, Pierre-Hugues Husson (phh@phh.me)
**resetprop** (`core/jni/resetprop`) **resetprop** (`core/jni/resetprop`)
* Copyright 2016-2017 John Wu (@topjohnwu) * Copyright 2016-2018 John Wu (@topjohnwu)
* Copyright 2016 nkk71 (nkk71x@gmail.com) * Copyright 2016 nkk71 (nkk71x@gmail.com)
**External Dependencies** (`core/jni/external`) **External Dependencies** (`core/jni/external`)
@@ -78,4 +78,4 @@ All of them are either GPL or GPL compatible.
**Others Not Mentioned** **Others Not Mentioned**
* Copyright 2016-2017, John Wu (@topjohnwu) * Copyright 2016-2018, John Wu (@topjohnwu)

2
app

Submodule app updated: 0d9527921a...2e02af994e

View File

@@ -274,7 +274,7 @@ static void clone_skeleton(struct node_entry *node) {
char *con; char *con;
xstat(full_path, &s); xstat(full_path, &s);
getfilecon(full_path, &con); getfilecon(full_path, &con);
LOGI("tmpfs: %s\n", full_path); LOGI("mnt_tmpfs : %s\n", full_path);
xmount("tmpfs", full_path, "tmpfs", 0, NULL); xmount("tmpfs", full_path, "tmpfs", 0, NULL);
chmod(full_path, s.st_mode & 0777); chmod(full_path, s.st_mode & 0777);
chown(full_path, s.st_uid, s.st_gid); chown(full_path, s.st_uid, s.st_gid);
@@ -295,7 +295,7 @@ static void clone_skeleton(struct node_entry *node) {
if (child->parent->parent == NULL && strcmp(child->name, "vendor") == 0) { if (child->parent->parent == NULL && strcmp(child->name, "vendor") == 0) {
if (IS_LNK(child)) { if (IS_LNK(child)) {
cp_afc(MIRRDIR "/system/vendor", "/system/vendor"); cp_afc(MIRRDIR "/system/vendor", "/system/vendor");
LOGI("cplink: %s -> %s\n", MIRRDIR "/system/vendor", "/system/vendor"); LOGI("creat_link: %s <- %s\n", "/system/vendor", MIRRDIR "/system/vendor");
} }
// Skip // Skip
continue; continue;
@@ -315,9 +315,9 @@ static void clone_skeleton(struct node_entry *node) {
// Copy symlinks directly // Copy symlinks directly
cp_afc(buf2, buf); cp_afc(buf2, buf);
#ifdef MAGISK_DEBUG #ifdef MAGISK_DEBUG
LOGI("cplink: %s -> %s\n",buf2, buf); LOGI("creat_link: %s <- %s\n",buf, buf2);
#else #else
LOGI("cplink: %s\n", buf); LOGI("creat_link: %s\n", buf);
#endif #endif
} else { } else {
snprintf(buf, PATH_MAX, "%s/%s", full_path, child->name); snprintf(buf, PATH_MAX, "%s/%s", full_path, child->name);
@@ -392,11 +392,16 @@ static void simple_mount(const char *path) {
* Miscellaneous * * Miscellaneous *
*****************/ *****************/
#define alt_img ((char *[]) \
{ "/cache/magisk.img", "/data/magisk_merge.img", "/data/adb/magisk_merge.img", NULL })
static int prepare_img() { static int prepare_img() {
// First merge images // Merge images
if (merge_img("/data/magisk_merge.img", MAINIMG)) { for (int i = 0; alt_img[i]; ++i) {
LOGE("Image merge /data/magisk_merge.img -> " MAINIMG " failed!\n"); if (merge_img(alt_img[i], MAINIMG)) {
return 1; LOGE("Image merge %s -> " MAINIMG " failed!\n", alt_img[i]);
return 1;
}
} }
if (access(MAINIMG, F_OK) == -1) { if (access(MAINIMG, F_OK) == -1) {
@@ -493,7 +498,7 @@ void post_fs_data(int client) {
// ack // ack
write_int(client, 0); write_int(client, 0);
close(client); close(client);
if (!check_data()) if (!is_daemon_init && !check_data())
goto unblock; goto unblock;
// Start the debug log // Start the debug log

View File

@@ -129,11 +129,6 @@ void daemon_init() {
unlink("/data/magisk_debug.log"); unlink("/data/magisk_debug.log");
chmod("/data/adb", 0700); chmod("/data/adb", 0700);
// Use shell glob to match files
exec_command_sync("sh", "-c",
"mv -f /data/adb/magisk/stock_*.img.gz /data;"
"rm -f /data/user*/*/magisk.db;", NULL);
LOGI("* Creating /sbin overlay"); LOGI("* Creating /sbin overlay");
DIR *dir; DIR *dir;
struct dirent *entry; struct dirent *entry;

View File

@@ -55,7 +55,7 @@ static void *logger_thread(void *args) {
while (1) { while (1) {
// Start logcat // Start logcat
log_pid = exec_command(0, &log_fd, NULL, "logcat", "-b", "all" , "-v", "threadtime", "-s", "am_proc_start", "Magisk", NULL); log_pid = exec_command(0, &log_fd, NULL, "logcat", "-b", "events", "-b", "main", "-v", "threadtime", "-s", "am_proc_start", "-s", "Magisk", NULL);
while (fdgets(line, sizeof(line), log_fd)) { while (fdgets(line, sizeof(line), log_fd)) {
for (int i = 0; i < (sizeof(log_events) / sizeof(struct log_listener)); ++i) { for (int i = 0; i < (sizeof(log_events) / sizeof(struct log_listener)); ++i) {
if (log_events[i].fd > 0 && log_events[i].filter(line)) { if (log_events[i].fd > 0 && log_events[i].filter(line)) {
@@ -74,7 +74,7 @@ static void *logger_thread(void *args) {
waitpid(log_pid, NULL, 0); waitpid(log_pid, NULL, 0);
// Clear buffer before restart // Clear buffer before restart
exec_command_sync("logcat", "-b", "all", "-c", NULL); exec_command_sync("logcat", "-b", "events", "-b", "main", "-c", NULL);
} }
// Should never be here, but well... // Should never be here, but well...
@@ -82,8 +82,6 @@ static void *logger_thread(void *args) {
} }
static void *magisk_log_thread(void *args) { static void *magisk_log_thread(void *args) {
int have_data = 0;
// Buffer logs before we have data access // Buffer logs before we have data access
struct vector logs; struct vector logs;
vec_init(&logs); vec_init(&logs);
@@ -97,10 +95,12 @@ static void *magisk_log_thread(void *args) {
LOGD("log_monitor: magisk log dumper start"); LOGD("log_monitor: magisk log dumper start");
FILE *log; FILE *log = NULL;
for (char *line; xxread(pipefd[0], &line, sizeof(line)) > 0; free(line)) { for (char *line; xxread(pipefd[0], &line, sizeof(line)) > 0; free(line)) {
if (!have_data) { if (!is_daemon_init) {
if ((have_data = check_data())) { vec_push_back(&logs, strdup(line));
} else {
if (log == NULL) {
// Dump buffered logs to file // Dump buffered logs to file
log = xfopen(LOGFILE, "w"); log = xfopen(LOGFILE, "w");
setbuf(log, NULL); setbuf(log, NULL);
@@ -110,12 +110,9 @@ static void *magisk_log_thread(void *args) {
free(tmp); free(tmp);
} }
vec_destroy(&logs); vec_destroy(&logs);
} else {
vec_push_back(&logs, strdup(line));
} }
}
if (have_data)
fprintf(log, "%s", line); fprintf(log, "%s", line);
}
} }
return NULL; return NULL;
} }

View File

@@ -220,6 +220,8 @@ static int compile_cil() {
cil_db_init(&db); cil_db_init(&db);
cil_set_mls(db, 1); cil_set_mls(db, 1);
cil_set_multiple_decls(db, 1);
cil_set_disable_neverallow(db, 1);
cil_set_target_platform(db, SEPOL_TARGET_SELINUX); cil_set_target_platform(db, SEPOL_TARGET_SELINUX);
cil_set_policy_version(db, POLICYDB_VERSION_XPERMS_IOCTL); cil_set_policy_version(db, POLICYDB_VERSION_XPERMS_IOCTL);
cil_set_attrs_expand_generated(db, 0); cil_set_attrs_expand_generated(db, 0);
@@ -303,16 +305,20 @@ static int verify_precompiled() {
return strcmp(sys_sha, ven_sha) == 0; return strcmp(sys_sha, ven_sha) == 0;
} }
static void patch_sepolicy() { static int patch_sepolicy() {
if (access("/sepolicy", R_OK) == 0) if (access("/sepolicy", R_OK) == 0)
load_policydb("/sepolicy"); load_policydb("/sepolicy");
else if (access(SPLIT_PRECOMPILE, R_OK) == 0 && verify_precompiled()) else if (access(SPLIT_PRECOMPILE, R_OK) == 0 && verify_precompiled())
load_policydb(SPLIT_PRECOMPILE); load_policydb(SPLIT_PRECOMPILE);
else if (access(SPLIT_PLAT_CIL, R_OK) == 0) else if (access(SPLIT_PLAT_CIL, R_OK) == 0)
compile_cil(); compile_cil();
else
return 1;
sepol_magisk_rules(); sepol_magisk_rules();
dump_policydb("/sepolicy"); dump_policydb("/sepolicy");
return 0;
} }
#define BUFSIZE (1 << 20) #define BUFSIZE (1 << 20)
@@ -362,7 +368,8 @@ static void magisk_init_daemon() {
sepol_allow("su", ALL, ALL, ALL); sepol_allow("su", ALL, ALL, ALL);
// Wait till init cold boot done // Wait till init cold boot done
wait_till_exists("/dev/.coldboot_done"); while (access("/dev/.coldboot_done", F_OK))
usleep(1);
int null = open("/dev/null", O_RDWR | O_CLOEXEC); int null = open("/dev/null", O_RDWR | O_CLOEXEC);
dup3(null, STDIN_FILENO, O_CLOEXEC); dup3(null, STDIN_FILENO, O_CLOEXEC);
@@ -505,7 +512,21 @@ int main(int argc, char *argv[]) {
mv_dir(overlay, root); mv_dir(overlay, root);
patch_ramdisk(root); patch_ramdisk(root);
patch_sepolicy(); if (patch_sepolicy()) {
/* Non skip_initramfs devices using separate sepolicy
* Mount /system and try to load again */
mount("sysfs", "/sys", "sysfs", 0, NULL);
struct device dev;
setup_block(&dev, "system");
mount(dev.path, "/system", "ext4", MS_RDONLY, NULL);
// We need to mount independent vendor partition
if (setup_block(&dev, "vendor") == 0)
mount(dev.path, "/vendor", "ext4", MS_RDONLY, NULL);
patch_sepolicy();
umount("/system");
}
if (fork_dont_care() == 0) { if (fork_dont_care() == 0) {
strcpy(argv[0], "magiskinit"); strcpy(argv[0], "magiskinit");

View File

@@ -29,7 +29,7 @@ struct vector *vec_dup(struct vector *v);
for (int _ = 0; v && _ < (v)->size; ++_, e = (v)->data[_]) for (int _ = 0; v && _ < (v)->size; ++_, e = (v)->data[_])
#define vec_for_each_r(v, e) \ #define vec_for_each_r(v, e) \
e = v ? (v)->data[(v)->size - 1] : NULL; \ e = (v && (v)->size > 0) ? (v)->data[(v)->size - 1] : NULL; \
for (int _ = ((int) (v)->size) - 1; v && _ >= 0; --_, e = (v)->data[_]) for (int _ = ((int) (v)->size) - 1; v && _ >= 0; --_, e = (v)->data[_])
#define vec_cur(v) vec_entry(v)[_] #define vec_cur(v) vec_entry(v)[_]

View File

@@ -49,7 +49,7 @@ static void dtb_dump(const char *file) {
for (int i = 0; i < size; ++i) { 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; fdt = dtb + i;
fprintf(stderr, "Dumping dtb.%04d\n\n", dtb_num++); fprintf(stderr, "Dumping dtb.%04d\n", dtb_num++);
print_subnode(fdt, 0, 0); print_subnode(fdt, 0, 0);
} }
} }
@@ -61,7 +61,7 @@ static void dtb_dump(const char *file) {
static void dtb_patch(const char *file, int patch) { static void dtb_patch(const char *file, int patch) {
size_t size ; size_t size ;
void *dtb, *fdt; void *dtb, *fdt;
fprintf(stderr, "Loading dtbs from [%s]\n\n", file); fprintf(stderr, "Loading dtbs from [%s]\n", file);
if (patch) if (patch)
mmap_rw(file, &dtb, &size); mmap_rw(file, &dtb, &size);
else else
@@ -78,13 +78,21 @@ 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;
void *value = (char *) fdt_getprop(fdt, block, "fsmgr_flags", &value_size); void *value = (void *) fdt_getprop(fdt, block, "fsmgr_flags", &value_size);
found |= patch_verity(&value, &value_size, patch); if (patch) {
void *dup = xmalloc(value_size);
memcpy(dup, value, value_size);
memset(value, 0, value_size);
found |= patch_verity(&dup, &value_size, 1);
memcpy(value, dup, value_size);
free(dup);
} else {
found |= patch_verity(&value, &value_size, 0);
}
} }
} }
} }
} }
fprintf(stderr, "\n");
munmap(dtb, size); munmap(dtb, size);
exit(!found); exit(!found);
} }

View File

@@ -73,12 +73,12 @@ static void usage(char *arg0) {
" --dtb-<cmd> <dtb>\n" " --dtb-<cmd> <dtb>\n"
" Do dtb related cmds to <dtb> (modifications are done directly)\n" " Do dtb related cmds to <dtb> (modifications are done directly)\n"
" Supported commands:\n" " Supported commands:\n"
" -dump\n" " dump\n"
" Dump all contents from dtb for debugging\n" " Dump all contents from dtb for debugging\n"
" -test\n" " test\n"
" Check if fstab has verity/avb flags\n" " Check if fstab has verity/avb flags\n"
" Return value: 0/no flags 1/flag exists" " Return value: 0/no flags 1/flag exists\n"
" -patch\n" " patch\n"
" Search for fstab and remove verity/avb\n" " Search for fstab and remove verity/avb\n"
"\n" "\n"
" --compress[=method] <infile> [outfile]\n" " --compress[=method] <infile> [outfile]\n"

View File

@@ -9,6 +9,8 @@
#include "cpio.h" #include "cpio.h"
static void cpio_patch(struct vector *v, int keepverity, int keepforceencrypt) { static void cpio_patch(struct vector *v, int keepverity, int keepforceencrypt) {
fprintf(stderr, "Patch with flag KEEPVERITY=[%s] KEEPFORCEENCRYPT=[%s]\n",
keepverity ? "true" : "false", keepforceencrypt ? "true" : "false");
cpio_entry *e; cpio_entry *e;
vec_for_each(v, e) { vec_for_each(v, e) {
if (!e) continue; if (!e) continue;
@@ -134,7 +136,7 @@ static void cpio_backup(struct vector *v, struct vector *bak, const char *orig,
backup = 1; backup = 1;
fprintf(stderr, "Backup mismatch entry: "); fprintf(stderr, "Backup mismatch entry: ");
} else { } else {
// Someting new in ramdisk, record in rem // Something new in ramdisk, record in rem
++j; ++j;
rem->data = xrealloc(rem->data, rem->filesize + strlen(n->filename) + 1); rem->data = xrealloc(rem->data, rem->filesize + strlen(n->filename) + 1);
memcpy(rem->data + rem->filesize, n->filename, strlen(n->filename) + 1); memcpy(rem->data + rem->filesize, n->filename, strlen(n->filename) + 1);

View File

@@ -176,8 +176,8 @@ void proc_monitor() {
// Get the mount namespace of zygote // Get the mount namespace of zygote
zygote_num = 0; zygote_num = 0;
while(!zygote_num) { while(!zygote_num) {
// Check zygote every 2 secs // Check zygote every 10 ms
sleep(2); usleep(10000);
ps_filter_proc_name("zygote", store_zygote_ns); ps_filter_proc_name("zygote", store_zygote_ns);
} }
ps_filter_proc_name("zygote64", store_zygote_ns); ps_filter_proc_name("zygote64", store_zygote_ns);

View File

@@ -57,9 +57,9 @@ void cpio_vec_insert(struct vector *v, cpio_entry *n) {
// Parse cpio file to a vector of cpio_entry // Parse cpio file to a vector of cpio_entry
void parse_cpio(struct vector *v, const char *filename) { void parse_cpio(struct vector *v, const char *filename) {
fprintf(stderr, "Loading cpio: [%s]\n", filename);
int fd = open(filename, O_RDONLY); int fd = open(filename, O_RDONLY);
if (fd < 0) return; if (fd < 0) return;
fprintf(stderr, "Loading cpio: [%s]\n", filename);
cpio_newc_header header; cpio_newc_header header;
cpio_entry *f; cpio_entry *f;
while(xxread(fd, &header, 110) != -1) { while(xxread(fd, &header, 110) != -1) {

View File

@@ -20,6 +20,7 @@
#include "logging.h" #include "logging.h"
#include "utils.h" #include "utils.h"
#include "resetprop.h"
unsigned get_shell_uid() { unsigned get_shell_uid() {
struct passwd* ppwd = getpwnam("shell"); struct passwd* ppwd = getpwnam("shell");
@@ -46,18 +47,22 @@ unsigned get_radio_uid() {
} }
int check_data() { int check_data() {
int ret = 0; struct vector v;
char buffer[4096]; vec_init(&v);
FILE *fp = xfopen("/proc/mounts", "r"); file_to_vector("/proc/mounts", &v);
while (fgets(buffer, sizeof(buffer), fp)) { char *line, *crypto;
if (strstr(buffer, " /data ")) { int mnt = 0;
if (strstr(buffer, "tmpfs") == NULL) vec_for_each(&v, line) {
ret = 1; if (strstr(line, " /data ")) {
if (strstr(line, "tmpfs") == NULL)
mnt = 1;
break; break;
} }
} }
fclose(fp); vec_deep_destroy(&v);
return ret; // /data is mounted and not tmpfs and data is unencrypted or vold is started
return mnt && (((crypto = getprop("ro.crypto.state")) && strcmp(crypto, "unencrypted") == 0)
|| getprop("init.svc.vold"));
} }
/* All the string should be freed manually!! */ /* All the string should be freed manually!! */
@@ -277,7 +282,7 @@ int exec_command(int err, int *fd, void (*setupenv)(struct vector*), const char
int bind_mount(const char *from, const char *to) { int bind_mount(const char *from, const char *to) {
int ret = xmount(from, to, NULL, MS_BIND, NULL); int ret = xmount(from, to, NULL, MS_BIND, NULL);
#ifdef MAGISK_DEBUG #ifdef MAGISK_DEBUG
LOGI("bind_mount: %s -> %s\n", from, to); LOGI("bind_mount: %s <- %s\n", to, from);
#else #else
LOGI("bind_mount: %s\n", to); LOGI("bind_mount: %s\n", to);
#endif #endif

View File

@@ -4,19 +4,19 @@
#include "utils.h" #include "utils.h"
static int check_verity_pattern(const char *s) { static int check_verity_pattern(const char *s) {
int pos = 0; int skip = 0;
if (s[0] == ',') ++pos; if (s[0] == ',') ++skip;
if (strncmp(s + pos, "verify", 6) == 0) if (strncmp(s + skip, "verify", 6) == 0)
pos += 6; skip += 6;
else if (strncmp(s + pos, "avb", 3) == 0) else if (strncmp(s + skip, "avb", 3) == 0)
pos += 3; skip += 3;
else else
return -1; return -1;
if (s[pos] == '=') { if (s[skip] == '=') {
while (s[pos] != '\0' && s[pos] != ' ' && s[pos] != '\n' && s[pos] != ',') ++pos; while (s[skip] != '\0' && s[skip] != ' ' && s[skip] != '\n' && s[skip] != ',') ++skip;
} }
return pos; return skip;
} }
static int check_encryption_pattern(const char *s) { static int check_encryption_pattern(const char *s) {
@@ -59,34 +59,41 @@ void patch_init_rc(void **buf, size_t *size) {
} }
int patch_verity(void **buf, uint32_t *size, int patch) { int patch_verity(void **buf, uint32_t *size, int patch) {
int skip, found = 0; int skip, src_size = *size;
for (int pos = 0; pos < *size; ++pos) { char *src = *buf, *patched = patch ? xcalloc(src_size, 1) : NULL;
if ((skip = check_verity_pattern(*buf + pos)) > 0) { for (int read = 0, write = 0; read < src_size; ++read, ++write) {
found = 1; if ((skip = check_verity_pattern(src + read)) > 0) {
fprintf(stderr, "%s pattern [%.*s]\n", patch ? "Remove" : "Found", skip, (char *) *buf + pos); if (!patch)
if (patch) { return 1;
memcpy(*buf + pos, *buf + pos + skip, *size - pos - skip); fprintf(stderr, "Remove pattern [%.*s]\n", skip, src + read);
memset(*buf + *size - skip, '\0', skip); read += skip;
*size -= skip; *size -= skip;
} else {
pos += skip - 1;
}
} }
if (patch)
patched[write] = src[read];
} }
return found; if (patch) {
free(*buf);
*buf = patched;
}
return 0;
} }
void patch_encryption(void **buf, uint32_t *size) { void patch_encryption(void **buf, uint32_t *size) {
int skip; int skip, src_size = *size;
for (int pos = 0; pos < *size; ++pos) { char *src = *buf, *patched = xcalloc(src_size, 1);
if ((skip = check_encryption_pattern(*buf + pos)) > 0) { for (int read = 0, write = 0; read < src_size; ++read, ++write) {
fprintf(stderr, "Replace pattern [%.*s] with [encryptable]\n", skip, (char *) *buf + pos); if ((skip = check_encryption_pattern(src + read)) > 0) {
memcpy(*buf + pos, "encryptable", 11); fprintf(stderr, "Replace pattern [%.*s] with [encryptable]\n", skip, src + read);
memcpy(*buf + pos + 11, *buf + pos + skip, *size - pos - skip); memcpy(patched + read, "encryptable", 11);
memset(*buf + *size - skip + 11, '\0', skip - 11); read += skip;
write += 11;
*size -= (skip - 11); *size -= (skip - 11);
} }
patched[write] = src[read];
} }
free(*buf);
*buf = patched;
} }

View File

@@ -13,8 +13,6 @@
main() { main() {
# Magisk binaries # Magisk binaries
MAGISKBIN=/data/adb/magisk MAGISKBIN=/data/adb/magisk
# This script always runs in recovery
BOOTMODE=false
mount /data 2>/dev/null mount /data 2>/dev/null
@@ -41,7 +39,6 @@ main() {
remove_system_su remove_system_su
find_boot_image
[ -z $BOOTIMAGE ] && abort "! Unable to detect boot image" [ -z $BOOTIMAGE ] && abort "! Unable to detect boot image"
ui_print "- Found boot image: $BOOTIMAGE" ui_print "- Found boot image: $BOOTIMAGE"
@@ -59,13 +56,6 @@ main() {
mv stock_boot* /data mv stock_boot* /data
fi fi
patch_dtbo_image
if [ -f stock_dtbo* ]; then
rm -f /data/stock_dtbo* 2>/dev/null
mv stock_dtbo* /data
fi
cd / cd /
recovery_cleanup recovery_cleanup

View File

@@ -83,8 +83,6 @@ chmod -R 755 .
# Unpack # Unpack
########################################################################################## ##########################################################################################
migrate_boot_backup
CHROMEOS=false CHROMEOS=false
ui_print "- Unpacking boot image" ui_print "- Unpacking boot image"

View File

@@ -13,10 +13,6 @@
# Preparation # Preparation
########################################################################################## ##########################################################################################
# Detect whether in boot mode
ps | grep zygote | grep -v grep >/dev/null && BOOTMODE=true || BOOTMODE=false
$BOOTMODE || ps -A 2>/dev/null | grep zygote | grep -v grep >/dev/null && BOOTMODE=true
# This path should work in any cases # This path should work in any cases
TMPDIR=/dev/tmp TMPDIR=/dev/tmp
@@ -24,7 +20,6 @@ INSTALLER=$TMPDIR/install
COMMONDIR=$INSTALLER/common COMMONDIR=$INSTALLER/common
APK=$COMMONDIR/magisk.apk APK=$COMMONDIR/magisk.apk
CHROMEDIR=$INSTALLER/chromeos CHROMEDIR=$INSTALLER/chromeos
COREDIR=/magisk/.core
# Default permissions # Default permissions
umask 022 umask 022
@@ -83,8 +78,8 @@ if is_mounted /data; then
chmod 700 /data/adb 2>/dev/null chmod 700 /data/adb 2>/dev/null
# Some legacy migration # Some legacy migration
mv /data/magisk/stock_boot* /data 2>/dev/null run_migrations
[ -L /data/magisk.img ] || mv /data/magisk.img /data/adb/magisk.img [ -L /data/magisk.img ] || mv /data/magisk.img /data/adb/magisk.img 2>/dev/null
else else
MAGISKBIN=/cache/data_bin MAGISKBIN=/cache/data_bin
fi fi
@@ -113,7 +108,6 @@ $BOOTMODE || recovery_actions
[ -z $BOOTIMAGE ] && abort "! Unable to detect boot image" [ -z $BOOTIMAGE ] && abort "! Unable to detect boot image"
ui_print "- Found boot image: $BOOTIMAGE" ui_print "- Found boot image: $BOOTIMAGE"
find_dtbo_image
if [ ! -z $DTBOIMAGE ]; then if [ ! -z $DTBOIMAGE ]; then
ui_print "- Found dtbo image: $DTBOIMAGE" ui_print "- Found dtbo image: $DTBOIMAGE"
# Disable dtbo patch by default # Disable dtbo patch by default

View File

@@ -34,20 +34,16 @@ fi
if $BOOTMODE; then if $BOOTMODE; then
# Load utility functions # Load utility functions
. $MAGISKBIN/util_functions.sh . $MAGISKBIN/util_functions.sh
BOOTMODE=true
boot_actions boot_actions
mount_partitions mount_partitions
fi fi
cd $MAGISKBIN cd $MAGISKBIN
# Find the boot image
find_boot_image
[ -z $BOOTIMAGE ] && abort "! Unable to detect boot image" [ -z $BOOTIMAGE ] && abort "! Unable to detect boot image"
ui_print "- Found Boot Image: $BOOTIMAGE" ui_print "- Found Boot Image: $BOOTIMAGE"
migrate_boot_backup
ui_print "- Unpacking boot image" ui_print "- Unpacking boot image"
./magiskboot --unpack "$BOOTIMAGE" ./magiskboot --unpack "$BOOTIMAGE"
CHROMEOS=false CHROMEOS=false

View File

@@ -10,8 +10,15 @@
#MAGISK_VERSION_STUB #MAGISK_VERSION_STUB
SCRIPT_VERSION=$MAGISK_VER_CODE SCRIPT_VERSION=$MAGISK_VER_CODE
# Detect whether in boot mode
ps | grep zygote | grep -v grep >/dev/null && BOOTMODE=true || BOOTMODE=false
$BOOTMODE || ps -A 2>/dev/null | grep zygote | grep -v grep >/dev/null && BOOTMODE=true
$BOOTMODE || id | grep -q 'uid=0' || BOOTMODE=true
# Default location, will override if needed # Default location, will override if needed
[ -d /data/adb/magisk ] && MAGISKBIN=/data/adb/magisk || MAGISKBIN=/data/magisk MAGISKBIN=/data/adb/magisk
[ -z $MOUNTPATH ] && MOUNTPATH=/sbin/.core/img
[ -z $IMG ] && IMG=/data/adb/magisk.img
BOOTSIGNER="/system/bin/dalvikvm -Xnodex2oat -Xnoimage-dex2oat -cp \$APK com.topjohnwu.magisk.utils.BootSigner" BOOTSIGNER="/system/bin/dalvikvm -Xnodex2oat -Xnoimage-dex2oat -cp \$APK com.topjohnwu.magisk.utils.BootSigner"
BOOTSIGNED=false BOOTSIGNED=false
@@ -45,7 +52,12 @@ mount_partitions() {
SLOT=_`getprop ro.boot.slot` SLOT=_`getprop ro.boot.slot`
[ $SLOT = "_" ] && SLOT= [ $SLOT = "_" ] && SLOT=
fi fi
# Check the boot image to make sure the slot actually make sense
find_boot_image
find_dtbo_image
[ -z $SLOT ] || ui_print "- A/B partition detected, current slot: $SLOT" [ -z $SLOT ] || ui_print "- A/B partition detected, current slot: $SLOT"
ui_print "- Mounting /system, /vendor" ui_print "- Mounting /system, /vendor"
is_mounted /system || [ -f /system/build.prop ] || mount -o ro /system 2>/dev/null is_mounted /system || [ -f /system/build.prop ] || mount -o ro /system 2>/dev/null
if ! is_mounted /system && ! [ -f /system/build.prop ]; then if ! is_mounted /system && ! [ -f /system/build.prop ]; then
@@ -84,7 +96,7 @@ getvar() {
local VARNAME=$1 local VARNAME=$1
local VALUE=$(eval echo \$$VARNAME) local VALUE=$(eval echo \$$VARNAME)
[ ! -z $VALUE ] && return [ ! -z $VALUE ] && return
for DIR in /.backup /data /cache /system; do for DIR in /.backup /dev /data /cache /system; do
VALUE=`grep_prop $VARNAME $DIR/.magisk` VALUE=`grep_prop $VARNAME $DIR/.magisk`
[ ! -z $VALUE ] && break; [ ! -z $VALUE ] && break;
done done
@@ -103,7 +115,10 @@ find_boot_image() {
BOOTIMAGE= BOOTIMAGE=
if [ ! -z $SLOT ]; then if [ ! -z $SLOT ]; then
BOOTIMAGE=`find /dev/block -iname boot$SLOT | head -n 1` 2>/dev/null BOOTIMAGE=`find /dev/block -iname boot$SLOT | head -n 1` 2>/dev/null
else fi
if [ -z "$BOOTIMAGE" ]; then
# The slot info is incorrect...
SLOT=
for BLOCK in boot_a kern-a android_boot kernel boot lnx bootimg; do for BLOCK in boot_a kern-a android_boot kernel boot lnx bootimg; do
BOOTIMAGE=`find /dev/block -iname $BLOCK | head -n 1` 2>/dev/null BOOTIMAGE=`find /dev/block -iname $BLOCK | head -n 1` 2>/dev/null
[ ! -z $BOOTIMAGE ] && break [ ! -z $BOOTIMAGE ] && break
@@ -116,10 +131,10 @@ find_boot_image() {
[ ! -z $BOOTIMAGE ] && break [ ! -z $BOOTIMAGE ] && break
done done
fi fi
BOOTIMAGE=`resolve_link $BOOTIMAGE` [ ! -z "$BOOTIMAGE" ] && BOOTIMAGE=`resolve_link $BOOTIMAGE`
} }
migrate_boot_backup() { run_migrations() {
# Update the broken boot backup # Update the broken boot backup
if [ -f /data/stock_boot_.img.gz ]; then if [ -f /data/stock_boot_.img.gz ]; then
$MAGISKBIN/magiskboot --decompress /data/stock_boot_.img.gz /data/stock_boot.img $MAGISKBIN/magiskboot --decompress /data/stock_boot_.img.gz /data/stock_boot.img
@@ -132,8 +147,17 @@ migrate_boot_backup() {
mv /data/stock_boot.img $STOCKDUMP mv /data/stock_boot.img $STOCKDUMP
$MAGISKBIN/magiskboot --compress $STOCKDUMP $MAGISKBIN/magiskboot --compress $STOCKDUMP
fi fi
mv /data/magisk/stock_boot* /data 2>/dev/null # Move the stock backups
mv /data/magisk/adb/stock_boot* /data 2>/dev/null if [ -f /data/magisk/stock_boot* ]; then
rm -rf /data/stock_boot*
mv /data/magisk/stock_boot* /data 2>/dev/null
fi
if [ -f /data/adb/magisk/stock_boot* ]; then
rm -rf /data/stock_boot*
mv /data/adb/magisk/stock_boot* /data 2>/dev/null
fi
# Remove old dbs
rm -f /data/user*/*/magisk.db
} }
flash_boot_image() { flash_boot_image() {
@@ -333,3 +357,36 @@ image_size_check() {
curFreeM=$((curSizeM - curUsedM)) curFreeM=$((curSizeM - curUsedM))
} }
mount_magisk_img() {
[ -z reqSizeM ] && reqSizeM=0
if [ -f "$IMG" ]; then
ui_print "- Found $IMG"
image_size_check $IMG
if [ "$reqSizeM" -gt "$curFreeM" ]; then
newSizeM=$(((reqSizeM + curUsedM) / 32 * 32 + 64))
ui_print "- Resizing $IMG to ${newSizeM}M"
$MAGISKBIN/magisk --resizeimg $IMG $newSizeM >&2
fi
else
newSizeM=$((reqSizeM / 32 * 32 + 64));
ui_print "- Creating $IMG with size ${newSizeM}M"
$MAGISKBIN/magisk --createimg $IMG $newSizeM >&2
fi
ui_print "- Mounting $IMG to $MOUNTPATH"
MAGISKLOOP=`$MAGISKBIN/magisk --mountimg $IMG $MOUNTPATH`
is_mounted $MOUNTPATH || abort "! $IMG mount failed..."
}
unmount_magisk_img() {
$MAGISKBIN/magisk --umountimg $MOUNTPATH $MAGISKLOOP
# Shrink the image if possible
image_size_check $IMG
newSizeM=$((curUsedM / 32 * 32 + 64))
if [ $curSizeM -gt $newSizeM ]; then
ui_print "- Shrinking $IMG to ${newSizeM}M"
$MAGISKBIN/magisk --resizeimg $IMG $newSizeM
fi
}

View File

@@ -2,7 +2,7 @@ apply plugin: 'com.android.application'
android { android {
compileSdkVersion 27 compileSdkVersion 27
buildToolsVersion "27.0.2" buildToolsVersion "27.0.3"
defaultConfig { defaultConfig {
applicationId "com.topjohnwu.snet" applicationId "com.topjohnwu.snet"

View File

@@ -32,6 +32,8 @@ public class SafetyNetHelper
public static final int BASIC_PASS = 0x10; public static final int BASIC_PASS = 0x10;
public static final int CTS_PASS = 0x20; public static final int CTS_PASS = 0x20;
public static final int SNET_EXT_VER = 7;
private GoogleApiClient mGoogleApiClient; private GoogleApiClient mGoogleApiClient;
private Activity mActivity; private Activity mActivity;
private int responseCode; private int responseCode;
@@ -39,6 +41,10 @@ public class SafetyNetHelper
private String dexPath; private String dexPath;
private boolean isDarkTheme; private boolean isDarkTheme;
public static int getVersion() {
return SNET_EXT_VER;
}
public SafetyNetHelper(Activity activity, String dexPath, SafetyNetCallback cb) { public SafetyNetHelper(Activity activity, String dexPath, SafetyNetCallback cb) {
mActivity = activity; mActivity = activity;
this.cb = cb; this.cb = cb;