Compare commits

...

25 Commits
v16.2 ... v16.4

Author SHA1 Message Date
topjohnwu
3a9a3ed184 Bump Magisk Manager version 2018-04-29 15:20:41 +08:00
topjohnwu
88fae36b8a Hide sub-services of apps for hiding
Close #383
2018-04-29 15:10:35 +08:00
topjohnwu
fc9d4034a9 Fix installation in custom recoveries 2018-04-29 14:04:18 +08:00
topjohnwu
cecc0b932d Remove some traits 2018-04-29 12:34:36 +08:00
topjohnwu
0faed7159c Add invincible mode back 2018-04-29 12:17:28 +08:00
topjohnwu
fb491cfdcf Add Protobuf support to resetprop 2018-04-29 01:20:48 +08:00
topjohnwu
fc706dcb40 Bump busybox to 1.28.3 2018-04-22 14:28:16 +08:00
topjohnwu
a2c1b024f3 Use 32-bit binaries only 2018-04-22 14:13:27 +08:00
Frieder Bluemle
3d865394d7 Update Gradle wrapper to 4.6 2018-04-22 03:09:02 +08:00
topjohnwu
76ef1d0d86 Cleanup sepolicy rules 2018-04-22 03:06:40 +08:00
topjohnwu
9484ec0c17 Massive refactoring
Remove post-fs mode
2018-04-22 02:16:56 +08:00
topjohnwu
614c552e55 Improve daemon startup 2018-04-21 20:16:59 +08:00
topjohnwu
7db3d84ba2 Forgot to update the default file secontext 2018-04-21 13:20:42 +08:00
topjohnwu
87f6018468 Massive sepolicy refactor 2018-04-15 03:18:18 +08:00
topjohnwu
9194c50590 Update build.gradle 2018-04-15 03:17:28 +08:00
topjohnwu
7ff45974c6 Upstream selinux 2018-04-14 17:18:29 +08:00
topjohnwu
2533a4fc4a Fix APK installation on Android P 2018-04-08 03:22:22 +08:00
topjohnwu
42284c5efb Test logcat instead of checking logd 2018-04-08 02:12:40 +08:00
topjohnwu
7d7686da33 Update Magisk Manager 2018-03-28 15:23:55 +08:00
topjohnwu
65e455ef0b Update Android gradle plugin 2018-03-28 02:43:03 +08:00
topjohnwu
ac05e2f2e2 Fix tail size calculation
Close #381
2018-03-27 00:45:18 +08:00
topjohnwu
787f7b3035 Remove backwards compatibility symlinks
These links cause magiskhide unable to work ideally and add complications. I think I gave enough time for migration
2018-03-27 00:35:59 +08:00
topjohnwu
31bd642b80 Update to busybox 1.28.2 2018-03-26 22:12:04 +08:00
topjohnwu
f0bac6b154 Resetprop small refactor 2018-03-26 21:21:48 +08:00
topjohnwu
cc7e74ca11 Cleanup build.gradle 2018-03-26 03:53:06 +08:00
44 changed files with 863 additions and 712 deletions

3
.gitmodules vendored
View File

@@ -25,3 +25,6 @@
[submodule "xz"] [submodule "xz"]
path = native/jni/external/xz path = native/jni/external/xz
url = https://github.com/xz-mirror/xz.git url = https://github.com/xz-mirror/xz.git
[submodule "nanopb"]
path = native/jni/external/nanopb
url = https://github.com/nanopb/nanopb.git

2
app

Submodule app updated: 0c782edf21...15ed3e52f2

View File

@@ -7,7 +7,7 @@ buildscript {
jcenter() jcenter()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:3.0.1' classpath 'com.android.tools.build:gradle:3.1.2'
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong
@@ -19,9 +19,16 @@ allprojects {
repositories { repositories {
google() google()
jcenter() jcenter()
maven { url "https://jitpack.io" }
} }
} }
ext {
compileSdkVersion = 27
buildToolsVersion = "28.0.0-rc1"
supportLibVersion = "27.1.1"
}
task clean(type: Delete) { task clean(type: Delete) {
delete rootProject.buildDir delete rootProject.buildDir
} }

View File

@@ -93,7 +93,7 @@ def build_binary(args):
error('Build Magisk binary failed!') error('Build Magisk binary failed!')
print('') print('')
for arch in ['arm64-v8a', 'armeabi-v7a', 'x86', 'x86_64']: for arch in ['armeabi-v7a', 'x86']:
mkdir_p(os.path.join('out', arch)) mkdir_p(os.path.join('out', arch))
with open(os.path.join('out', arch, 'dump.h'), 'w') as dump: with open(os.path.join('out', arch, 'dump.h'), 'w') as dump:
dump.write('#include "stdlib.h"\n') dump.write('#include "stdlib.h"\n')
@@ -110,7 +110,7 @@ def build_binary(args):
error('Build Magisk binary failed!') error('Build Magisk binary failed!')
print('') print('')
for arch in ['arm64-v8a', 'armeabi-v7a', 'x86', 'x86_64']: for arch in ['armeabi-v7a', 'x86']:
for binary in ['magiskinit', 'magiskboot', 'b64xz', 'busybox']: for binary in ['magiskinit', 'magiskboot', 'b64xz', 'busybox']:
try: try:
mv(os.path.join('native', 'libs', arch, binary), os.path.join('out', arch, binary)) mv(os.path.join('native', 'libs', arch, binary), os.path.join('out', arch, binary))
@@ -234,7 +234,7 @@ def zip_main(args):
zip_with_msg(zipf, source, target) zip_with_msg(zipf, source, target)
# Binaries # Binaries
for lib_dir, zip_dir in [('arm64-v8a', 'arm64'), ('armeabi-v7a', 'arm'), ('x86', 'x86'), ('x86_64', 'x64')]: for lib_dir, zip_dir in [('armeabi-v7a', 'arm'), ('x86', 'x86')]:
for binary in ['magiskinit', 'magiskboot']: for binary in ['magiskinit', 'magiskboot']:
source = os.path.join('out', lib_dir, binary) source = os.path.join('out', lib_dir, binary)
target = os.path.join(zip_dir, binary) target = os.path.join(zip_dir, binary)
@@ -261,7 +261,7 @@ def zip_main(args):
zipf.writestr(target, util_func) zipf.writestr(target, util_func)
# addon.d.sh # addon.d.sh
source = os.path.join('scripts', 'addon.d.sh') source = os.path.join('scripts', 'addon.d.sh')
target = os.path.join('addon.d', '99-magisk.sh') target = os.path.join('common', '99-magisk.sh')
zip_with_msg(zipf, source, target) zip_with_msg(zipf, source, target)
# Prebuilts # Prebuilts
@@ -291,7 +291,7 @@ def zip_uninstaller(args):
zip_with_msg(zipf, source, target) zip_with_msg(zipf, source, target)
# Binaries # Binaries
for lib_dir, zip_dir in [('arm64-v8a', 'arm64'), ('armeabi-v7a', 'arm'), ('x86', 'x86'), ('x86_64', 'x64')]: for lib_dir, zip_dir in [('armeabi-v7a', 'arm'), ('x86', 'x86')]:
source = os.path.join('out', lib_dir, 'magiskboot') source = os.path.join('out', lib_dir, 'magiskboot')
target = os.path.join(zip_dir, 'magiskboot') target = os.path.join(zip_dir, 'magiskboot')
zip_with_msg(zipf, source, target) zip_with_msg(zipf, source, target)

Binary file not shown.

View File

@@ -1,6 +1,5 @@
#Mon Dec 04 11:24:34 CST 2017
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip

100
gradlew vendored
View File

@@ -1,4 +1,4 @@
#!/usr/bin/env bash #!/usr/bin/env sh
############################################################################## ##############################################################################
## ##
@@ -6,42 +6,6 @@
## ##
############################################################################## ##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# Attempt to set APP_HOME # Attempt to set APP_HOME
# Resolve links: $0 may be a link # Resolve links: $0 may be a link
PRG="$0" PRG="$0"
@@ -60,6 +24,46 @@ cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`" APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM. # Determine the Java command to use to start the JVM.
@@ -85,7 +89,7 @@ location of your Java installation."
fi fi
# Increase the maximum file descriptors if we can. # Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n` MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
@@ -150,11 +154,19 @@ if $cygwin ; then
esac esac
fi fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules # Escape application args
function splitJvmOpts() { save () {
JVM_OPTS=("$@") for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
} }
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS APP_ARGS=$(save "$@")
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" # Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"

14
gradlew.bat vendored
View File

@@ -8,14 +8,14 @@
@rem Set local scope for the variables with windows NT shell @rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0 set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=. if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0 set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME% set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
@rem Find java.exe @rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome if defined JAVA_HOME goto findJavaFromJavaHome
@@ -46,10 +46,9 @@ echo location of your Java installation.
goto fail goto fail
:init :init
@rem Get command-line arguments, handling Windowz variants @rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args :win9xME_args
@rem Slurp the command line arguments. @rem Slurp the command line arguments.
@@ -60,11 +59,6 @@ set _SKIP=2
if "x%~1" == "x" goto execute if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%* set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute :execute
@rem Setup the command line @rem Setup the command line

View File

@@ -1,7 +1,8 @@
apply plugin: 'com.android.library' apply plugin: 'com.android.library'
android { android {
compileSdkVersion 27 compileSdkVersion rootProject.ext.compileSdkVersion
buildToolsVersion rootProject.ext.buildToolsVersion
externalNativeBuild { externalNativeBuild {
ndkBuild { ndkBuild {

View File

@@ -9,6 +9,7 @@ LIBLZMA := $(EXT_PATH)/xz/src/liblzma/api
LIBLZ4 := $(EXT_PATH)/lz4/lib LIBLZ4 := $(EXT_PATH)/lz4/lib
LIBBZ2 := $(EXT_PATH)/bzip2 LIBBZ2 := $(EXT_PATH)/bzip2
LIBFDT := $(EXT_PATH)/dtc/libfdt LIBFDT := $(EXT_PATH)/dtc/libfdt
LIBNANOPB := $(EXT_PATH)/nanopb
UTIL_SRC := utils/cpio.c \ UTIL_SRC := utils/cpio.c \
utils/file.c \ utils/file.c \
utils/img.c \ utils/img.c \
@@ -28,11 +29,13 @@ ifneq "$(or $(PRECOMPILE), $(GRADLE))" ""
include $(CLEAR_VARS) include $(CLEAR_VARS)
LOCAL_MODULE := magisk LOCAL_MODULE := magisk
LOCAL_SHARED_LIBRARIES := libsqlite libselinux LOCAL_SHARED_LIBRARIES := libsqlite libselinux
LOCAL_STATIC_LIBRARIES := libnanopb
LOCAL_C_INCLUDES := \ LOCAL_C_INCLUDES := \
jni/include \ jni/include \
jni/magiskpolicy \
$(EXT_PATH)/include \ $(EXT_PATH)/include \
$(LIBSELINUX) $(LIBSELINUX) \
$(LIBNANOPB)
LOCAL_SRC_FILES := \ LOCAL_SRC_FILES := \
core/magisk.c \ core/magisk.c \
@@ -43,7 +46,8 @@ LOCAL_SRC_FILES := \
magiskhide/magiskhide.c \ magiskhide/magiskhide.c \
magiskhide/proc_monitor.c \ magiskhide/proc_monitor.c \
magiskhide/hide_utils.c \ magiskhide/hide_utils.c \
resetprop/resetprop.cpp \ resetprop/persist_props.c \
resetprop/resetprop.c \
resetprop/system_properties.cpp \ resetprop/system_properties.cpp \
su/su.c \ su/su.c \
su/activity.c \ su/activity.c \
@@ -74,7 +78,6 @@ LOCAL_C_INCLUDES := \
LOCAL_SRC_FILES := \ LOCAL_SRC_FILES := \
core/magiskinit.c \ core/magiskinit.c \
core/socket.c \
magiskpolicy/api.c \ magiskpolicy/api.c \
magiskpolicy/magiskpolicy.c \ magiskpolicy/magiskpolicy.c \
magiskpolicy/rules.c \ magiskpolicy/rules.c \
@@ -110,10 +113,8 @@ LOCAL_CFLAGS := -DXWRAP_EXIT
LOCAL_LDLIBS := -lz LOCAL_LDLIBS := -lz
include $(BUILD_EXECUTABLE) include $(BUILD_EXECUTABLE)
# 32-bit static binaries # static binaries
ifndef GRADLE # Do not run gradle sync on these binaries ifndef GRADLE # Do not run gradle sync on these binaries
ifneq ($(TARGET_ARCH_ABI), x86_64)
ifneq ($(TARGET_ARCH_ABI), arm64-v8a)
# b64xz # b64xz
include $(CLEAR_VARS) include $(CLEAR_VARS)
LOCAL_MODULE := b64xz LOCAL_MODULE := b64xz
@@ -125,8 +126,6 @@ include $(BUILD_EXECUTABLE)
# Busybox # Busybox
include jni/external/busybox/Android.mk include jni/external/busybox/Android.mk
endif endif
endif
endif
# Precompile # Precompile
endif endif

View File

@@ -1,4 +1,4 @@
APP_ABI := x86 x86_64 armeabi-v7a arm64-v8a APP_ABI := x86 armeabi-v7a
APP_PLATFORM := android-21 APP_PLATFORM := android-21
APP_CFLAGS := $(MAGISK_FLAGS) -std=gnu99 APP_CFLAGS := $(MAGISK_FLAGS) -std=gnu99
APP_CPPFLAGS := -std=c++11 APP_CPPFLAGS := -std=c++11

View File

@@ -19,6 +19,7 @@
#include "utils.h" #include "utils.h"
#include "daemon.h" #include "daemon.h"
#include "resetprop.h" #include "resetprop.h"
#include "magiskpolicy.h"
static char *buf, *buf2; static char *buf, *buf2;
static struct vector module_list; static struct vector module_list;
@@ -124,15 +125,6 @@ static void bb_setenv(struct vector *v) {
vec_push_back(v, NULL); vec_push_back(v, NULL);
} }
static void pm_setenv(struct vector *v) {
for (int i = 0; environ[i]; ++i) {
if (strncmp(environ[i], "CLASSPATH=", 10) != 0)
vec_push_back(v, strdup(environ[i]));
}
vec_push_back(v, strdup("CLASSPATH=/system/framework/pm.jar"));
vec_push_back(v, NULL);
}
/*********** /***********
* Scripts * * Scripts *
***********/ ***********/
@@ -359,7 +351,7 @@ static void simple_mount(const char *path) {
DIR *dir; DIR *dir;
struct dirent *entry; struct dirent *entry;
snprintf(buf, PATH_MAX, "%s%s", CACHEMOUNT, path); snprintf(buf, PATH_MAX, "%s%s", SIMPLEMOUNT, path);
if (!(dir = opendir(buf))) if (!(dir = opendir(buf)))
return; return;
@@ -377,7 +369,7 @@ static void simple_mount(const char *path) {
free(new_path); free(new_path);
} else if (entry->d_type == DT_REG) { } else if (entry->d_type == DT_REG) {
// Actual file path // Actual file path
snprintf(buf, PATH_MAX, "%s%s", CACHEMOUNT, buf2); snprintf(buf, PATH_MAX, "%s%s", SIMPLEMOUNT, buf2);
// Clone all attributes // Clone all attributes
clone_attr(buf2, buf); clone_attr(buf2, buf);
// Finally, mount the file // Finally, mount the file
@@ -460,7 +452,7 @@ static int prepare_img() {
void fix_filecon() { void fix_filecon() {
int dirfd = xopen(MOUNTPOINT, O_RDONLY | O_CLOEXEC); int dirfd = xopen(MOUNTPOINT, O_RDONLY | O_CLOEXEC);
restorecon(dirfd, 0); restorecon(dirfd);
close(dirfd); close(dirfd);
} }
@@ -473,15 +465,13 @@ static void unblock_boot_process() {
pthread_exit(NULL); pthread_exit(NULL);
} }
void post_fs(int client) { void startup() {
LOGI("** post-fs mode running\n"); if (!check_data())
// ack return;
write_int(client, 0);
close(client);
// Uninstall or core only mode // uninstaller or core-only mode
if (access(UNINSTALLER, F_OK) == 0 || access(DISABLEFILE, F_OK) == 0) if (access(UNINSTALLER, F_OK) == 0 || access(DISABLEFILE, F_OK) == 0)
goto unblock; goto initialize;
// Allocate buffer // Allocate buffer
buf = xmalloc(PATH_MAX); buf = xmalloc(PATH_MAX);
@@ -490,32 +480,152 @@ void post_fs(int client) {
simple_mount("/system"); simple_mount("/system");
simple_mount("/vendor"); simple_mount("/vendor");
unblock: initialize:
unblock_boot_process(); LOGI("** Initializing Magisk\n");
}
void post_fs_data(int client) { // Unlock all blocks for rw
// ack unlock_blocks();
write_int(client, 0);
close(client);
if (!is_daemon_init && !check_data())
goto unblock;
// Start the debug log // Magisk binaries
start_debug_full_log(); char *bin_path = NULL;
if (access("/cache/data_bin", F_OK) == 0)
bin_path = "/cache/data_bin";
else if (access("/data/data/com.topjohnwu.magisk/install", F_OK) == 0)
bin_path = "/data/data/com.topjohnwu.magisk/install";
else if (access("/data/user_de/0/com.topjohnwu.magisk/install", F_OK) == 0)
bin_path = "/data/user_de/0/com.topjohnwu.magisk/install";
if (bin_path) {
rm_rf(DATABIN);
cp_afc(bin_path, DATABIN);
rm_rf(bin_path);
}
LOGI("** post-fs-data mode running\n"); // Migration
rm_rf("/data/magisk");
unlink("/data/magisk.img");
unlink("/data/magisk_debug.log");
xmkdir("/data/adb", 0700);
chmod("/data/adb", 0700);
// Allocate buffer LOGI("* Creating /sbin overlay");
if (buf == NULL) buf = xmalloc(PATH_MAX); DIR *dir;
if (buf2 == NULL) buf2 = xmalloc(PATH_MAX); struct dirent *entry;
vec_init(&module_list); int root, sbin, fd;
char buf[PATH_MAX];
void *magisk, *init;
size_t magisk_size, init_size;
// Initialize xmount(NULL, "/", NULL, MS_REMOUNT, NULL);
if (!is_daemon_init)
daemon_init();
// uninstaller // Remove some traits of Magisk
unlink("/init.magisk.rc");
// Create hardlink mirror of /sbin to /root
mkdir("/root", 0750);
full_read("/sbin/magisk", &magisk, &magisk_size);
unlink("/sbin/magisk");
full_read("/sbin/magiskinit", &init, &init_size);
unlink("/sbin/magiskinit");
root = xopen("/root", O_RDONLY | O_CLOEXEC);
sbin = xopen("/sbin", O_RDONLY | O_CLOEXEC);
link_dir(sbin, root);
close(sbin);
// Mount the /sbin tmpfs overlay
xmount("tmpfs", "/sbin", "tmpfs", 0, NULL);
chmod("/sbin", 0755);
setfilecon("/sbin", "u:object_r:rootfs:s0");
sbin = xopen("/sbin", O_RDONLY | O_CLOEXEC);
// Setup magisk symlinks
fd = creat("/sbin/magisk", 0755);
xwrite(fd, magisk, magisk_size);
close(fd);
free(magisk);
setfilecon("/sbin/magisk", "u:object_r:"SEPOL_FILE_DOMAIN":s0");
for (int i = 0; applet[i]; ++i) {
snprintf(buf, PATH_MAX, "/sbin/%s", applet[i]);
xsymlink("/sbin/magisk", buf);
}
// Setup magiskinit symlinks
fd = creat("/sbin/magiskinit", 0755);
xwrite(fd, init, init_size);
close(fd);
free(init);
setfilecon("/sbin/magiskinit", "u:object_r:"SEPOL_FILE_DOMAIN":s0");
for (int i = 0; init_applet[i]; ++i) {
snprintf(buf, PATH_MAX, "/sbin/%s", init_applet[i]);
xsymlink("/sbin/magiskinit", buf);
}
// Create symlinks pointing back to /root
dir = xfdopendir(root);
while((entry = xreaddir(dir))) {
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue;
snprintf(buf, PATH_MAX, "/root/%s", entry->d_name);
symlinkat(buf, sbin, entry->d_name);
}
close(sbin);
close(root);
LOGI("* Mounting mirrors");
struct vector mounts;
vec_init(&mounts);
file_to_vector("/proc/mounts", &mounts);
char *line;
int skip_initramfs = 0;
// Check whether skip_initramfs device
vec_for_each(&mounts, line) {
if (strstr(line, " /system_root ")) {
xmkdirs(MIRRDIR "/system", 0755);
bind_mount("/system_root/system", MIRRDIR "/system");
skip_initramfs = 1;
break;
}
}
vec_for_each(&mounts, line) {
if (!skip_initramfs && strstr(line, " /system ")) {
sscanf(line, "%s", buf);
xmkdirs(MIRRDIR "/system", 0755);
xmount(buf, MIRRDIR "/system", "ext4", MS_RDONLY, NULL);
#ifdef MAGISK_DEBUG
LOGI("mount: %s <- %s\n", MIRRDIR "/system", buf);
#else
LOGI("mount: %s\n", MIRRDIR "/system");
#endif
} else if (strstr(line, " /vendor ")) {
seperate_vendor = 1;
sscanf(line, "%s", buf);
xmkdirs(MIRRDIR "/vendor", 0755);
xmount(buf, MIRRDIR "/vendor", "ext4", MS_RDONLY, NULL);
#ifdef MAGISK_DEBUG
LOGI("mount: %s <- %s\n", MIRRDIR "/vendor", buf);
#else
LOGI("mount: %s\n", MIRRDIR "/vendor");
#endif
}
free(line);
}
vec_destroy(&mounts);
if (!seperate_vendor) {
xsymlink(MIRRDIR "/system/vendor", MIRRDIR "/vendor");
#ifdef MAGISK_DEBUG
LOGI("link: %s <- %s\n", MIRRDIR "/vendor", MIRRDIR "/system/vendor");
#else
LOGI("link: %s\n", MIRRDIR "/vendor");
#endif
}
xmkdirs(MIRRDIR "/bin", 0755);
bind_mount(DATABIN, MIRRDIR "/bin");
LOGI("* Setting up internal busybox");
xmkdirs(BBPATH, 0755);
exec_command_sync(MIRRDIR "/bin/busybox", "--install", "-s", BBPATH, NULL);
xsymlink(MIRRDIR "/bin/busybox", BBPATH "/busybox");
// uninstall
if (access(UNINSTALLER, F_OK) == 0) { if (access(UNINSTALLER, F_OK) == 0) {
close(open(UNBLOCKFILE, O_RDONLY | O_CREAT)); close(open(UNBLOCKFILE, O_RDONLY | O_CREAT));
setenv("BOOTMODE", "true", 1); setenv("BOOTMODE", "true", 1);
@@ -523,6 +633,28 @@ void post_fs_data(int client) {
return; return;
} }
// Start post-fs-data mode
execv("/sbin/magisk", (char *[]) { "magisk", "--post-fs-data", NULL });
}
void post_fs_data(int client) {
// ack
write_int(client, 0);
close(client);
// Start the debug log
start_debug_full_log();
LOGI("** post-fs-data mode running\n");
xmount(NULL, "/", NULL, MS_REMOUNT | MS_RDONLY, NULL);
full_patch_pid = exec_command(0, NULL, NULL, "/sbin/magiskpolicy", "--live", "allow "SEPOL_PROC_DOMAIN" * * *", NULL);
// Allocate buffer
buf = xmalloc(PATH_MAX);
buf2 = xmalloc(PATH_MAX);
vec_init(&module_list);
// Merge, trim, mount magisk.img, which will also travel through the modules // Merge, trim, mount magisk.img, which will also travel through the modules
// After this, it will create the module list // After this, it will create the module list
if (prepare_img()) if (prepare_img())
@@ -614,8 +746,6 @@ core_only:
} }
auto_start_magiskhide(); auto_start_magiskhide();
unblock:
unblock_boot_process(); unblock_boot_process();
} }
@@ -630,8 +760,7 @@ void late_start(int client) {
if (buf2 == NULL) buf2 = xmalloc(PATH_MAX); if (buf2 == NULL) buf2 = xmalloc(PATH_MAX);
// Wait till the full patch is done // Wait till the full patch is done
wait_till_exists(PATCHDONE); waitpid(full_patch_pid, NULL, 0);
unlink(PATCHDONE);
// Run scripts after full patch, most reliable way to run scripts // Run scripts after full patch, most reliable way to run scripts
LOGI("* Running service.d scripts\n"); LOGI("* Running service.d scripts\n");
@@ -648,14 +777,13 @@ core_only:
// Install Magisk Manager if exists // Install Magisk Manager if exists
if (access(MANAGERAPK, F_OK) == 0) { if (access(MANAGERAPK, F_OK) == 0) {
rename(MANAGERAPK, "/data/magisk.apk"); rename(MANAGERAPK, "/data/magisk.apk");
setfilecon("/data/magisk.apk", "u:object_r:su_file:s0"); setfilecon("/data/magisk.apk", "u:object_r:"SEPOL_FILE_DOMAIN":s0");
while (1) { while (1) {
sleep(5); sleep(5);
LOGD("apk_install: attempting to install APK");
int apk_res = -1, pid; int apk_res = -1, pid;
pid = exec_command(1, &apk_res, pm_setenv, pid = exec_command(1, &apk_res, NULL,
"app_process", "/system/bin/pm", "install", "-r", "/data/magisk.apk", NULL);
"/system/bin", "com.android.commands.pm.Pm",
"install", "-r", "/data/magisk.apk", NULL);
if (pid != -1) { if (pid != -1) {
int err = 0; int err = 0;
while (fdgets(buf, PATH_MAX, apk_res) > 0) { while (fdgets(buf, PATH_MAX, apk_res) > 0) {

View File

@@ -19,8 +19,10 @@
#include "utils.h" #include "utils.h"
#include "daemon.h" #include "daemon.h"
#include "resetprop.h" #include "resetprop.h"
#include "magiskpolicy.h"
int is_daemon_init = 0, seperate_vendor = 0; int seperate_vendor = 0;
int full_patch_pid;
static void *request_handler(void *args) { static void *request_handler(void *args) {
int client = *((int *) args); int client = *((int *) args);
@@ -36,7 +38,6 @@ static void *request_handler(void *args) {
case ADD_HIDELIST: case ADD_HIDELIST:
case RM_HIDELIST: case RM_HIDELIST:
case LS_HIDELIST: case LS_HIDELIST:
case POST_FS:
case POST_FS_DATA: case POST_FS_DATA:
case LATE_START: case LATE_START:
if (credential.uid != 0) { if (credential.uid != 0) {
@@ -75,9 +76,6 @@ static void *request_handler(void *args) {
write_int(client, MAGISK_VER_CODE); write_int(client, MAGISK_VER_CODE);
close(client); close(client);
break; break;
case POST_FS:
post_fs(client);
break;
case POST_FS_DATA: case POST_FS_DATA:
post_fs_data(client); post_fs_data(client);
break; break;
@@ -96,6 +94,30 @@ static void *start_magisk_hide(void *args) {
return NULL; return NULL;
} }
static void daemon_saver() {
int fd, val;
struct sockaddr_un sun;
// Change process name
strcpy(argv0, "magisk_saver");
while (1) {
fd = setup_socket(&sun);
while(connect(fd, (struct sockaddr*) &sun, sizeof(sun)))
usleep(10000);
write_int(fd, DO_NOTHING);
// Should hold forever unless the other side is closed
read(fd, &val, sizeof(int));
// If it came here, the daemon is terminated
close(fd);
if (fork_dont_care() == 0)
start_daemon(0);
}
}
void auto_start_magiskhide() { void auto_start_magiskhide() {
char *hide_prop = getprop2(MAGISKHIDE_PROP, 1); char *hide_prop = getprop2(MAGISKHIDE_PROP, 1);
if (hide_prop == NULL || strcmp(hide_prop, "0") != 0) { if (hide_prop == NULL || strcmp(hide_prop, "0") != 0) {
@@ -106,151 +128,18 @@ void auto_start_magiskhide() {
free(hide_prop); free(hide_prop);
} }
void daemon_init() { void start_daemon(int post_fs_data) {
is_daemon_init = 1;
// Magisk binaries
char *bin_path = NULL;
if (access("/cache/data_bin", F_OK) == 0)
bin_path = "/cache/data_bin";
else if (access("/data/data/com.topjohnwu.magisk/install", F_OK) == 0)
bin_path = "/data/data/com.topjohnwu.magisk/install";
else if (access("/data/user_de/0/com.topjohnwu.magisk/install", F_OK) == 0)
bin_path = "/data/user_de/0/com.topjohnwu.magisk/install";
if (bin_path) {
rm_rf(DATABIN);
cp_afc(bin_path, DATABIN);
rm_rf(bin_path);
}
// Migration
rm_rf("/data/magisk");
unlink("/data/magisk.img");
unlink("/data/magisk_debug.log");
chmod("/data/adb", 0700);
LOGI("* Creating /sbin overlay");
DIR *dir;
struct dirent *entry;
int root, sbin;
char buf[PATH_MAX], buf2[PATH_MAX];
char magisk_name[10], init_name[10];
// Setup links under /sbin
xmount(NULL, "/", NULL, MS_REMOUNT, NULL);
xmkdir("/root", 0755);
chmod("/root", 0755);
root = xopen("/root", O_RDONLY | O_CLOEXEC);
sbin = xopen("/sbin", O_RDONLY | O_CLOEXEC);
link_dir(sbin, root);
unlink("/sbin/magisk");
close(sbin);
xmount("tmpfs", "/sbin", "tmpfs", 0, NULL);
chmod("/sbin", 0755);
setfilecon("/sbin", "u:object_r:rootfs:s0");
dir = xfdopendir(root);
while((entry = xreaddir(dir))) {
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue;
snprintf(buf, PATH_MAX, "/root/%s", entry->d_name);
snprintf(buf2, PATH_MAX, "/sbin/%s", entry->d_name);
xsymlink(buf, buf2);
}
gen_rand_str(magisk_name, sizeof(magisk_name));
snprintf(buf, PATH_MAX, "/root/%s", magisk_name);
unlink("/sbin/magisk");
rename("/root/magisk", buf);
xsymlink(buf, "/sbin/magisk");
for (int i = 0; applet[i]; ++i) {
snprintf(buf2, PATH_MAX, "/sbin/%s", applet[i]);
xsymlink(buf, buf2);
}
gen_rand_str(init_name, sizeof(init_name));
snprintf(buf, PATH_MAX, "/root/%s", init_name);
unlink("/sbin/magiskinit");
rename("/root/magiskinit", buf);
for (int i = 0; init_applet[i]; ++i) {
snprintf(buf2, PATH_MAX, "/sbin/%s", init_applet[i]);
xsymlink(buf, buf2);
}
close(root);
// Backward compatibility
xsymlink(DATABIN, "/data/magisk");
xsymlink(MAINIMG, "/data/magisk.img");
xsymlink(MOUNTPOINT, "/magisk");
xmount(NULL, "/", NULL, MS_REMOUNT | MS_RDONLY, NULL);
LOGI("* Mounting mirrors");
struct vector mounts;
vec_init(&mounts);
file_to_vector("/proc/mounts", &mounts);
char *line;
int skip_initramfs = 0;
// Check whether skip_initramfs device
vec_for_each(&mounts, line) {
if (strstr(line, " /system_root ")) {
xmkdirs(MIRRDIR "/system", 0755);
bind_mount("/system_root/system", MIRRDIR "/system");
skip_initramfs = 1;
break;
}
}
vec_for_each(&mounts, line) {
if (!skip_initramfs && strstr(line, " /system ")) {
sscanf(line, "%s", buf);
xmkdirs(MIRRDIR "/system", 0755);
xmount(buf, MIRRDIR "/system", "ext4", MS_RDONLY, NULL);
#ifdef MAGISK_DEBUG
LOGI("mount: %s <- %s\n", MIRRDIR "/system", buf);
#else
LOGI("mount: %s\n", MIRRDIR "/system");
#endif
} else if (strstr(line, " /vendor ")) {
seperate_vendor = 1;
sscanf(line, "%s", buf);
xmkdirs(MIRRDIR "/vendor", 0755);
xmount(buf, MIRRDIR "/vendor", "ext4", MS_RDONLY, NULL);
#ifdef MAGISK_DEBUG
LOGI("mount: %s <- %s\n", MIRRDIR "/vendor", buf);
#else
LOGI("mount: %s\n", MIRRDIR "/vendor");
#endif
}
free(line);
}
vec_destroy(&mounts);
if (!seperate_vendor) {
xsymlink(MIRRDIR "/system/vendor", MIRRDIR "/vendor");
#ifdef MAGISK_DEBUG
LOGI("link: %s <- %s\n", MIRRDIR "/vendor", MIRRDIR "/system/vendor");
#else
LOGI("link: %s\n", MIRRDIR "/vendor");
#endif
}
xmkdirs(MIRRDIR "/bin", 0755);
bind_mount(DATABIN, MIRRDIR "/bin");
LOGI("* Setting up internal busybox");
xmkdirs(BBPATH, 0755);
exec_command_sync(MIRRDIR "/bin/busybox", "--install", "-s", BBPATH, NULL);
xsymlink(MIRRDIR "/bin/busybox", BBPATH "/busybox");
}
void start_daemon() {
setsid(); setsid();
setcon("u:r:su:s0"); setcon("u:r:"SEPOL_PROC_DOMAIN":s0");
umask(0);
int fd = xopen("/dev/null", O_RDWR | O_CLOEXEC); int fd = xopen("/dev/null", O_RDWR | O_CLOEXEC);
xdup2(fd, STDIN_FILENO); xdup2(fd, STDIN_FILENO);
xdup2(fd, STDOUT_FILENO); xdup2(fd, STDOUT_FILENO);
xdup2(fd, STDERR_FILENO); xdup2(fd, STDERR_FILENO);
close(fd); close(fd);
if (post_fs_data && fork_dont_care() == 0)
daemon_saver();
// Block user signals // Block user signals
sigset_t block_set; sigset_t block_set;
sigemptyset(&block_set); sigemptyset(&block_set);
@@ -268,22 +157,17 @@ void start_daemon() {
// Start the log monitor // Start the log monitor
monitor_logs(); monitor_logs();
if ((is_daemon_init = (access(MAGISKTMP, F_OK) == 0))) { if (!post_fs_data && (access(MAGISKTMP, F_OK) == 0)) {
// Restart stuffs if the daemon is restarted // Restart stuffs if the daemon is restarted
exec_command_sync("logcat", "-b", "all", "-c", NULL); exec_command_sync("logcat", "-b", "all", "-c", NULL);
auto_start_magiskhide(); auto_start_magiskhide();
start_debug_log(); start_debug_log();
} else if (check_data()) {
daemon_init();
} }
LOGI("Magisk v" xstr(MAGISK_VERSION) "(" xstr(MAGISK_VER_CODE) ") daemon started\n"); LOGI("Magisk v" xstr(MAGISK_VERSION) "(" xstr(MAGISK_VER_CODE) ") daemon started\n");
// Change process name // Change process name
strcpy(argv0, "magisk_daemon"); strcpy(argv0, "magiskd");
// Unlock all blocks for rw
unlock_blocks();
// Loop forever to listen for requests // Loop forever to listen for requests
while(1) { while(1) {
@@ -297,7 +181,7 @@ void start_daemon() {
} }
/* Connect the daemon, and return a socketfd */ /* Connect the daemon, and return a socketfd */
int connect_daemon() { int connect_daemon(int post_fs_data) {
struct sockaddr_un sun; struct sockaddr_un sun;
int fd = setup_socket(&sun); int fd = setup_socket(&sun);
if (connect(fd, (struct sockaddr*) &sun, sizeof(sun))) { if (connect(fd, (struct sockaddr*) &sun, sizeof(sun))) {
@@ -308,10 +192,10 @@ int connect_daemon() {
exit(1); exit(1);
} }
if (xfork() == 0) { if (fork_dont_care() == 0) {
LOGD("client: connect fail, try launching new daemon process\n"); LOGD("client: connect fail, try launching new daemon process\n");
close(fd); close(fd);
start_daemon(); start_daemon(post_fs_data);
} }
while (connect(fd, (struct sockaddr*) &sun, sizeof(sun))) while (connect(fd, (struct sockaddr*) &sun, sizeof(sun)))

View File

@@ -14,8 +14,7 @@
#include "utils.h" #include "utils.h"
#include "resetprop.h" #include "resetprop.h"
extern int is_daemon_init; int loggable = 1;
int logd = 0;
static int am_proc_start_filter(const char *log) { static int am_proc_start_filter(const char *log) {
return strstr(log, "am_proc_start") != NULL; return strstr(log, "am_proc_start") != NULL;
@@ -49,15 +48,16 @@ struct log_listener log_events[] = {
static int debug_log_pid = -1, debug_log_fd = -1; static int debug_log_pid = -1, debug_log_fd = -1;
#endif #endif
static void check_logd() { static void test_logcat() {
char *prop = getprop("init.svc.logd"); int log_fd = -1, log_pid;
if (prop != NULL) { char buf[1];
free(prop); log_pid = exec_command(0, &log_fd, NULL, "logcat", NULL);
logd = 1; if (read(log_fd, buf, sizeof(buf)) != sizeof(buf)) {
} else { loggable = 0;
LOGD("log_monitor: logd not started, disable logging"); LOGD("log_monitor: cannot read from logcat, disable logging");
logd = 0;
} }
kill(log_pid, SIGTERM);
waitpid(log_pid, NULL, 0);
} }
static void *logger_thread(void *args) { static void *logger_thread(void *args) {
@@ -67,7 +67,7 @@ static void *logger_thread(void *args) {
LOGD("log_monitor: logger start"); LOGD("log_monitor: logger start");
while (1) { while (1) {
if (!logd) { if (!loggable) {
// Disable all services // Disable all services
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) {
close(log_events[i].fd); close(log_events[i].fd);
@@ -98,7 +98,7 @@ static void *logger_thread(void *args) {
// Clear buffer before restart // Clear buffer before restart
exec_command_sync("logcat", "-b", "events", "-b", "main", "-c", NULL); exec_command_sync("logcat", "-b", "events", "-b", "main", "-c", NULL);
check_logd(); test_logcat();
} }
// Should never be here, but well... // Should never be here, but well...
@@ -106,38 +106,20 @@ static void *logger_thread(void *args) {
} }
static void *magisk_log_thread(void *args) { static void *magisk_log_thread(void *args) {
// Buffer logs before we have data access FILE *log = xfopen(LOGFILE, "w");
struct vector logs; setbuf(log, NULL);
vec_init(&logs);
int pipefd[2]; int pipefd[2];
if (xpipe2(pipefd, O_CLOEXEC) == -1) if (xpipe2(pipefd, O_CLOEXEC) == -1)
return NULL; return NULL;
LOGD("log_monitor: magisk log dumper start");
// Register our listener // Register our listener
log_events[LOG_EVENT].fd = pipefd[1]; log_events[LOG_EVENT].fd = pipefd[1];
LOGD("log_monitor: magisk log dumper start"); for (char *line; xxread(pipefd[0], &line, sizeof(line)) > 0; free(line))
fprintf(log, "%s", line);
FILE *log = NULL;
for (char *line; xxread(pipefd[0], &line, sizeof(line)) > 0; free(line)) {
if (!is_daemon_init) {
vec_push_back(&logs, strdup(line));
} else {
if (log == NULL) {
// Dump buffered logs to file
log = xfopen(LOGFILE, "w");
setbuf(log, NULL);
char *tmp;
vec_for_each(&logs, tmp) {
fprintf(log, "%s", tmp);
free(tmp);
}
vec_destroy(&logs);
}
fprintf(log, "%s", line);
}
}
return NULL; return NULL;
} }
@@ -163,9 +145,9 @@ static void *debug_magisk_log_thread(void *args) {
void monitor_logs() { void monitor_logs() {
pthread_t thread; pthread_t thread;
check_logd(); test_logcat();
if (logd) { if (loggable) {
// Start log file dumper before monitor // Start log file dumper before monitor
xpthread_create(&thread, NULL, magisk_log_thread, NULL); xpthread_create(&thread, NULL, magisk_log_thread, NULL);
pthread_detach(thread); pthread_detach(thread);
@@ -178,7 +160,7 @@ void monitor_logs() {
void start_debug_full_log() { void start_debug_full_log() {
#ifdef MAGISK_DEBUG #ifdef MAGISK_DEBUG
if (logd) { if (loggable) {
// Log everything initially // Log everything initially
debug_log_fd = xopen(DEBUG_LOG, O_WRONLY | O_CREAT | O_CLOEXEC | O_TRUNC, 0644); debug_log_fd = xopen(DEBUG_LOG, O_WRONLY | O_CREAT | O_CLOEXEC | O_TRUNC, 0644);
debug_log_pid = exec_command(0, &debug_log_fd, NULL, "logcat", "-v", "threadtime", NULL); debug_log_pid = exec_command(0, &debug_log_fd, NULL, "logcat", "-v", "threadtime", NULL);
@@ -201,7 +183,7 @@ void stop_debug_full_log() {
void start_debug_log() { void start_debug_log() {
#ifdef MAGISK_DEBUG #ifdef MAGISK_DEBUG
if (logd) { if (loggable) {
pthread_t thread; pthread_t thread;
// Start debug thread // Start debug thread
xpthread_create(&thread, NULL, debug_magisk_log_thread, NULL); xpthread_create(&thread, NULL, debug_magisk_log_thread, NULL);

View File

@@ -47,13 +47,14 @@ static void usage() {
" --resizeimg IMG SIZE resize ext4 image. SIZE is interpreted in MB\n" " --resizeimg IMG SIZE resize ext4 image. SIZE is interpreted in MB\n"
" --mountimg IMG PATH mount IMG to PATH and prints the loop device\n" " --mountimg IMG PATH mount IMG to PATH and prints the loop device\n"
" --umountimg PATH LOOP unmount PATH and delete LOOP device\n" " --umountimg PATH LOOP unmount PATH and delete LOOP device\n"
" --[init service] start init service\n" " --daemon manually start magisk daemon\n"
" --[init trigger] start service for init trigger\n"
" --unlock-blocks set BLKROSET flag to OFF for all block devices\n" " --unlock-blocks set BLKROSET flag to OFF for all block devices\n"
" --restorecon fix selinux context on Magisk files and folders\n" " --restorecon fix selinux context on Magisk files and folders\n"
" --clone-attr SRC DEST clone permission, owner, and selinux context\n" " --clone-attr SRC DEST clone permission, owner, and selinux context\n"
"\n" "\n"
"Supported init services:\n" "Supported init triggers:\n"
" daemon, post-fs, post-fs-data, service\n" " startup, post-fs-data, service\n"
"\n" "\n"
"Supported applets:\n" "Supported applets:\n"
, argv0, argv0); , argv0, argv0);
@@ -65,6 +66,7 @@ static void usage() {
} }
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
umask(0);
argv0 = argv[0]; argv0 = argv[0];
if (strcmp(basename(argv[0]), "magisk") == 0) { if (strcmp(basename(argv[0]), "magisk") == 0) {
if (argc < 2) usage(); if (argc < 2) usage();
@@ -72,14 +74,14 @@ int main(int argc, char *argv[]) {
printf("%s (%d)\n", MAGISK_VER_STR, MAGISK_VER_CODE); printf("%s (%d)\n", MAGISK_VER_STR, MAGISK_VER_CODE);
return 0; return 0;
} else if (strcmp(argv[1], "-v") == 0) { } else if (strcmp(argv[1], "-v") == 0) {
int fd = connect_daemon(); int fd = connect_daemon(0);
write_int(fd, CHECK_VERSION); write_int(fd, CHECK_VERSION);
char *v = read_string(fd); char *v = read_string(fd);
printf("%s\n", v); printf("%s\n", v);
free(v); free(v);
return 0; return 0;
} else if (strcmp(argv[1], "-V") == 0) { } else if (strcmp(argv[1], "-V") == 0) {
int fd = connect_daemon(); int fd = connect_daemon(0);
write_int(fd, CHECK_VERSION_CODE); write_int(fd, CHECK_VERSION_CODE);
printf("%d\n", read_int(fd)); printf("%d\n", read_int(fd));
return 0; return 0;
@@ -144,19 +146,18 @@ int main(int argc, char *argv[]) {
clone_attr(argv[2], argv[3]); clone_attr(argv[2], argv[3]);
return 0; return 0;
} else if (strcmp(argv[1], "--daemon") == 0) { } else if (strcmp(argv[1], "--daemon") == 0) {
if (xfork() == 0) int fd = connect_daemon(0);
start_daemon(); close(fd);
return 0;
} else if (strcmp(argv[1], "--startup") == 0) {
startup();
return 0; return 0;
} else if (strcmp(argv[1], "--post-fs") == 0) {
int fd = connect_daemon();
write_int(fd, POST_FS);
return read_int(fd);
} else if (strcmp(argv[1], "--post-fs-data") == 0) { } else if (strcmp(argv[1], "--post-fs-data") == 0) {
int fd = connect_daemon(); int fd = connect_daemon(1);
write_int(fd, POST_FS_DATA); write_int(fd, POST_FS_DATA);
return read_int(fd); return read_int(fd);
} else if (strcmp(argv[1], "--service") == 0) { } else if (strcmp(argv[1], "--service") == 0) {
int fd = connect_daemon(); int fd = connect_daemon(0);
write_int(fd, LATE_START); write_int(fd, LATE_START);
return read_int(fd); return read_int(fd);
} else { } else {

View File

@@ -339,7 +339,7 @@ static void patch_socket_name(const char *path) {
mmap_rw(path, &buf, &size); mmap_rw(path, &buf, &size);
if (SOCKET_OFF < 0) { if (SOCKET_OFF < 0) {
for (int i = 0; i < size; ++i) { for (int i = 0; i < size; ++i) {
if (memcmp(buf + i, socket_name, sizeof(SOCKET_NAME)) == 0) { if (memcmp(buf + i, SOCKET_NAME, sizeof(SOCKET_NAME)) == 0) {
SOCKET_OFF = i; SOCKET_OFF = i;
break; break;
} }
@@ -350,55 +350,6 @@ static void patch_socket_name(const char *path) {
munmap(buf, size); munmap(buf, size);
} }
static void magisk_init_daemon() {
setsid();
// Full patch
sepol_allow("su", ALL, ALL, ALL);
// Wait till init cold boot done
while (access("/dev/.coldboot_done", F_OK))
usleep(1);
int null = open("/dev/null", O_RDWR | O_CLOEXEC);
dup3(null, STDIN_FILENO, O_CLOEXEC);
dup3(null, STDOUT_FILENO, O_CLOEXEC);
dup3(null, STDERR_FILENO, O_CLOEXEC);
if (null > STDERR_FILENO)
close(null);
// Transit our context to su (mimic setcon)
int fd, crap;
fd = open("/proc/self/attr/current", O_WRONLY);
write(fd, "u:r:su:s0", 9);
close(fd);
// Dump full patch to kernel
dump_policydb(SELINUX_LOAD);
close(creat(PATCHDONE, 0));
destroy_policydb();
// Keep Magisk daemon always alive
while (1) {
struct sockaddr_un sun;
fd = setup_socket(&sun);
memcpy(sun.sun_path + 1, RAND_SOCKET_NAME, sizeof(SOCKET_NAME));
while (connect(fd, (struct sockaddr*) &sun, sizeof(sun)))
usleep(10000); /* Wait 10 ms after each try */
/* Should hold forever */
read(fd, &crap, sizeof(crap));
/* If things went here, it means the other side of the socket is closed
* We restart the daemon again */
close(fd);
if (fork_dont_care() == 0) {
execv("/sbin/magisk", (char *[]) { "magisk", "--daemon", NULL } );
exit(1);
}
}
}
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
umask(0); umask(0);
@@ -424,14 +375,8 @@ int main(int argc, char *argv[]) {
if (null > STDERR_FILENO) if (null > STDERR_FILENO)
close(null); close(null);
// Extract and link files // Backup self
mkdir("/overlay", 0000); link("/init", "/init.bak");
dump_magiskrc("/overlay/init.magisk.rc", 0750);
mkdir("/overlay/sbin", 0755);
dump_magisk("/overlay/sbin/magisk", 0755);
patch_socket_name("/overlay/sbin/magisk");
mkdir("/overlay/root", 0755);
link("/init", "/overlay/root/magiskinit");
struct cmdline cmd; struct cmdline cmd;
parse_cmdline(&cmd); parse_cmdline(&cmd);
@@ -444,7 +389,7 @@ int main(int argc, char *argv[]) {
if (cmd.skip_initramfs) { if (cmd.skip_initramfs) {
// Clear rootfs // Clear rootfs
excl_list = (char *[]) { "overlay", ".backup", NULL }; excl_list = (char *[]) { "overlay", ".backup", "init.bak", NULL };
frm_rf(root); frm_rf(root);
} else if (access("/ramdisk.cpio.xz", R_OK) == 0) { } else if (access("/ramdisk.cpio.xz", R_OK) == 0) {
// High compression mode // High compression mode
@@ -513,23 +458,24 @@ int main(int argc, char *argv[]) {
// Only patch rootfs if not intended to run in recovery // Only patch rootfs if not intended to run in recovery
if (access("/etc/recovery.fstab", F_OK) != 0) { if (access("/etc/recovery.fstab", F_OK) != 0) {
int overlay = open("/overlay", O_RDONLY | O_CLOEXEC); int fd;
mv_dir(overlay, root);
close(overlay); // Handle ramdisk overlays
rmdir("/overlay"); fd = open("/overlay", O_RDONLY | O_CLOEXEC);
if (fd >= 0) {
mv_dir(fd, root);
close(fd);
rmdir("/overlay");
}
patch_ramdisk(); patch_ramdisk();
patch_sepolicy(); patch_sepolicy();
close(STDIN_FILENO); // Dump binaries
close(STDOUT_FILENO); dump_magiskrc("/init.magisk.rc", 0750);
close(STDERR_FILENO); dump_magisk("/sbin/magisk", 0755);
patch_socket_name("/sbin/magisk");
if (fork_dont_care() == 0) { rename("/init.bak", "/sbin/magiskinit");
strcpy(argv[0], "magiskinit");
close(root);
magisk_init_daemon();
}
} }
// Clean up // Clean up

View File

@@ -8,7 +8,7 @@
#include "utils.h" #include "utils.h"
#include "magisk.h" #include "magisk.h"
char socket_name[] = SOCKET_NAME; static char socket_name[] = SOCKET_NAME; /* Workaround compiler bug pre NDK r13 */
/* Setup the address and return socket fd */ /* Setup the address and return socket fd */
int setup_socket(struct sockaddr_un *sun) { int setup_socket(struct sockaddr_un *sun) {

View File

@@ -28,6 +28,16 @@ LOCAL_SRC_FILES := \
mincrypt/sha256.c mincrypt/sha256.c
include $(BUILD_STATIC_LIBRARY) include $(BUILD_STATIC_LIBRARY)
# libnanopb.a
include $(CLEAR_VARS)
LOCAL_MODULE:= libnanopb
LOCAL_C_INCLUDES := $(LIBNANOPB)
LOCAL_SRC_FILES := \
nanopb/pb_common.c \
nanopb/pb_decode.c \
nanopb/pb_encode.c
include $(BUILD_STATIC_LIBRARY)
# libfdt.a # libfdt.a
include $(CLEAR_VARS) include $(CLEAR_VARS)
LOCAL_MODULE:= libfdt LOCAL_MODULE:= libfdt

1
native/jni/external/nanopb vendored Submodule

View File

@@ -8,7 +8,9 @@
#include <sys/un.h> #include <sys/un.h>
#include <sys/socket.h> #include <sys/socket.h>
extern int is_daemon_init, seperate_vendor; extern int is_daemon_init;
extern int seperate_vendor;
extern int full_patch_pid;
// Commands require connecting to daemon // Commands require connecting to daemon
enum { enum {
@@ -16,7 +18,6 @@ enum {
SUPERUSER, SUPERUSER,
CHECK_VERSION, CHECK_VERSION,
CHECK_VERSION_CODE, CHECK_VERSION_CODE,
POST_FS,
POST_FS_DATA, POST_FS_DATA,
LATE_START, LATE_START,
LAUNCH_MAGISKHIDE, LAUNCH_MAGISKHIDE,
@@ -31,7 +32,7 @@ enum {
DAEMON_ERROR = -1, DAEMON_ERROR = -1,
DAEMON_SUCCESS = 0, DAEMON_SUCCESS = 0,
ROOT_REQUIRED, ROOT_REQUIRED,
LOGD_DISABLED, LOGCAT_DISABLED,
HIDE_IS_ENABLED, HIDE_IS_ENABLED,
HIDE_NOT_ENABLED, HIDE_NOT_ENABLED,
HIDE_ITEM_EXIST, HIDE_ITEM_EXIST,
@@ -40,10 +41,9 @@ enum {
// daemon.c // daemon.c
void start_daemon(); void start_daemon(int post_fs_data);
int connect_daemon(); int connect_daemon(int post_fs_data);
void auto_start_magiskhide(); void auto_start_magiskhide();
void daemon_init();
// socket.c // socket.c
@@ -59,7 +59,7 @@ void write_string(int fd, const char* val);
* Boot Stages * * Boot Stages *
***************/ ***************/
void post_fs(int client); void startup();
void post_fs_data(int client); void post_fs_data(int client);
void late_start(int client); void late_start(int client);
void fix_filecon(); void fix_filecon();

View File

@@ -58,7 +58,7 @@ struct log_listener {
}; };
extern struct log_listener log_events[]; extern struct log_listener log_events[];
extern int logd; extern int loggable;
void monitor_logs(); void monitor_logs();
void start_debug_full_log(); void start_debug_full_log();

View File

@@ -14,12 +14,9 @@
#endif #endif
#define LOGFILE "/cache/magisk.log" #define LOGFILE "/cache/magisk.log"
#define DEBUG_LOG "/data/adb/magisk_debug.log"
#define UNBLOCKFILE "/dev/.magisk.unblock" #define UNBLOCKFILE "/dev/.magisk.unblock"
#define PATCHDONE "/dev/.magisk.patch.done"
#define DISABLEFILE "/cache/.disable_magisk" #define DISABLEFILE "/cache/.disable_magisk"
#define UNINSTALLER "/cache/magisk_uninstaller.sh" #define UNINSTALLER "/cache/magisk_uninstaller.sh"
#define CACHEMOUNT "/cache/magisk_mount"
#define MAGISKTMP "/sbin/.core" #define MAGISKTMP "/sbin/.core"
#define MIRRDIR MAGISKTMP "/mirror" #define MIRRDIR MAGISKTMP "/mirror"
#define BBPATH MAGISKTMP "/busybox" #define BBPATH MAGISKTMP "/busybox"
@@ -27,8 +24,12 @@
#define COREDIR MOUNTPOINT "/.core" #define COREDIR MOUNTPOINT "/.core"
#define HOSTSFILE COREDIR "/hosts" #define HOSTSFILE COREDIR "/hosts"
#define HIDELIST COREDIR "/hidelist" #define HIDELIST COREDIR "/hidelist"
#define MAINIMG "/data/adb/magisk.img" #define SECURE_DIR "/data/adb/"
#define DATABIN "/data/adb/magisk" #define MAINIMG SECURE_DIR "magisk.img"
#define DATABIN SECURE_DIR "magisk"
#define MAGISKDB SECURE_DIR "magisk.db"
#define SIMPLEMOUNT SECURE_DIR "magisk_simple"
#define DEBUG_LOG SECURE_DIR "magisk_debug.log"
#define MANAGERAPK DATABIN "/magisk.apk" #define MANAGERAPK DATABIN "/magisk.apk"
#define MAGISKRC "/init.magisk.rc" #define MAGISKRC "/init.magisk.rc"
@@ -55,7 +56,6 @@ extern char *argv0; /* For changing process name */
#define init_applet ((char *[]) { "magiskpolicy", "supolicy", NULL }) #define init_applet ((char *[]) { "magiskpolicy", "supolicy", NULL })
extern int (*applet_main[]) (int, char *[]), (*init_applet_main[]) (int, char *[]); extern int (*applet_main[]) (int, char *[]), (*init_applet_main[]) (int, char *[]);
extern char socket_name[]; /* Workaround compiler bug pre NDK r13 */
int create_links(const char *bin, const char *path); int create_links(const char *bin, const char *path);
@@ -63,13 +63,6 @@ int create_links(const char *bin, const char *path);
int magiskhide_main(int argc, char *argv[]); int magiskhide_main(int argc, char *argv[]);
int magiskpolicy_main(int argc, char *argv[]); int magiskpolicy_main(int argc, char *argv[]);
int su_client_main(int argc, char *argv[]); int su_client_main(int argc, char *argv[]);
#ifdef __cplusplus
extern "C" {
#endif
int resetprop_main(int argc, char *argv[]); int resetprop_main(int argc, char *argv[]);
#ifdef __cplusplus
}
#endif
#endif #endif

View File

@@ -1,17 +1,17 @@
#include "magiskpolicy.h"
const char magiskrc[] = const char magiskrc[] =
// Triggers // Triggers
"on post-fs\n" "on post-fs\n"
" start logd\n" " start logd\n"
" start magisk_pfs\n"
" wait /dev/.magisk.unblock 10\n"
"\n" "\n"
"on post-fs-data\n" "on post-fs-data\n"
" load_persist_props\n" " load_persist_props\n"
" rm /dev/.magisk.unblock\n" " rm /dev/.magisk.unblock\n"
" start magisk_pfsd\n" " start magisk_startup\n"
" wait /dev/.magisk.unblock 10\n" " wait /dev/.magisk.unblock 10\n"
" rm /dev/.magisk.unblock\n" " rm /dev/.magisk.unblock\n"
"\n" "\n"
@@ -20,25 +20,19 @@ const char magiskrc[] =
"service magisk_daemon /sbin/magisk --daemon\n" "service magisk_daemon /sbin/magisk --daemon\n"
" user root\n" " user root\n"
" seclabel u:r:su:s0\n" " seclabel u:r:"SEPOL_PROC_DOMAIN":s0\n"
" oneshot\n" " oneshot\n"
"\n" "\n"
"service magisk_pfs /sbin/magisk --post-fs\n" "service magisk_startup /sbin/magisk --startup\n"
" user root\n" " user root\n"
" seclabel u:r:su:s0\n" " seclabel u:r:"SEPOL_PROC_DOMAIN":s0\n"
" oneshot\n" " oneshot\n"
"\n" "\n"
"service magisk_pfsd /sbin/magisk --post-fs-data\n" "service magisk_service /sbin/magisk --service\n"
" user root\n"
" seclabel u:r:su:s0\n"
" oneshot\n"
"\n"
"service magisk_service /sbin/magisk --service\n"
" class late_start\n" " class late_start\n"
" user root\n" " user root\n"
" seclabel u:r:su:s0\n" " seclabel u:r:"SEPOL_PROC_DOMAIN":s0\n"
" oneshot\n" " oneshot\n"
; ;

View File

@@ -4,10 +4,6 @@
#ifndef _RESETPROP_H_ #ifndef _RESETPROP_H_
#define _RESETPROP_H_ #define _RESETPROP_H_
#ifdef __cplusplus
extern "C" {
#endif
int prop_exist(const char *name); int prop_exist(const char *name);
int setprop(const char *name, const char *value); int setprop(const char *name, const char *value);
int setprop2(const char *name, const char *value, const int trigger); int setprop2(const char *name, const char *value, const int trigger);
@@ -16,10 +12,6 @@ char *getprop2(const char *name, int persist);
int deleteprop(const char *name); int deleteprop(const char *name);
int deleteprop2(const char *name, const int persist); int deleteprop2(const char *name, const int persist);
int read_prop_file(const char* filename, const int trigger); int read_prop_file(const char* filename, const int trigger);
void getprop_all(void (*callback)(const char*, const char*)); void getprop_all(void (*callback)(const char *, const char *, void *), void *cookie);
#ifdef __cplusplus
}
#endif
#endif #endif

View File

@@ -122,7 +122,7 @@ int setattrat(int dirfd, const char *pathname, struct file_attr *a);
int fsetattr(int fd, struct file_attr *a); int fsetattr(int fd, struct file_attr *a);
void fclone_attr(const int sourcefd, const int targetfd); void fclone_attr(const int sourcefd, const int targetfd);
void clone_attr(const char *source, const char *target); void clone_attr(const char *source, const char *target);
void restorecon(int dirfd, int force); void restorecon(int dirfd);
int mmap_ro(const char *filename, void **buf, size_t *size); int mmap_ro(const char *filename, void **buf, size_t *size);
int mmap_rw(const char *filename, void **buf, size_t *size); int mmap_rw(const char *filename, void **buf, size_t *size);
void fd_full_read(int fd, void **buf, size_t *size); void fd_full_read(int fd, void **buf, size_t *size);

View File

@@ -168,7 +168,7 @@ int parse_img(const char *image, boot_img *boot) {
if (pos < boot->map_size) { if (pos < boot->map_size) {
boot->tail = head + pos; boot->tail = head + pos;
boot->tail_size = boot->map_size - pos; boot->tail_size = boot->map_size - (boot->tail - boot->map_addr);
} }
// Check tail info, currently only for LG Bump and Samsung SEANDROIDENFORCE // Check tail info, currently only for LG Bump and Samsung SEANDROIDENFORCE

View File

@@ -56,7 +56,7 @@ void hide_sensitive_props() {
} }
} }
static void rm_magisk_prop(const char *name, const char *value) { static void rm_magisk_prop(const char *name, const char *value, void *v) {
if (strstr(name, "magisk")) { if (strstr(name, "magisk")) {
deleteprop2(name, 0); deleteprop2(name, 0);
} }
@@ -64,7 +64,7 @@ static void rm_magisk_prop(const char *name, const char *value) {
void clean_magisk_props() { void clean_magisk_props() {
LOGD("hide_utils: Cleaning magisk props\n"); LOGD("hide_utils: Cleaning magisk props\n");
getprop_all(rm_magisk_prop); getprop_all(rm_magisk_prop, NULL);
} }
int add_list(char *proc) { int add_list(char *proc) {

View File

@@ -49,9 +49,9 @@ void launch_magiskhide(int client) {
return; return;
} }
if (!logd) { if (!loggable) {
if (client > 0) { if (client > 0) {
write_int(client, LOGD_DISABLED); write_int(client, LOGCAT_DISABLED);
close(client); close(client);
} }
setprop(MAGISKHIDE_PROP, "0"); setprop(MAGISKHIDE_PROP, "0");
@@ -135,7 +135,7 @@ int magiskhide_main(int argc, char *argv[]) {
} else { } else {
usage(argv[0]); usage(argv[0]);
} }
int fd = connect_daemon(); int fd = connect_daemon(0);
write_int(fd, req); write_int(fd, req);
if (req == ADD_HIDELIST || req == RM_HIDELIST) { if (req == ADD_HIDELIST || req == RM_HIDELIST) {
write_string(fd, argv[2]); write_string(fd, argv[2]);
@@ -147,14 +147,14 @@ int magiskhide_main(int argc, char *argv[]) {
case ROOT_REQUIRED: case ROOT_REQUIRED:
fprintf(stderr, "Root is required for this operation\n"); fprintf(stderr, "Root is required for this operation\n");
return code; return code;
case LOGD_DISABLED: case LOGCAT_DISABLED:
fprintf(stderr, "Logd is not running, cannot run logcat\n"); fprintf(stderr, "Logcat is disabled, cannot start MagiskHide\n");
return (code); return (code);
case HIDE_NOT_ENABLED: case HIDE_NOT_ENABLED:
fprintf(stderr, "Magisk hide is not enabled yet\n"); fprintf(stderr, "MagiskHide is not enabled yet\n");
return code; return code;
case HIDE_IS_ENABLED: case HIDE_IS_ENABLED:
fprintf(stderr, "Magisk hide is already enabled\n"); fprintf(stderr, "MagiskHide is already enabled\n");
return code; return code;
case HIDE_ITEM_EXIST: case HIDE_ITEM_EXIST:
fprintf(stderr, "Process [%s] already exists in hide list\n", argv[2]); fprintf(stderr, "Process [%s] already exists in hide list\n", argv[2]);

View File

@@ -4,7 +4,6 @@
#include <pthread.h> #include <pthread.h>
#define TERM_THREAD SIGUSR1 #define TERM_THREAD SIGUSR1
#define HIDE_DONE SIGUSR2
// Kill process // Kill process
void kill_proc(int pid); void kill_proc(int pid);

View File

@@ -20,7 +20,7 @@
#include "magiskhide.h" #include "magiskhide.h"
static char init_ns[32], zygote_ns[2][32], cache_block[256]; static char init_ns[32], zygote_ns[2][32], cache_block[256];
static int hide_queue = 0, zygote_num, has_cache = 1, pipefd[2] = { -1, -1 }; static int zygote_num, has_cache = 1, pipefd[2] = { -1, -1 };
// Workaround for the lack of pthread_cancel // Workaround for the lack of pthread_cancel
static void term_thread(int sig) { static void term_thread(int sig) {
@@ -38,17 +38,6 @@ static void term_thread(int sig) {
pthread_exit(NULL); pthread_exit(NULL);
} }
static void hide_done(int sig) {
--hide_queue;
if (hide_queue == 0) {
xmount(NULL, "/", NULL, MS_REMOUNT, NULL);
xsymlink(DATABIN, "/data/magisk");
xsymlink(MAINIMG, "/data/magisk.img");
xsymlink(MOUNTPOINT, "/magisk");
xmount(NULL, "/", NULL, MS_REMOUNT | MS_RDONLY, NULL);
}
}
static int read_namespace(const int pid, char* target, const size_t size) { static int read_namespace(const int pid, char* target, const size_t size) {
char path[32]; char path[32];
snprintf(path, sizeof(path), "/proc/%d/ns/mnt", pid); snprintf(path, sizeof(path), "/proc/%d/ns/mnt", pid);
@@ -72,7 +61,7 @@ static void lazy_unmount(const char* mountpoint) {
LOGD("hide_daemon: Unmounted (%s)\n", mountpoint); LOGD("hide_daemon: Unmounted (%s)\n", mountpoint);
} }
static void hide_daemon(int pid, int ppid) { static void hide_daemon(int pid) {
LOGD("hide_daemon: start unmount for pid=[%d]\n", pid); LOGD("hide_daemon: start unmount for pid=[%d]\n", pid);
strcpy(argv0, "hide_daemon"); strcpy(argv0, "hide_daemon");
@@ -140,9 +129,6 @@ exit:
kill(pid, SIGCONT); kill(pid, SIGCONT);
// Free up memory // Free up memory
vec_destroy(&mount_list); vec_destroy(&mount_list);
// Wait a while and link it back
sleep(10);
kill(ppid, HIDE_DONE);
_exit(0); _exit(0);
} }
@@ -151,7 +137,6 @@ void proc_monitor() {
sigset_t block_set; sigset_t block_set;
sigemptyset(&block_set); sigemptyset(&block_set);
sigaddset(&block_set, TERM_THREAD); sigaddset(&block_set, TERM_THREAD);
sigaddset(&block_set, HIDE_DONE);
pthread_sigmask(SIG_UNBLOCK, &block_set, NULL); pthread_sigmask(SIG_UNBLOCK, &block_set, NULL);
// Register the cancel signal // Register the cancel signal
@@ -159,8 +144,6 @@ void proc_monitor() {
memset(&act, 0, sizeof(act)); memset(&act, 0, sizeof(act));
act.sa_handler = term_thread; act.sa_handler = term_thread;
sigaction(TERM_THREAD, &act, NULL); sigaction(TERM_THREAD, &act, NULL);
act.sa_handler = hide_done;
sigaction(HIDE_DONE, &act, NULL);
cache_block[0] = '\0'; cache_block[0] = '\0';
@@ -219,6 +202,11 @@ void proc_monitor() {
if(ret != 2) if(ret != 2)
continue; continue;
// Allow hiding sub-services of applications
char *colon = strchr(processName, ':');
if (colon)
*colon = '\0';
// Critical region // Critical region
pthread_mutex_lock(&hide_lock); pthread_mutex_lock(&hide_lock);
vec_for_each(hide_list, line) { vec_for_each(hide_list, line) {
@@ -239,23 +227,17 @@ void proc_monitor() {
// Send pause signal ASAP // Send pause signal ASAP
if (kill(pid, SIGSTOP) == -1) continue; if (kill(pid, SIGSTOP) == -1) continue;
// Restore the colon so we can log the actual process name
if (colon)
*colon = ':';
LOGI("proc_monitor: %s (PID=%d ns=%s)\n", processName, pid, ns); LOGI("proc_monitor: %s (PID=%d ns=%s)\n", processName, pid, ns);
xmount(NULL, "/", NULL, MS_REMOUNT, NULL);
unlink("/magisk");
unlink("/data/magisk");
unlink("/data/magisk.img");
unlink(MAGISKRC);
xmount(NULL, "/", NULL, MS_REMOUNT | MS_RDONLY, NULL);
++hide_queue;
/* /*
* The setns system call do not support multithread processes * The setns system call do not support multithread processes
* We have to fork a new process, setns, then do the unmounts * We have to fork a new process, setns, then do the unmounts
*/ */
int selfpid = getpid();
if (fork_dont_care() == 0) if (fork_dont_care() == 0)
hide_daemon(pid, selfpid); hide_daemon(pid);
break; break;
} }

View File

@@ -0,0 +1,31 @@
/* resetprop.h - Internal struct definitions
*/
#ifndef MAGISK_PROPS_H
#define MAGISK_PROPS_H
#include "system_properties.h"
#include "logging.h"
extern int prop_verbose;
#define PRINT_D(...) { LOGD(__VA_ARGS__); if (prop_verbose) fprintf(stderr, __VA_ARGS__); }
#define PRINT_E(...) { LOGE(__VA_ARGS__); fprintf(stderr, __VA_ARGS__); }
struct prop_t {
char *name;
char value[PROP_VALUE_MAX];
};
struct read_cb_t {
void (*func)(const char *name, const char *value, void *cookie);
void *cookie;
};
char *persist_getprop(const char *name);
void persist_getprop_all(struct read_cb_t *read_cb);
bool persist_deleteprop(const char *name);
void collect_props(const char *name, const char *value, void *prop_list);
#endif //MAGISK_PROPS_H

View File

@@ -0,0 +1,252 @@
#include <stdbool.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <pb.h>
#include <pb_decode.h>
#include <pb_encode.h>
#include "_resetprop.h"
#include "utils.h"
#include "vector.h"
#define PERSISTENT_PROPERTY_DIR "/data/property"
/* ***********************************************************************
* Auto generated header and constant definitions compiled from
* android/platform/system/core/master/init/persistent_properties.proto
* using Nanopb's protoc
* Nanopb: https://github.com/nanopb/nanopb
* ***********************************************************************/
/* Automatically generated nanopb header */
/* Generated by nanopb-0.3.9.1 at Sun Apr 22 14:36:22 2018. */
/* @@protoc_insertion_point(includes) */
#if PB_PROTO_HEADER_VERSION != 30
#error Regenerate this file with the current version of nanopb generator.
#endif
/* Struct definitions */
typedef struct _PersistentProperties {
pb_callback_t properties;
/* @@protoc_insertion_point(struct:PersistentProperties) */
} PersistentProperties;
typedef struct _PersistentProperties_PersistentPropertyRecord {
pb_callback_t name;
bool has_value;
char value[92];
/* @@protoc_insertion_point(struct:PersistentProperties_PersistentPropertyRecord) */
} PersistentProperties_PersistentPropertyRecord;
/* Default values for struct fields */
/* Initializer values for message structs */
#define PersistentProperties_init_default {{{NULL}, NULL}}
#define PersistentProperties_PersistentPropertyRecord_init_default {{{NULL}, NULL}, false, ""}
#define PersistentProperties_init_zero {{{NULL}, NULL}}
#define PersistentProperties_PersistentPropertyRecord_init_zero {{{NULL}, NULL}, false, ""}
/* Field tags (for use in manual encoding/decoding) */
#define PersistentProperties_properties_tag 1
#define PersistentProperties_PersistentPropertyRecord_name_tag 1
#define PersistentProperties_PersistentPropertyRecord_value_tag 2
/* Automatically generated nanopb constant definitions */
/* Generated by nanopb-0.3.9.1 at Sun Apr 22 14:36:22 2018. */
/* Struct field encoding specification for nanopb */
const pb_field_t PersistentProperties_PersistentPropertyRecord_fields[3] = {
PB_FIELD( 1, STRING , OPTIONAL, CALLBACK, FIRST, PersistentProperties_PersistentPropertyRecord, name, name, 0),
PB_FIELD( 2, STRING , OPTIONAL, STATIC , OTHER, PersistentProperties_PersistentPropertyRecord, value, name, 0),
PB_LAST_FIELD
};
const pb_field_t PersistentProperties_fields[2] = {
PB_FIELD( 1, MESSAGE , REPEATED, CALLBACK, FIRST, PersistentProperties, properties, properties, &PersistentProperties_PersistentPropertyRecord_fields),
PB_LAST_FIELD
};
/* Maximum encoded size of messages (where known) */
/* PersistentProperties_size depends on runtime parameters */
/* PersistentProperties_PersistentPropertyRecord_size depends on runtime parameters */
/* Message IDs (where set with "msgid" option) */
#ifdef PB_MSGID
#define PROPS_MESSAGES \
#endif
/* @@protoc_insertion_point(eof) */
/* ***************************
* End of auto generated code
* ***************************/
static bool name_decode(pb_istream_t *stream, const pb_field_t *field, void **arg) {
uint8_t *name = xmalloc(stream->bytes_left + 1);
name[stream->bytes_left] = '\0';
if (!pb_read(stream, name, stream->bytes_left))
return false;
*arg = name;
return true;
}
static bool name_encode(pb_ostream_t *stream, const pb_field_t *field, void * const *arg) {
return pb_encode_tag_for_field(stream, field) && pb_encode_string(stream, *arg, strlen(*arg));
}
static bool prop_decode(pb_istream_t *stream, const pb_field_t *field, void **arg) {
PersistentProperties_PersistentPropertyRecord prop = {};
prop.name.funcs.decode = name_decode;
if (!pb_decode(stream, PersistentProperties_PersistentPropertyRecord_fields, &prop))
return false;
struct read_cb_t *read_cb = *arg;
read_cb->func(prop.name.arg, prop.value, read_cb->cookie);
return true;
}
static bool prop_encode(pb_ostream_t *stream, const pb_field_t *field, void * const *arg) {
PersistentProperties_PersistentPropertyRecord prop = {};
prop.name.funcs.encode = name_encode;
prop.has_value = true;
struct vector *v = *arg;
struct prop_t *e;
vec_for_each(v, e) {
if (e == NULL)
continue;
if (!pb_encode_tag_for_field(stream, field))
return false;
prop.name.arg = e->name;
strcpy(prop.value, e->value);
if (!pb_encode_submessage(stream, PersistentProperties_PersistentPropertyRecord_fields, &prop))
return false;
free(e->name);
free(e);
}
return true;
}
static bool write_callback(pb_ostream_t *stream, const uint8_t *buf, size_t count) {
int fd = (intptr_t)stream->state;
return xwrite(fd, buf, count) == count;
}
static pb_ostream_t create_ostream(const char *filename) {
int fd = creat(filename, 0644);
pb_ostream_t o = {&write_callback, (void*)(intptr_t)fd, SIZE_MAX, 0};
return o;
}
static void pb_getprop_cb(const char *name, const char *value, void *v) {
struct prop_t *prop = v;
if (prop->name && strcmp(name, prop->name) == 0) {
strcpy(prop->value, value);
prop->name = NULL;
}
}
void persist_getprop_all(struct read_cb_t *read_cb) {
if (access(PERSISTENT_PROPERTY_DIR "/persistent_properties", R_OK) == 0) {
PRINT_D("resetprop: decode with protobuf from [" PERSISTENT_PROPERTY_DIR "/persistent_properties]\n");
PersistentProperties props = PersistentProperties_init_zero;
props.properties.funcs.decode = prop_decode;
props.properties.arg = read_cb;
uint8_t *buf;
size_t size;
mmap_ro(PERSISTENT_PROPERTY_DIR "/persistent_properties", (void **) &buf, &size);
pb_istream_t stream = pb_istream_from_buffer(buf, size);
pb_decode(&stream, PersistentProperties_fields, &props);
munmap(buf, size);
} else {
DIR *dir = opendir(PERSISTENT_PROPERTY_DIR);
struct dirent *entry;
while ((entry = readdir(dir))) {
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0 )
continue;
char *value = persist_getprop(entry->d_name);
if (value) {
read_cb->func(strdup(entry->d_name), value, read_cb->cookie);
free(value);
}
}
}
}
char *persist_getprop(const char *name) {
struct prop_t prop;
prop.name = (char *) name;
if (access(PERSISTENT_PROPERTY_DIR "/persistent_properties", R_OK) == 0) {
struct read_cb_t read_cb = {
.func = pb_getprop_cb,
.cookie = &prop
};
persist_getprop_all(&read_cb);
if (prop.name)
return NULL;
} else {
// Try to read from file
char path[PATH_MAX];
snprintf(path, sizeof(path), PERSISTENT_PROPERTY_DIR "/%s", name);
int fd = open(path, O_RDONLY | O_CLOEXEC);
if (fd < 0)
return NULL;
PRINT_D("resetprop: read prop from [%s]\n", path);
prop.value[read(fd, prop.value, sizeof(PROP_VALUE_MAX))] = '\0'; // Null terminate the read value
close(fd);
}
return strdup(prop.value);
}
bool persist_deleteprop(const char *name) {
if (access(PERSISTENT_PROPERTY_DIR "/persistent_properties", R_OK) == 0) {
struct vector v;
vec_init(&v);
struct read_cb_t read_cb = {
.func = collect_props,
.cookie = &v
};
persist_getprop_all(&read_cb);
struct prop_t *p;
bool reencode = false;
vec_for_each(&v, p) {
if (strcmp(p->name, name) == 0) {
// Remove the prop from the list
free(p->name);
free(p);
vec_cur(&v) = NULL;
reencode = true;
break;
}
}
if (reencode) {
// Dump the props back
PersistentProperties props = PersistentProperties_init_zero;
pb_ostream_t ostream = create_ostream(PERSISTENT_PROPERTY_DIR "/persistent_properties.tmp");
props.properties.funcs.encode = prop_encode;
props.properties.arg = &v;
PRINT_D("resetprop: encode with protobuf to [" PERSISTENT_PROPERTY_DIR "/persistent_properties.tmp]\n");
if (!pb_encode(&ostream, PersistentProperties_fields, &props))
return false;
clone_attr(PERSISTENT_PROPERTY_DIR "/persistent_properties", PERSISTENT_PROPERTY_DIR "/persistent_properties.tmp");
rename(PERSISTENT_PROPERTY_DIR "/persistent_properties.tmp", PERSISTENT_PROPERTY_DIR "/persistent_properties");
}
vec_destroy(&v);
return reencode;
} else {
char path[PATH_MAX];
snprintf(path, sizeof(path), PERSISTENT_PROPERTY_DIR "/%s", name);
if (unlink(path) == 0) {
PRINT_D("resetprop: unlink [%s]\n", path);
return true;
}
}
return false;
}

View File

@@ -2,52 +2,6 @@
* *
* Copyright 2016 nkk71 <nkk71x@gmail.com> * Copyright 2016 nkk71 <nkk71x@gmail.com>
* Copyright 2016 topjohnwu <topjohnwu@gmail.com> * Copyright 2016 topjohnwu <topjohnwu@gmail.com>
*
* Info:
*
* all changes are in
*
* bionic/libc/bionic/system_properties.cpp
*
* Functions that need to be patched/added in system_properties.cpp
*
* int __system_properties_init2()
* on android 7, first tear down the everything then let it initialize again:
* if (initialized) {
* //list_foreach(contexts, [](context_node* l) { l->reset_access(); });
* //return 0;
* free_and_unmap_contexts();
* initialized = false;
* }
*
*
* static prop_area* map_prop_area(const char* filename, bool is_legacy)
* we dont want this read only so change: 'O_RDONLY' to 'O_RDWR'
*
* static prop_area* map_fd_ro(const int fd)
* we dont want this read only so change: 'PROT_READ' to 'PROT_READ | PROT_WRITE'
*
*
* Copy the code of prop_info *prop_area::find_property, and modify to delete props
* const prop_info *prop_area::find_property_and_del(prop_bt *const trie, const char *name)
* {
* ...
* ... Do not alloc a new prop_bt here, remove all code involve alloc_if_needed
* ...
*
* if (prop_offset != 0) {
* atomic_store_explicit(&current->prop, 0, memory_order_release); // Add this line to nullify the prop entry
* return to_prop_info(&current->prop);
* } else {
*
* ....
* }
*
*
* by patching just those functions directly, all other functions should be ok
* as is.
*
*
*/ */
#include <stdio.h> #include <stdio.h>
@@ -65,15 +19,11 @@
#include "magisk.h" #include "magisk.h"
#include "resetprop.h" #include "resetprop.h"
extern "C" { #include "_resetprop.h"
#include "vector.h" #include "vector.h"
} #include "utils.h"
#define PRINT_D(...) { LOGD(__VA_ARGS__); if (verbose) fprintf(stderr, __VA_ARGS__); } int prop_verbose = 0;
#define PRINT_E(...) { LOGE(__VA_ARGS__); fprintf(stderr, __VA_ARGS__); }
#define PERSISTENT_PROPERTY_DIR "/data/property"
static int verbose = 0;
static int check_legal_property_name(const char *name) { static int check_legal_property_name(const char *name) {
int namelen = strlen(name); int namelen = strlen(name);
@@ -129,6 +79,49 @@ static int usage(char* arg0) {
return 1; return 1;
} }
// The callback passes to __system_property_read_callback2, actually runs the callback in read_cb
static void callback_wrapper(void *read_cb, const char *name, const char *value, uint32_t serial) {
((struct read_cb_t *) read_cb)->func(name, value, ((struct read_cb_t *) read_cb)->cookie);
}
/* **********************************
* Callback functions for read_cb_t
* **********************************/
void collect_props(const char *name, const char *value, void *prop_list) {
struct prop_t *p = (struct prop_t *) xmalloc(sizeof(*p));
p->name = strdup(name);
strcpy(p->value, value);
vec_push_back(prop_list, p);
}
static void collect_unique_props(const char *name, const char *value, void *prop_list) {
struct vector *v = prop_list;
struct prop_t *p;
bool uniq = true;
vec_for_each(v, p) {
if (strcmp(name, p->name) == 0) {
uniq = 0;
break;
}
}
if (uniq)
collect_props(name, value, prop_list);
}
static void store_prop_value(const char *name, const char *value, void *dst) {
strcpy(dst, value);
}
static void prop_foreach_cb(const prop_info* pi, void* read_cb) {
__system_property_read_callback2(pi, callback_wrapper, read_cb);
}
// Comparision function used to sort prop vectors
static int prop_cmp(const void *p1, const void *p2) {
return strcmp(((struct prop_t *) p1)->name, ((struct prop_t *) p2)->name);
}
static int init_resetprop() { static int init_resetprop() {
if (__system_properties_init2()) { if (__system_properties_init2()) {
PRINT_E("resetprop: Initialize error\n"); PRINT_E("resetprop: Initialize error\n");
@@ -137,16 +130,36 @@ static int init_resetprop() {
return 0; return 0;
} }
static void print_props(int persist) {
struct prop_t *p;
struct vector prop_list;
vec_init(&prop_list);
getprop_all(collect_props, &prop_list);
if (persist) {
struct read_cb_t read_cb = {
.func = collect_unique_props,
.cookie = &prop_list
};
persist_getprop_all(&read_cb);
}
vec_sort(&prop_list, prop_cmp);
vec_for_each(&prop_list, p) {
printf("[%s]: [%s]\n", p->name, p->value);
free(p->name);
free(p);
}
vec_destroy(&prop_list);
}
/* **************************************************
* Implementations of functions in resetprop.h (APIs)
* **************************************************/
int prop_exist(const char *name) { int prop_exist(const char *name) {
if (init_resetprop()) return 0; if (init_resetprop()) return 0;
return __system_property_find2(name) != NULL; return __system_property_find2(name) != NULL;
} }
static void read_prop_info(void* cookie, const char *name, const char *value, uint32_t serial) {
strcpy((char *) cookie, value);
}
char *getprop(const char *name) { char *getprop(const char *name) {
return getprop2(name, 0); return getprop2(name, 0);
} }
@@ -155,103 +168,35 @@ char *getprop(const char *name) {
char *getprop2(const char *name, int persist) { char *getprop2(const char *name, int persist) {
if (check_legal_property_name(name)) if (check_legal_property_name(name))
return NULL; return NULL;
char value[PROP_VALUE_MAX];
if (init_resetprop()) return NULL; if (init_resetprop()) return NULL;
const prop_info *pi = __system_property_find2(name); const prop_info *pi = __system_property_find2(name);
if (pi == NULL) { if (pi == NULL) {
if (persist && strncmp(name, "persist.", 8) == 0) { if (persist && strncmp(name, "persist.", 8) == 0) {
// Try to read from file char *value = persist_getprop(name);
char path[PATH_MAX]; if (value)
snprintf(path, sizeof(path), PERSISTENT_PROPERTY_DIR "/%s", name); return value;
int fd = open(path, O_RDONLY | O_CLOEXEC); }
if (fd < 0) goto no_prop;
PRINT_D("resetprop: read prop from [%s]\n", path);
size_t len = read(fd, value, sizeof(value));
value[len] = '\0'; // Null terminate the read value
} else {
no_prop:
PRINT_D("resetprop: prop [%s] does not exist\n", name); PRINT_D("resetprop: prop [%s] does not exist\n", name);
return NULL; return NULL;
}
} else { } else {
__system_property_read_callback2(pi, read_prop_info, value); char value[PROP_VALUE_MAX];
struct read_cb_t read_cb = {
.func = store_prop_value,
.cookie = value
};
__system_property_read_callback2(pi, callback_wrapper, &read_cb);
PRINT_D("resetprop: getprop [%s]: [%s]\n", name, value);
return strdup(value);
} }
PRINT_D("resetprop: getprop [%s]: [%s]\n", name, value);
return strdup(value);
} }
struct wrapper { void getprop_all(void (*callback)(const char *, const char *, void *), void *cookie) {
void (*func)(const char *, const char *);
};
static void cb_wrapper(void* cookie, const char *name, const char *value, uint32_t serial) {
((wrapper *) cookie)->func(name, value);
}
static void prop_foreach_cb(const prop_info* pi, void* cookie) {
__system_property_read_callback2(pi, cb_wrapper, cookie);
}
class property {
public:
property(const char *n, const char *v) {
name = strdup(n);
value = strdup(v);
}
~property() {
free((void *)name);
free((void *)value);
}
const char *name;
const char *value;
};
vector prop_list;
static int prop_cmp(const void *p1, const void *p2) {
return strcmp(((property *) p1)->name, ((property *) p2)->name);
}
static void print_all_props_cb(const char *name, const char *value) {
vec_push_back(&prop_list, new property(name, value));
}
static void print_all_props(int persist) {
void *p;
vec_init(&prop_list);
getprop_all(print_all_props_cb);
if (persist) {
// Check all persist props in data
DIR *dir = opendir(PERSISTENT_PROPERTY_DIR);
struct dirent *entry;
while ((entry = readdir(dir))) {
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0 )
continue;
int found = 0;
vec_for_each(&prop_list, p) {
if (strcmp(((property *) p)->name, entry->d_name) == 0) {
found = 1;
break;
}
}
if (!found)
vec_push_back(&prop_list, new property(entry->d_name, getprop2(entry->d_name, 1)));
}
}
vec_sort(&prop_list, prop_cmp);
vec_for_each(&prop_list, p) {
printf("[%s]: [%s]\n", ((property *) p)->name, ((property *) p)->value);
delete((property *) p);
}
vec_destroy(&prop_list);
}
void getprop_all(void (*callback)(const char*, const char*)) {
if (init_resetprop()) return; if (init_resetprop()) return;
struct wrapper wrap = { struct read_cb_t read_cb = {
.func = callback .func = callback,
.cookie = cookie
}; };
__system_property_foreach2(prop_foreach_cb, &wrap); __system_property_foreach2(prop_foreach_cb, &read_cb);
} }
int setprop(const char *name, const char *value) { int setprop(const char *name, const char *value) {
@@ -294,7 +239,7 @@ int deleteprop(const char *name) {
return deleteprop2(name, 1); return deleteprop2(name, 1);
} }
int deleteprop2(const char *name, const int persist) { int deleteprop2(const char *name, int persist) {
if (check_legal_property_name(name)) if (check_legal_property_name(name))
return 1; return 1;
if (init_resetprop()) return -1; if (init_resetprop()) return -1;
@@ -302,8 +247,8 @@ int deleteprop2(const char *name, const int persist) {
path[0] = '\0'; path[0] = '\0';
PRINT_D("resetprop: deleteprop [%s]\n", name); PRINT_D("resetprop: deleteprop [%s]\n", name);
if (persist && strncmp(name, "persist.", 8) == 0) if (persist && strncmp(name, "persist.", 8) == 0)
snprintf(path, sizeof(path), PERSISTENT_PROPERTY_DIR "/%s", name); persist = persist_deleteprop(name);
return __system_property_del(name) && unlink(path); return __system_property_del(name) && !(persist && strncmp(name, "persist.", 8) == 0);
} }
int read_prop_file(const char* filename, const int trigger) { int read_prop_file(const char* filename, const int trigger) {
@@ -336,7 +281,7 @@ int read_prop_file(const char* filename, const int trigger) {
} }
if (comment) continue; if (comment) continue;
pch = strchr(line, '='); pch = strchr(line, '=');
// Ignore ivalid formats // Ignore invalid formats
if ( ((pch == NULL) || (i >= (pch - line))) || (pch >= line + read - 1) ) continue; if ( ((pch == NULL) || (i >= (pch - line))) || (pch >= line + read - 1) ) continue;
// Separate the string // Separate the string
*pch = '\0'; *pch = '\0';
@@ -367,7 +312,7 @@ int resetprop_main(int argc, char *argv[]) {
goto usage; goto usage;
} }
case 'v': case 'v':
verbose = 1; prop_verbose = 1;
continue; continue;
case 'p': case 'p':
persist = 1; persist = 1;
@@ -390,7 +335,7 @@ int resetprop_main(int argc, char *argv[]) {
switch (argc) { switch (argc) {
case 0: case 0:
print_all_props(persist); print_props(persist);
return 0; return 0;
case 1: case 1:
prop = getprop2(argv[0], persist); prop = getprop2(argv[0], persist);

View File

@@ -153,7 +153,7 @@ class prop_area {
} }
const prop_info* find(const char* name); const prop_info* find(const char* name);
bool del(const char *name); // resetprop add bool del(const char *name); /* resetprop add */
bool add(const char* name, unsigned int namelen, const char* value, unsigned int valuelen); bool add(const char* name, unsigned int namelen, const char* value, unsigned int valuelen);
bool foreach (void (*propfn)(const prop_info* pi, void* cookie), void* cookie); bool foreach (void (*propfn)(const prop_info* pi, void* cookie), void* cookie);
@@ -184,7 +184,7 @@ class prop_area {
const prop_info* find_property(prop_bt* const trie, const char* name, uint32_t namelen, const prop_info* find_property(prop_bt* const trie, const char* name, uint32_t namelen,
const char* value, uint32_t valuelen, bool alloc_if_needed); const char* value, uint32_t valuelen, bool alloc_if_needed);
bool find_property_and_del(prop_bt *const trie, const char *name); // resetprop add bool find_property_and_del(prop_bt *const trie, const char *name); /* resetprop add */
bool foreach_property(prop_bt* const trie, void (*propfn)(const prop_info* pi, void* cookie), bool foreach_property(prop_bt* const trie, void (*propfn)(const prop_info* pi, void* cookie),
void* cookie); void* cookie);
@@ -283,7 +283,8 @@ static prop_area* map_prop_area_rw(const char* filename, const char* context,
return pa; return pa;
} }
static prop_area* map_fd_ro(const int fd) { // resetprop: map the memory as rw
static prop_area* map_fd_rw(const int fd) {
struct stat fd_stat; struct stat fd_stat;
if (fstat(fd, &fd_stat) < 0) { if (fstat(fd, &fd_stat) < 0) {
return nullptr; return nullptr;
@@ -298,7 +299,7 @@ static prop_area* map_fd_ro(const int fd) {
pa_size = fd_stat.st_size; pa_size = fd_stat.st_size;
pa_data_size = pa_size - sizeof(prop_area); pa_data_size = pa_size - sizeof(prop_area);
void* const map_result = mmap(nullptr, pa_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); // resetprop: add PROT_WRITE void* const map_result = mmap(nullptr, pa_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); /* resetprop: add PROT_WRITE */
if (map_result == MAP_FAILED) { if (map_result == MAP_FAILED) {
return nullptr; return nullptr;
} }
@@ -313,10 +314,10 @@ static prop_area* map_fd_ro(const int fd) {
} }
static prop_area* map_prop_area(const char* filename) { static prop_area* map_prop_area(const char* filename) {
int fd = open(filename, O_CLOEXEC | O_NOFOLLOW | O_RDWR); // resetprop: O_RDONLY -> O_RDWR int fd = open(filename, O_CLOEXEC | O_NOFOLLOW | O_RDWR); /* resetprop: O_RDONLY -> O_RDWR */
if (fd == -1) return nullptr; if (fd == -1) return nullptr;
prop_area* map_result = map_fd_ro(fd); prop_area* map_result = map_fd_rw(fd);
close(fd); close(fd);
return map_result; return map_result;
@@ -530,7 +531,7 @@ bool prop_area::find_property_and_del(prop_bt* const trie, const char* name) {
uint_least32_t prop_offset = atomic_load_explicit(&current->prop, memory_order_relaxed); uint_least32_t prop_offset = atomic_load_explicit(&current->prop, memory_order_relaxed);
if (prop_offset != 0) { if (prop_offset != 0) {
atomic_store_explicit(&current->prop, 0, memory_order_release); // resetprop: nullify the offset to delete the prop atomic_store_explicit(&current->prop, 0, memory_order_release);
return true; return true;
} else { } else {
return false; return false;
@@ -1116,17 +1117,16 @@ static bool initialize_properties() {
if (!initialize_properties_from_file("/system/etc/selinux/plat_property_contexts")) { if (!initialize_properties_from_file("/system/etc/selinux/plat_property_contexts")) {
return false; return false;
} }
if (!initialize_properties_from_file("/vendor/etc/selinux/nonplat_property_contexts") // Don't check for failure here, so we always have a sane list of properties.
&& !initialize_properties_from_file("/vendor/etc/selinux/vendor_property_contexts")) { // E.g. In case of recovery, the vendor partition will not have mounted and we
return false; // still need the system / platform properties to function.
} initialize_properties_from_file("/vendor/etc/selinux/nonplat_property_contexts") ||
initialize_properties_from_file("/vendor/etc/selinux/vendor_property_contexts");
} else { } else {
if (!initialize_properties_from_file("/plat_property_contexts")) { if (!initialize_properties_from_file("/plat_property_contexts")) {
return false; return false;
} }
if (!initialize_properties_from_file("/nonplat_property_contexts")) { initialize_properties_from_file("/nonplat_property_contexts");
return false;
}
} }
return true; return true;

View File

@@ -344,7 +344,7 @@ void fclone_attr(const int sourcefd, const int targetfd) {
#define UNLABEL_CON "u:object_r:unlabeled:s0" #define UNLABEL_CON "u:object_r:unlabeled:s0"
#define SYSTEM_CON "u:object_r:system_file:s0" #define SYSTEM_CON "u:object_r:system_file:s0"
void restorecon(int dirfd, int force) { void restorecon(int dirfd) {
struct dirent *entry; struct dirent *entry;
DIR *dir; DIR *dir;
int fd; int fd;
@@ -352,7 +352,7 @@ void restorecon(int dirfd, int force) {
fd_getpath(dirfd, path, sizeof(path)); fd_getpath(dirfd, path, sizeof(path));
lgetfilecon(path, &con); lgetfilecon(path, &con);
if (force || strlen(con) == 0 || strcmp(con, UNLABEL_CON) == 0) if (strlen(con) == 0 || strcmp(con, UNLABEL_CON) == 0)
lsetfilecon(path, SYSTEM_CON); lsetfilecon(path, SYSTEM_CON);
freecon(con); freecon(con);
@@ -362,12 +362,12 @@ void restorecon(int dirfd, int force) {
continue; continue;
if (entry->d_type == DT_DIR) { if (entry->d_type == DT_DIR) {
fd = xopenat(dirfd, entry->d_name, O_RDONLY | O_CLOEXEC); fd = xopenat(dirfd, entry->d_name, O_RDONLY | O_CLOEXEC);
restorecon(fd, force); restorecon(fd);
} else { } else {
fd = xopenat(dirfd, entry->d_name, O_PATH | O_NOFOLLOW | O_CLOEXEC); fd = xopenat(dirfd, entry->d_name, O_PATH | O_NOFOLLOW | O_CLOEXEC);
fd_getpath(fd, path, sizeof(path)); fd_getpath(fd, path, sizeof(path));
lgetfilecon(path, &con); lgetfilecon(path, &con);
if (force || strlen(con) == 0 || strcmp(con, UNLABEL_CON) == 0) if (strlen(con) == 0 || strcmp(con, UNLABEL_CON) == 0)
lsetfilecon(path, SYSTEM_CON); lsetfilecon(path, SYSTEM_CON);
freecon(con); freecon(con);
} }
@@ -379,7 +379,7 @@ void restorecon(int dirfd, int force) {
static int _mmap(int rw, const char *filename, void **buf, size_t *size) { static int _mmap(int rw, const char *filename, void **buf, size_t *size) {
struct stat st; struct stat st;
int fd = xopen(filename, rw ? O_RDWR : O_RDONLY); int fd = xopen(filename, (rw ? O_RDWR : O_RDONLY) | O_CLOEXEC);
fstat(fd, &st); fstat(fd, &st);
if (S_ISBLK(st.st_mode)) if (S_ISBLK(st.st_mode))
ioctl(fd, BLKGETSIZE64, size); ioctl(fd, BLKGETSIZE64, size);
@@ -407,7 +407,7 @@ void fd_full_read(int fd, void **buf, size_t *size) {
} }
void full_read(const char *filename, void **buf, size_t *size) { void full_read(const char *filename, void **buf, size_t *size) {
int fd = xopen(filename, O_RDONLY); int fd = xopen(filename, O_RDONLY | O_CLOEXEC);
if (fd < 0) { if (fd < 0) {
*buf = NULL; *buf = NULL;
*size = 0; *size = 0;
@@ -418,7 +418,7 @@ void full_read(const char *filename, void **buf, size_t *size) {
} }
void full_read_at(int dirfd, const char *filename, void **buf, size_t *size) { void full_read_at(int dirfd, const char *filename, void **buf, size_t *size) {
int fd = xopenat(dirfd, filename, O_RDONLY); int fd = xopenat(dirfd, filename, O_RDONLY | O_CLOEXEC);
if (fd < 0) { if (fd < 0) {
*buf = NULL; *buf = NULL;
*size = 0; *size = 0;

View File

@@ -84,7 +84,7 @@ chmod -R 755 .
CHROMEOS=false CHROMEOS=false
ui_print "- Unpacking boot image" ui_print "- Unpacking boot image"
./magiskboot --unpack "$BOOTIMAGE" eval $LIB32PFX ./magiskboot --unpack "$BOOTIMAGE"
case $? in case $? in
1 ) 1 )
@@ -113,14 +113,14 @@ esac
# Test patch status and do restore, after this section, ramdisk.cpio.orig is guaranteed to exist # Test patch status and do restore, after this section, ramdisk.cpio.orig is guaranteed to exist
ui_print "- Checking ramdisk status" ui_print "- Checking ramdisk status"
MAGISK_PATCHED=false MAGISK_PATCHED=false
./magiskboot --cpio ramdisk.cpio test eval $LIB32PFX ./magiskboot --cpio ramdisk.cpio test
case $? in case $? in
0 ) # Stock boot 0 ) # Stock boot
ui_print "- Stock boot image detected" ui_print "- Stock boot image detected"
ui_print "- Backing up stock boot image" ui_print "- Backing up stock boot image"
SHA1=`./magiskboot --sha1 "$BOOTIMAGE" 2>/dev/null` SHA1=`eval $LIB32PFX ./magiskboot --sha1 "$BOOTIMAGE" 2>/dev/null`
STOCKDUMP=stock_boot_${SHA1}.img.gz STOCKDUMP=stock_boot_${SHA1}.img.gz
./magiskboot --compress "$BOOTIMAGE" $STOCKDUMP eval $LIB32PFX ./magiskboot --compress "$BOOTIMAGE" $STOCKDUMP
cp -af ramdisk.cpio ramdisk.cpio.orig cp -af ramdisk.cpio ramdisk.cpio.orig
;; ;;
1 ) # Magisk patched 1 ) # Magisk patched
@@ -140,8 +140,8 @@ esac
if $MAGISK_PATCHED; then if $MAGISK_PATCHED; then
ui_print "- Magisk patched image detected" ui_print "- Magisk patched image detected"
# Find SHA1 of stock boot image # Find SHA1 of stock boot image
[ -z $SHA1 ] && SHA1=`./magiskboot --cpio ramdisk.cpio sha1 2>/dev/null` [ -z $SHA1 ] && SHA1=`eval $LIB32PFX ./magiskboot --cpio ramdisk.cpio sha1 2>/dev/null`
./magiskboot --cpio ramdisk.cpio restore eval $LIB32PFX ./magiskboot --cpio ramdisk.cpio restore
cp -af ramdisk.cpio ramdisk.cpio.orig cp -af ramdisk.cpio ramdisk.cpio.orig
fi fi
@@ -156,9 +156,9 @@ fi
ui_print "- Patching ramdisk" ui_print "- Patching ramdisk"
./magiskboot --cpio ramdisk.cpio \ eval $LIB32PFX ./magiskboot --cpio ramdisk.cpio \
'add 750 init magiskinit' \ \"add 750 init magiskinit\" \
"magisk ramdisk.cpio.orig $HIGHCOMP $KEEPVERITY $KEEPFORCEENCRYPT $SHA1" \"magisk ramdisk.cpio.orig $HIGHCOMP $KEEPVERITY $KEEPFORCEENCRYPT $SHA1\"
rm -f ramdisk.cpio.orig rm -f ramdisk.cpio.orig
@@ -167,17 +167,17 @@ rm -f ramdisk.cpio.orig
########################################################################################## ##########################################################################################
if ! $KEEPVERITY && [ -f dtb ]; then if ! $KEEPVERITY && [ -f dtb ]; then
./magiskboot --dtb-patch dtb && ui_print "- Patching fstab in dtb to remove dm-verity" eval $LIB32PFX ./magiskboot --dtb-patch dtb && ui_print "- Patching fstab in dtb to remove dm-verity"
fi fi
if [ -f kernel ]; then if [ -f kernel ]; then
# Remove Samsung RKP in stock kernel # Remove Samsung RKP in stock kernel
./magiskboot --hexpatch kernel \ eval $LIB32PFX ./magiskboot --hexpatch kernel \
49010054011440B93FA00F71E9000054010840B93FA00F7189000054001840B91FA00F7188010054 \ 49010054011440B93FA00F71E9000054010840B93FA00F7189000054001840B91FA00F7188010054 \
A1020054011440B93FA00F7140020054010840B93FA00F71E0010054001840B91FA00F7181010054 A1020054011440B93FA00F7140020054010840B93FA00F71E0010054001840B91FA00F7181010054
# skip_initramfs -> want_initramfs # skip_initramfs -> want_initramfs
./magiskboot --hexpatch kernel \ eval $LIB32PFX ./magiskboot --hexpatch kernel \
736B69705F696E697472616D6673 \ 736B69705F696E697472616D6673 \
77616E745F696E697472616D6673 77616E745F696E697472616D6673
fi fi
@@ -187,9 +187,9 @@ fi
########################################################################################## ##########################################################################################
ui_print "- Repacking boot image" ui_print "- Repacking boot image"
./magiskboot --repack "$BOOTIMAGE" || abort "! Unable to repack boot image!" eval $LIB32PFX ./magiskboot --repack "$BOOTIMAGE" || abort "! Unable to repack boot image!"
# Sign chromeos boot # Sign chromeos boot
$CHROMEOS && sign_chromeos $CHROMEOS && sign_chromeos
./magiskboot --cleanup eval $LIB32PFX ./magiskboot --cleanup

View File

@@ -69,7 +69,7 @@ api_level_arch_detect
ui_print "- Device platform: $ARCH" ui_print "- Device platform: $ARCH"
BINDIR=$INSTALLER/$ARCH BINDIR=$INSTALLER/$ARCH32
chmod -R 755 $CHROMEDIR $BINDIR chmod -R 755 $CHROMEDIR $BINDIR
# Check if system root is installed and remove # Check if system root is installed and remove
@@ -105,7 +105,7 @@ chmod -R 755 $MAGISKBIN
if [ -d /system/addon.d ]; then if [ -d /system/addon.d ]; then
ui_print "- Adding addon.d survival script" ui_print "- Adding addon.d survival script"
mount -o rw,remount /system mount -o rw,remount /system
cp -af $INSTALLER/addon.d/99-magisk.sh /system/addon.d/99-magisk.sh cp -af $INSTALLER/common/99-magisk.sh /system/addon.d/99-magisk.sh
chmod 755 /system/addon.d/99-magisk.sh chmod 755 /system/addon.d/99-magisk.sh
fi fi

View File

@@ -45,7 +45,7 @@ cd $MAGISKBIN
ui_print "- Found Boot Image: $BOOTIMAGE" ui_print "- Found Boot Image: $BOOTIMAGE"
ui_print "- Unpacking boot image" ui_print "- Unpacking boot image"
./magiskboot --unpack "$BOOTIMAGE" eval $LIB32PFX ./magiskboot --unpack "$BOOTIMAGE"
CHROMEOS=false CHROMEOS=false
case $? in case $? in
@@ -67,7 +67,7 @@ esac
# Detect boot image state # Detect boot image state
ui_print "- Checking ramdisk status" ui_print "- Checking ramdisk status"
./magiskboot --cpio ramdisk.cpio test eval $LIB32PFX ./magiskboot --cpio ramdisk.cpio test
case $? in case $? in
0 ) # Stock boot 0 ) # Stock boot
ui_print "- Stock boot image detected" ui_print "- Stock boot image detected"
@@ -76,14 +76,14 @@ case $? in
1|2 ) # Magisk patched 1|2 ) # Magisk patched
ui_print "- Magisk patched image detected" ui_print "- Magisk patched image detected"
# Find SHA1 of stock boot image # Find SHA1 of stock boot image
[ -z $SHA1 ] && SHA1=`./magiskboot --cpio ramdisk.cpio sha1 2>/dev/null` [ -z $SHA1 ] && SHA1=`eval $LIB32PFX ./magiskboot --cpio ramdisk.cpio sha1 2>/dev/null`
OK=false OK=false
[ ! -z $SHA1 ] && restore_imgs $SHA1 && OK=true [ ! -z $SHA1 ] && restore_imgs $SHA1 && OK=true
if ! $OK; then if ! $OK; then
ui_print "! Boot image backup unavailable" ui_print "! Boot image backup unavailable"
ui_print "- Restoring ramdisk with internal backup" ui_print "- Restoring ramdisk with internal backup"
./magiskboot --cpio ramdisk.cpio restore eval $LIB32PFX ./magiskboot --cpio ramdisk.cpio restore
./magiskboot --repack $BOOTIMAGE eval $LIB32PFX ./magiskboot --repack $BOOTIMAGE
# Sign chromeos boot # Sign chromeos boot
$CHROMEOS && sign_chromeos $CHROMEOS && sign_chromeos
flash_boot_image new-boot.img "$BOOTIMAGE" flash_boot_image new-boot.img "$BOOTIMAGE"

View File

@@ -20,7 +20,7 @@ MAGISKBIN=/data/adb/magisk
[ -z $MOUNTPATH ] && MOUNTPATH=/sbin/.core/img [ -z $MOUNTPATH ] && MOUNTPATH=/sbin/.core/img
[ -z $IMG ] && IMG=/data/adb/magisk.img [ -z $IMG ] && IMG=/data/adb/magisk.img
BOOTSIGNER="/system/bin/dalvikvm -Xnodex2oat -Xnoimage-dex2oat -cp \$APK com.topjohnwu.magisk.utils.BootSigner" BOOTSIGNER="eval \$LIBPFX /system/bin/dalvikvm -Xnodex2oat -Xnoimage-dex2oat -cp \$APK com.topjohnwu.magisk.utils.BootSigner"
BOOTSIGNED=false BOOTSIGNED=false
get_outfd() { get_outfd() {
@@ -128,15 +128,15 @@ find_boot_image() {
run_migrations() { 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 eval $LIB32PFX $MAGISKBIN/magiskboot --decompress /data/stock_boot_.img.gz /data/stock_boot.img
fi fi
# Update our previous backup to new format if exists # Update our previous backup to new format if exists
if [ -f /data/stock_boot.img ]; then if [ -f /data/stock_boot.img ]; then
ui_print "- Migrating boot image backup" ui_print "- Migrating boot image backup"
SHA1=`$MAGISKBIN/magiskboot --sha1 /data/stock_boot.img 2>/dev/null` SHA1=`eval $LIB32PFX $MAGISKBIN/magiskboot --sha1 /data/stock_boot.img 2>/dev/null`
STOCKDUMP=/data/stock_boot_${SHA1}.img STOCKDUMP=/data/stock_boot_${SHA1}.img
mv /data/stock_boot.img $STOCKDUMP mv /data/stock_boot.img $STOCKDUMP
$MAGISKBIN/magiskboot --compress $STOCKDUMP eval $LIB32PFX $MAGISKBIN/magiskboot --compress $STOCKDUMP
fi fi
# Move the stock backups # Move the stock backups
if [ -f /data/magisk/stock_boot* ]; then if [ -f /data/magisk/stock_boot* ]; then
@@ -154,7 +154,7 @@ run_migrations() {
flash_boot_image() { flash_boot_image() {
# Make sure all blocks are writable # Make sure all blocks are writable
$MAGISKBIN/magisk --unlock-blocks 2>/dev/null eval $LIB32PFX $MAGISKBIN/magisk --unlock-blocks 2>/dev/null
case "$1" in case "$1" in
*.gz) COMMAND="gzip -d < '$1'";; *.gz) COMMAND="gzip -d < '$1'";;
*) COMMAND="cat '$1'";; *) COMMAND="cat '$1'";;
@@ -184,11 +184,11 @@ find_dtbo_image() {
patch_dtbo_image() { patch_dtbo_image() {
if [ ! -z $DTBOIMAGE ]; then if [ ! -z $DTBOIMAGE ]; then
if $MAGISKBIN/magiskboot --dtb-test $DTBOIMAGE; then if eval $LIB32PFX $MAGISKBIN/magiskboot --dtb-test $DTBOIMAGE; then
ui_print "- Backing up stock dtbo image" ui_print "- Backing up stock dtbo image"
$MAGISKBIN/magiskboot --compress $DTBOIMAGE $MAGISKBIN/stock_dtbo.img.gz eval $LIB32PFX $MAGISKBIN/magiskboot --compress $DTBOIMAGE $MAGISKBIN/stock_dtbo.img.gz
ui_print "- Patching fstab in dtbo to remove avb-verity" ui_print "- Patching fstab in dtbo to remove avb-verity"
$MAGISKBIN/magiskboot --dtb-patch $DTBOIMAGE eval $LIB32PFX $MAGISKBIN/magiskboot --dtb-patch $DTBOIMAGE
return 0 return 0
fi fi
fi fi
@@ -200,7 +200,7 @@ restore_imgs() {
STOCKDTBO=/data/stock_dtbo.img.gz STOCKDTBO=/data/stock_dtbo.img.gz
# Make sure all blocks are writable # Make sure all blocks are writable
$MAGISKBIN/magisk --unlock-blocks 2>/dev/null eval $LIB32PFX $MAGISKBIN/magisk --unlock-blocks 2>/dev/null
find_dtbo_image find_dtbo_image
if [ ! -z "$DTBOIMAGE" -a -f "$STOCKDTBO" ]; then if [ ! -z "$DTBOIMAGE" -a -f "$STOCKDTBO" ]; then
ui_print "- Restoring stock dtbo image" ui_print "- Restoring stock dtbo image"
@@ -220,7 +220,7 @@ sign_chromeos() {
ui_print "- Signing ChromeOS boot image" ui_print "- Signing ChromeOS boot image"
echo > empty echo > empty
./chromeos/futility vbutil_kernel --pack new-boot.img.signed \ eval $LIBPFX ./chromeos/futility vbutil_kernel --pack new-boot.img.signed \
--keyblock ./chromeos/kernel.keyblock --signprivate ./chromeos/kernel_data_key.vbprivk \ --keyblock ./chromeos/kernel.keyblock --signprivate ./chromeos/kernel_data_key.vbprivk \
--version 1 --vmlinuz new-boot.img --config empty --arch arm --bootloader empty --flags 0x1 --version 1 --vmlinuz new-boot.img --config empty --arch arm --bootloader empty --flags 0x1
@@ -266,11 +266,12 @@ api_level_arch_detect() {
ABILONG=`grep_prop ro.product.cpu.abi` ABILONG=`grep_prop ro.product.cpu.abi`
ARCH=arm ARCH=arm
ARCH32=arm
IS64BIT=false IS64BIT=false
if [ "$ABI" = "x86" ]; then ARCH=x86; fi; if [ "$ABI" = "x86" ]; then ARCH=x86; ARCH32=x86; fi;
if [ "$ABI2" = "x86" ]; then ARCH=x86; fi; if [ "$ABI2" = "x86" ]; then ARCH=x86; ARCH32=x86; fi;
if [ "$ABILONG" = "arm64-v8a" ]; then ARCH=arm64; IS64BIT=true; fi; if [ "$ABILONG" = "arm64-v8a" ]; then ARCH=arm64; ARCH32=arm; IS64BIT=true; fi;
if [ "$ABILONG" = "x86_64" ]; then ARCH=x64; IS64BIT=true; fi; if [ "$ABILONG" = "x86_64" ]; then ARCH=x64; ARCH32=x86; IS64BIT=true; fi;
} }
boot_actions() { boot_actions() {
@@ -286,7 +287,6 @@ recovery_actions() {
mount -o bind /dev/urandom /dev/random mount -o bind /dev/urandom /dev/random
# Preserve environment varibles # Preserve environment varibles
OLD_PATH=$PATH OLD_PATH=$PATH
OLD_LD_PATH=$LD_LIBRARY_PATH
if [ ! -d $TMPDIR/bin ]; then if [ ! -d $TMPDIR/bin ]; then
# Add busybox to PATH # Add busybox to PATH
mkdir -p $TMPDIR/bin mkdir -p $TMPDIR/bin
@@ -296,13 +296,13 @@ recovery_actions() {
fi fi
# Temporarily block out all custom recovery binaries/libs # Temporarily block out all custom recovery binaries/libs
mv /sbin /sbin_tmp mv /sbin /sbin_tmp
# Add all possible library paths # Set library paths
$IS64BIT && export LD_LIBRARY_PATH=/system/lib64:/system/vendor/lib64 || export LD_LIBRARY_PATH=/system/lib:/system/vendor/lib $IS64BIT && LIBPFX="LD_LIBRARY_PATH=/system/lib64:/system/vendor/lib64" || LIBPFX="LD_LIBRARY_PATH=/system/lib:/system/vendor/lib"
LIB32PFX="LD_LIBRARY_PATH=/system/lib:/system/vendor/lib"
} }
recovery_cleanup() { recovery_cleanup() {
mv /sbin_tmp /sbin 2>/dev/null mv /sbin_tmp /sbin 2>/dev/null
export LD_LIBRARY_PATH=$OLD_LD_PATH
[ -z $OLD_PATH ] || export PATH=$OLD_PATH [ -z $OLD_PATH ] || export PATH=$OLD_PATH
ui_print "- Unmounting partitions" ui_print "- Unmounting partitions"
umount -l /system_root 2>/dev/null umount -l /system_root 2>/dev/null
@@ -348,7 +348,7 @@ request_zip_size_check() {
} }
image_size_check() { image_size_check() {
SIZE="`$MAGISKBIN/magisk --imgsize $IMG`" SIZE="`eval $LIB32PFX $MAGISKBIN/magisk --imgsize $IMG`"
curUsedM=`echo "$SIZE" | cut -d" " -f1` curUsedM=`echo "$SIZE" | cut -d" " -f1`
curSizeM=`echo "$SIZE" | cut -d" " -f2` curSizeM=`echo "$SIZE" | cut -d" " -f2`
curFreeM=$((curSizeM - curUsedM)) curFreeM=$((curSizeM - curUsedM))
@@ -362,28 +362,28 @@ mount_magisk_img() {
if [ "$reqSizeM" -gt "$curFreeM" ]; then if [ "$reqSizeM" -gt "$curFreeM" ]; then
newSizeM=$(((reqSizeM + curUsedM) / 32 * 32 + 64)) newSizeM=$(((reqSizeM + curUsedM) / 32 * 32 + 64))
ui_print "- Resizing $IMG to ${newSizeM}M" ui_print "- Resizing $IMG to ${newSizeM}M"
$MAGISKBIN/magisk --resizeimg $IMG $newSizeM >&2 eval $LIB32PFX $MAGISKBIN/magisk --resizeimg $IMG $newSizeM >&2
fi fi
else else
newSizeM=$((reqSizeM / 32 * 32 + 64)); newSizeM=$((reqSizeM / 32 * 32 + 64));
ui_print "- Creating $IMG with size ${newSizeM}M" ui_print "- Creating $IMG with size ${newSizeM}M"
$MAGISKBIN/magisk --createimg $IMG $newSizeM >&2 eval $LIB32PFX $MAGISKBIN/magisk --createimg $IMG $newSizeM >&2
fi fi
ui_print "- Mounting $IMG to $MOUNTPATH" ui_print "- Mounting $IMG to $MOUNTPATH"
MAGISKLOOP=`$MAGISKBIN/magisk --mountimg $IMG $MOUNTPATH` MAGISKLOOP=`eval $LIB32PFX $MAGISKBIN/magisk --mountimg $IMG $MOUNTPATH`
is_mounted $MOUNTPATH || abort "! $IMG mount failed..." is_mounted $MOUNTPATH || abort "! $IMG mount failed..."
} }
unmount_magisk_img() { unmount_magisk_img() {
$MAGISKBIN/magisk --umountimg $MOUNTPATH $MAGISKLOOP eval $LIB32PFX $MAGISKBIN/magisk --umountimg $MOUNTPATH $MAGISKLOOP
# Shrink the image if possible # Shrink the image if possible
image_size_check $IMG image_size_check $IMG
newSizeM=$((curUsedM / 32 * 32 + 64)) newSizeM=$((curUsedM / 32 * 32 + 64))
if [ $curSizeM -gt $newSizeM ]; then if [ $curSizeM -gt $newSizeM ]; then
ui_print "- Shrinking $IMG to ${newSizeM}M" ui_print "- Shrinking $IMG to ${newSizeM}M"
$MAGISKBIN/magisk --resizeimg $IMG $newSizeM eval $LIB32PFX $MAGISKBIN/magisk --resizeimg $IMG $newSizeM
fi fi
} }

View File

@@ -1,13 +1,13 @@
apply plugin: 'com.android.application' apply plugin: 'com.android.application'
android { android {
compileSdkVersion 27 compileSdkVersion rootProject.ext.compileSdkVersion
buildToolsVersion "27.0.3" buildToolsVersion rootProject.ext.buildToolsVersion
defaultConfig { defaultConfig {
applicationId "com.topjohnwu.snet" applicationId "com.topjohnwu.snet"
minSdkVersion 21 minSdkVersion 21
targetSdkVersion 27 targetSdkVersion rootProject.ext.compileSdkVersion
versionCode 1 versionCode 1
versionName "1.0" versionName "1.0"
} }
@@ -20,10 +20,6 @@ android {
} }
} }
repositories {
google()
}
dependencies { dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar']) implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.google.android.gms:play-services-safetynet:7.0.0' /* The oldest version */ implementation 'com.google.android.gms:play-services-safetynet:7.0.0' /* The oldest version */