Compare commits

..

9 Commits
v14.6 ... v15.1

Author SHA1 Message Date
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
16 changed files with 124 additions and 68 deletions

2
app

Submodule app updated: 0d9527921a...1adf331268

View File

@@ -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

@@ -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);

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
@@ -84,7 +84,6 @@ static void dtb_patch(const char *file, int patch) {
} }
} }
} }
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

@@ -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!! */

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,39 @@ 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; 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

@@ -11,7 +11,9 @@
SCRIPT_VERSION=$MAGISK_VER_CODE SCRIPT_VERSION=$MAGISK_VER_CODE
# 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
@@ -84,7 +86,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
@@ -333,3 +335,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;