From c7adb8e3b1902adcb33756cc1fef20d193fae299 Mon Sep 17 00:00:00 2001 From: tiann Date: Tue, 16 May 2023 17:15:01 +0800 Subject: [PATCH] manager: Add app profile implementation --- manager/app/src/main/cpp/jni.cc | 43 ++++++++++++++- manager/app/src/main/cpp/ksu.cc | 49 ++++++++++++++++- manager/app/src/main/cpp/ksu.h | 16 ++++++ .../main/java/me/weishu/kernelsu/Natives.java | 16 ++++++ .../weishu/kernelsu/ui/screen/AppProfile.kt | 53 +++++++++++++++---- manager/app/src/main/res/values/strings.xml | 4 ++ 6 files changed, 166 insertions(+), 15 deletions(-) diff --git a/manager/app/src/main/cpp/jni.cc b/manager/app/src/main/cpp/jni.cc index 86258709..58d5c461 100644 --- a/manager/app/src/main/cpp/jni.cc +++ b/manager/app/src/main/cpp/jni.cc @@ -60,10 +60,49 @@ Java_me_weishu_kernelsu_Natives_allowRoot(JNIEnv *env, jclass clazz, jint uid, j return allow_su(uid, allow); } - - extern "C" JNIEXPORT jboolean JNICALL Java_me_weishu_kernelsu_Natives_isSafeMode(JNIEnv *env, jclass clazz) { return is_safe_mode(); +} + +extern "C" +JNIEXPORT jboolean JNICALL +Java_me_weishu_kernelsu_Natives_isAllowlistMode(JNIEnv *env, jclass clazz) { + return is_allowlist_mode(); +} +extern "C" +JNIEXPORT jboolean JNICALL +Java_me_weishu_kernelsu_Natives_setAllowlistMode(JNIEnv *env, jclass clazz, jboolean is_allowlist) { + return set_allowlist_mode(is_allowlist); +} +extern "C" +JNIEXPORT jboolean JNICALL +Java_me_weishu_kernelsu_Natives_addUidToAllowlist(JNIEnv *env, jclass clazz, jint uid) { + return add_to_allow_list(uid); +} +extern "C" +JNIEXPORT jboolean JNICALL +Java_me_weishu_kernelsu_Natives_removeUidFromAllowlist(JNIEnv *env, jclass clazz, jint uid) { + return remove_from_allow_list(uid); +} +extern "C" +JNIEXPORT jboolean JNICALL +Java_me_weishu_kernelsu_Natives_addUidToDenylist(JNIEnv *env, jclass clazz, jint uid) { + return add_to_deny_list(uid); +} +extern "C" +JNIEXPORT jboolean JNICALL +Java_me_weishu_kernelsu_Natives_removeUidFromDenylist(JNIEnv *env, jclass clazz, jint uid) { + return remove_from_deny_list(uid); +} +extern "C" +JNIEXPORT jboolean JNICALL +Java_me_weishu_kernelsu_Natives_isUidInAllowlist(JNIEnv *env, jclass clazz, jint uid) { + return is_in_allow_list(uid); +} +extern "C" +JNIEXPORT jboolean JNICALL +Java_me_weishu_kernelsu_Natives_isUidInDenylist(JNIEnv *env, jclass clazz, jint uid) { + return is_in_deny_list(uid); } \ No newline at end of file diff --git a/manager/app/src/main/cpp/ksu.cc b/manager/app/src/main/cpp/ksu.cc index 8c473edc..76ab732d 100644 --- a/manager/app/src/main/cpp/ksu.cc +++ b/manager/app/src/main/cpp/ksu.cc @@ -18,10 +18,19 @@ #define CMD_GET_VERSION 2 #define CMD_ALLOW_SU 3 #define CMD_DENY_SU 4 -#define CMD_GET_ALLOW_LIST 5 +#define CMD_GET_SU_LIST 5 #define CMD_GET_DENY_LIST 6 #define CMD_CHECK_SAFEMODE 9 +#define CMD_GET_WORK_MODE 10 +#define CMD_SET_WORK_MODE 11 +#define CMD_IN_ALLOW_LIST 12 +#define CMD_IN_DENY_LIST 13 +#define CMD_ADD_ALLOW_LIST 14 +#define CMD_REMOVE_ALLOW_LIST 15 +#define CMD_ADD_DENY_LIST 16 +#define CMD_REMOVE_DENY_LIST 17 + static bool ksuctl(int cmd, void* arg1, void* arg2) { int32_t result = 0; prctl(KERNEL_SU_OPTION, cmd, arg1, arg2, &result); @@ -55,7 +64,7 @@ bool allow_su(int uid, bool allow) { } bool get_allow_list(int *uids, int *size) { - return ksuctl(CMD_GET_ALLOW_LIST, uids, size); + return ksuctl(CMD_GET_SU_LIST, uids, size); } bool get_deny_list(int *uids, int *size) { @@ -64,4 +73,40 @@ bool get_deny_list(int *uids, int *size) { bool is_safe_mode() { return ksuctl(CMD_CHECK_SAFEMODE, nullptr, nullptr); +} + +bool is_allowlist_mode() { + int32_t mode = -1; + ksuctl(CMD_GET_WORK_MODE, &mode, nullptr); + // for kernel that doesn't support allowlist mode, return -1 and it is always allowlist mode + return mode <= 0; +} + +bool set_allowlist_mode(bool allowlist_mode) { + int32_t mode = allowlist_mode ? 0 : 1; + return ksuctl(CMD_SET_WORK_MODE, &mode, nullptr); +} + +bool is_in_allow_list(int uid) { + return ksuctl(CMD_IN_ALLOW_LIST, &uid, nullptr); +} + +bool is_in_deny_list(int uid) { + return ksuctl(CMD_IN_DENY_LIST, &uid, nullptr); +} + +bool add_to_allow_list(int uid) { + return ksuctl(CMD_ADD_ALLOW_LIST, &uid, nullptr); +} + +bool remove_from_allow_list(int uid) { + return ksuctl(CMD_REMOVE_ALLOW_LIST, &uid, nullptr); +} + +bool add_to_deny_list(int uid) { + return ksuctl(CMD_ADD_DENY_LIST, &uid, nullptr); +} + +bool remove_from_deny_list(int uid) { + return ksuctl(CMD_REMOVE_DENY_LIST, &uid, nullptr); } \ No newline at end of file diff --git a/manager/app/src/main/cpp/ksu.h b/manager/app/src/main/cpp/ksu.h index 96841de8..a8b7b50b 100644 --- a/manager/app/src/main/cpp/ksu.h +++ b/manager/app/src/main/cpp/ksu.h @@ -17,4 +17,20 @@ bool get_deny_list(int *uids, int *size); bool is_safe_mode(); +bool is_allowlist_mode(); + +bool set_allowlist_mode(bool allowlist_mode); + +bool is_in_allow_list(int uid); + +bool is_in_deny_list(int uid); + +bool add_to_allow_list(int uid); + +bool remove_from_allow_list(int uid); + +bool add_to_deny_list(int uid); + +bool remove_from_deny_list(int uid); + #endif //KERNELSU_KSU_H diff --git a/manager/app/src/main/java/me/weishu/kernelsu/Natives.java b/manager/app/src/main/java/me/weishu/kernelsu/Natives.java index bed5713a..1af5de15 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/Natives.java +++ b/manager/app/src/main/java/me/weishu/kernelsu/Natives.java @@ -23,4 +23,20 @@ public final class Natives { public static native boolean allowRoot(int uid, boolean allow); public static native boolean isSafeMode(); + + public static native boolean isAllowlistMode(); + + public static native boolean setAllowlistMode(boolean isAllowlist); + + public static native boolean isUidInAllowlist(int uid); + + public static native boolean isUidInDenylist(int uid); + + public static native boolean addUidToAllowlist(int uid); + + public static native boolean removeUidFromAllowlist(int uid); + + public static native boolean addUidToDenylist(int uid); + + public static native boolean removeUidFromDenylist(int uid); } diff --git a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/AppProfile.kt b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/AppProfile.kt index 41ae849c..e7bce536 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/AppProfile.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/AppProfile.kt @@ -76,23 +76,41 @@ fun AppProfileScreen( }) } ) { paddingValues -> - LoadingDialog() - - val showAboutDialog = remember { mutableStateOf(false) } - AboutDialog(showAboutDialog) Column(modifier = Modifier.padding(paddingValues)) { - val context = LocalContext.current val scope = rememberCoroutineScope() + val uid = icon.applicationInfo.uid + val isAllowlistModeInit = Natives.isAllowlistMode() + + val isInAllowDenyListInit = if (isAllowlistModeInit) { + Natives.isUidInAllowlist(uid) + } else { + Natives.isUidInDenylist(uid) + } + GroupTitle(stringResource(id = R.string.app_profile_title0)) var allowlistMode by rememberSaveable { - mutableStateOf(true) + mutableStateOf(isAllowlistModeInit) + } + + var isInAllowDenyList by rememberSaveable { + mutableStateOf(isInAllowDenyListInit) + } + + val setAllowlistFailedMsg = if (allowlistMode) { + stringResource(R.string.failed_to_set_allowlist_mode) + } else { + stringResource(R.string.failed_to_set_denylist_mode) } WorkingMode(allowlistMode) { checked -> - allowlistMode = !allowlistMode + if (Natives.setAllowlistMode(checked)) { + allowlistMode = !allowlistMode + } else scope.launch { + snackbarHost.showSnackbar(setAllowlistFailedMsg) + } } Divider(thickness = Dp.Hairline) @@ -122,7 +140,6 @@ fun AppProfileScreen( } val failMessage = stringResource(R.string.superuser_failed_to_grant_root) - val uid = icon.applicationInfo.uid; AppSwitch( Icons.Filled.Security, stringResource(id = R.string.app_profile_root_switch), @@ -139,6 +156,11 @@ fun AppProfileScreen( } } + val failedToAddAllowListMsg = if (allowlistMode) { + stringResource(R.string.failed_to_add_to_allowlist) + } else { + stringResource(R.string.failed_to_add_to_denylist) + } AppSwitch( icon = Icons.Filled.List, title = if (allowlistMode) { @@ -146,9 +168,18 @@ fun AppProfileScreen( } else { stringResource(id = R.string.app_profile_denylist) }, - checked = true - ) { - + checked = isInAllowDenyList + ) { checked -> + val success = if (allowlistMode) { + Natives.addUidToAllowlist(uid) + } else { + Natives.addUidToDenylist(uid) + } + if (success) { + isInAllowDenyList = checked + } else scope.launch { + snackbarHost.showSnackbar(failedToAddAllowListMsg.format(label)) + } } Divider(thickness = Dp.Hairline) diff --git a/manager/app/src/main/res/values/strings.xml b/manager/app/src/main/res/values/strings.xml index e4a3a3ff..b7f454d9 100644 --- a/manager/app/src/main/res/values/strings.xml +++ b/manager/app/src/main/res/values/strings.xml @@ -73,4 +73,8 @@ Denylist Global Working Mode + Failed to switch to allowlist mode + Failed to add %s to allowlist + Failed to add %s to denylist + Failed to switch to denylist mode