diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ac69cd1a1270..1b66fe82433d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -21,15 +21,41 @@ jobs: run: | mkdir -p ksud for dir in ./ksud-*; do - if [ -d "$dir" ]; then - echo "----- Rename $dir -----" - ksud_platform_name=$(basename "$dir") - find "$dir" -type f -name "ksud" -path "*/release/*" | while read -r ksud_file; do - if [ -f "$ksud_file" ]; then - mv "$ksud_file" "ksud/$ksud_platform_name" - fi - done - fi + if [ -d "$dir" ]; then + echo "----- Rename $dir -----" + ksud_platform_name=$(basename "$dir") + if [ -f "$dir/ksud" ]; then + mv "$dir/ksud" "ksud/$ksud_platform_name" + elif [ -f "$dir/ksud.exe" ]; then + mv "$dir/ksud.exe" "ksud/$ksud_platform_name.exe" + fi + fi + done + + - name: Rename ksuinit + run: | + mkdir -p ksuinit + for dir in ./ksuinit-*; do + if [ -d "$dir" ]; then + echo "----- Rename $dir -----" + ksuinit_platform_name=$(basename "$dir") + if [ -f "$dir/ksuinit" ]; then + mv "$dir/ksuinit" "ksuinit/$ksuinit_platform_name" + fi + fi + done + + - name: Rename lkm + run: | + mkdir -p lkm + for dir in ./*-android*-lkm; do + if [ -d "$dir" ]; then + echo "----- Rename $dir -----" + lkm_platform_name=$(basename "$dir") + lkm_platform_name="lkm-${lkm_platform_name%-lkm}_kernelsu.ko" + KO="$(ls $dir/*_kernelsu.ko)" + mv "$KO" "lkm/$lkm_platform_name" + fi done - name: Display structure of downloaded files @@ -40,6 +66,6 @@ jobs: with: files: | manager/*.apk - android*-lkm/*_kernelsu.ko + lkm/lkm-*_kernelsu.ko ksud/ksud-* - ksuinit/** + ksuinit/* diff --git a/docs/README_ID.md b/docs/README_ID.md index 5ab4f459a423..0a8d6be8d65a 100644 --- a/docs/README_ID.md +++ b/docs/README_ID.md @@ -4,7 +4,7 @@ logo -Solusi root berbasis Kernel untuk perangkat Android. +Solusi root berbasis kernel untuk perangkat Android. [![Latest release](https://img.shields.io/github/v/release/tiann/KernelSU?label=Release&logo=github)](https://github.com/tiann/KernelSU/releases/latest) [![Weblate](https://img.shields.io/badge/Localization-Weblate-teal?logo=weblate)](https://hosted.weblate.org/engage/kernelsu) @@ -14,43 +14,49 @@ Solusi root berbasis Kernel untuk perangkat Android. ## Fitur -1. Manajemen akses root dan `su` berbasis kernel. -2. Sistem modul berdasarkan [metamodules](https://kernelsu.org/id_ID/guide/metamodule.html): Infrastruktur pluggable untuk modifikasi systemless. -3. [Profil Aplikasi](https://kernelsu.org/guide/app-profile.html): Kunci daya root di dalam sangkar. +1. Akses `su` dan manajemen hak akses root berbasis kernel. +2. Sistem modul berbasis [metamodules](https://kernelsu.org/id_ID/guide/metamodule.html): Infrastruktur yang dapat dicopot-pasang untuk modifikasi systemless. +3. [Profil Aplikasi](https://kernelsu.org/guide/app-profile.html): Kendalikan hak akses root secara aman. ## Status Kompatibilitas -KernelSU secara resmi mendukung perangkat Android GKI 2.0 (dengan kernel 5.10+), kernel lama (4.14+) juga kompatibel, tetapi Anda perlu membuat kernel sendiri. +KernelSU secara resmi mendukung perangkat Android GKI 2.0 (dengan kernel 5.10+), kernel lama (4.14+) juga didukung, tetapi kernel perlu dikompilasi secara manual. -WSA, ChromeOS, dan Android berbasis wadah juga dapat bekerja dengan KernelSU terintegrasi. +Dengan dukungan ini WSA, ChromeOS, dan Android berbasis kontainer semuanya dapat dijalankan. -Saat ini, arsitektur `arm64-v8a` dan `x86_64` didukung. +Saat ini, arsitektur `arm64-v8a` dan `x86_64` sudah didukung. > [!CAUTION] -> Versi kernel terbaru telah menerapkan perubahan yang merusak yang menyebabkan KernelSU gagal dan berpotensi memicu kernel panic pada `x86_64`! Cek situs web untuk info lebih lanjut! +> Versi kernel terbaru menerapkan perubahan besar yang menyebabkan KernelSU gagal dan berpotensi memicu kernel panic pada `x86_64`! Cek situs web untuk informasi lebih lanjut! ## Penggunaan -- [Petunjuk Instalasi](https://kernelsu.org/id_ID/guide/installation.html) -- [Bagaimana cara membuat?](https://kernelsu.org/id_ID/guide/how-to-build.html) +- [Pemasangan](https://kernelsu.org/id_ID/guide/installation.html) +- [Cara Build](https://kernelsu.org/id_ID/guide/how-to-build.html) - [Situs Web Resmi](https://kernelsu.org/id_ID/) ## Terjemahan -Untuk menerjemahkan KernelSU ke dalam bahasa Anda atau menyempurnakan terjemahan yang sudah ada, harap gunakan [Weblat](https://hosted.weblate.org/engage/kernelsu/). +Untuk membantu penerjemahan KernelSU, kami tidak lagi menerima kontribusi terjemahan melalui Weblate. Semua terjemahan kini ditangani menggunakan LLM. + +Jika Anda ingin menambahkan dukungan untuk bahasa baru, silakan buat PR (Pull Request). Harap diperhatikan bahwa perubahan pada terjemahan bahasa Inggris dan Mandarin yang sudah ada tidak akan diterima. ## Diskusi - Telegram: [@KernelSU](https://t.me/KernelSU) +## Keamanan + +Untuk informasi mengenai pelaporan kerentanan keamanan di KernelSU, lihat [SECURITY.md](/SECURITY.md). + ## Lisensi -- File di bawah direktori `kernel` adalah [GPL-2-only](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html). -- Semua bagian lain kecuali direktori `kernel` adalah [GPL-3.0-or-later](https://www.gnu.org/licenses/gpl-3.0.html). +- Berkas di bawah direktori `kernel` berlisensi [GPL-2-only](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html). +- Seluruh bagian lainnya kecuali direktori `kernel` berlisensi [GPL-3.0-or-later](https://www.gnu.org/licenses/gpl-3.0.html). ## Kredit -- [kernel-assisted-superuser](https://git.zx2c4.com/kernel-assisted-superuser/about/): ide KernelSU. -- [Magisk](https://github.com/topjohnwu/Magisk): alat root yang ampuh. -- [genuine](https://github.com/brevent/genuine/): validasi tanda tangan apk v2. -- [Diamorphine](https://github.com/m0nad/Diamorphine): beberapa keterampilan rootkit. +- [kernel-assisted-superuser](https://git.zx2c4.com/kernel-assisted-superuser/about/): Gagasan utama KernelSU. +- [Magisk](https://github.com/topjohnwu/Magisk): Alat root yang andal. +- [genuine](https://github.com/brevent/genuine/): Validasi tanda tangan APK v2. +- [Diamorphine](https://github.com/m0nad/Diamorphine): Beberapa keahlian rootkit. diff --git a/kernel/Makefile b/kernel/Makefile index d40d0ec1ff77..f3485588554b 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -1,21 +1,30 @@ KDIR := $(KDIR) MDIR := $(realpath $(dir $(abspath $(lastword $(MAKEFILE_LIST))))) ODIR := $(MDIR) +KMI := $(notdir $(patsubst %/,%,$(KDIR))) + +ifeq ($(KMI),android17-6.18) +KBUILD_ARGS := M=$(MDIR) MO=$(ODIR) +else +KBUILD_ARGS := M=$(ODIR) src=$(MDIR) +endif $(info -- KDIR: $(KDIR)) $(info -- MDIR: $(MDIR)) $(info -- OUTPUT DIR: $(ODIR)) +$(info -- KMI: $(KMI)) +$(info -- KBUILD_ARGS: $(KBUILD_ARGS)) .PHONY: all compdb clean format check-format all: check_symbol - make -C $(KDIR) M=$(ODIR) src=$(MDIR) modules compile_commands.json -j$(shell nproc) + $(MAKE) -C $(KDIR) $(KBUILD_ARGS) modules compile_commands.json -j$(shell nproc) ./check_symbol $(ODIR)/kernelsu.ko $(KDIR)/vmlinux compdb: python3 $(MDIR)/.vscode/generate_compdb.py -O $(ODIR) $(MDIR) clean: - make -C $(KDIR) M=$(ODIR) src=$(MDIR) clean + $(MAKE) -C $(KDIR) $(KBUILD_ARGS) clean rm check_symbol check_symbol: tools/check_symbol.c $(CC) tools/check_symbol.c -o check_symbol diff --git a/kernel/build-all.sh b/kernel/build-all.sh index 098c2b82b53a..37adfe82bf71 100755 --- a/kernel/build-all.sh +++ b/kernel/build-all.sh @@ -2,7 +2,7 @@ set -e if [ -z "$1" ]; then - KMIS="android12-5.10 android13-5.10 android13-5.15 android14-5.15 android14-6.1 android15-6.6 android16-6.12" + KMIS="android12-5.10 android13-5.10 android13-5.15 android14-5.15 android14-6.1 android15-6.6 android16-6.12 android17-6.18" else KMIS=$1 fi diff --git a/kernel/feature/kernel_umount.c b/kernel/feature/kernel_umount.c index d77494df225c..7e337abff786 100644 --- a/kernel/feature/kernel_umount.c +++ b/kernel/feature/kernel_umount.c @@ -2,7 +2,6 @@ #include #include #include -#include #include #include #include @@ -20,7 +19,6 @@ #include "ksu.h" static bool ksu_kernel_umount_enabled = true; -bool ksu_webview_zygote_umount_enabled = false; static int kernel_umount_feature_get(u64 *value) { @@ -43,27 +41,6 @@ static const struct ksu_feature_handler kernel_umount_handler = { .set_handler = kernel_umount_feature_set, }; -static int webview_zygote_umount_feature_get(u64 *value) -{ - *value = ksu_webview_zygote_umount_enabled ? 1 : 0; - return 0; -} - -static int webview_zygote_umount_feature_set(u64 value) -{ - bool enable = value != 0; - ksu_webview_zygote_umount_enabled = enable; - pr_info("webview_zygote_umount: set to %d\n", enable); - return 0; -} - -static const struct ksu_feature_handler webview_zygote_umount_handler = { - .feature_id = KSU_FEATURE_WEBVIEW_ZYGOTE_UMOUNT, - .name = "webview_zygote_umount", - .get_handler = webview_zygote_umount_feature_get, - .set_handler = webview_zygote_umount_feature_set, -}; - extern int path_umount(struct path *path, int flags); static void ksu_umount_mnt(const char *mnt, struct path *path, int flags) @@ -110,7 +87,7 @@ int ksu_handle_umount(uid_t old_uid, uid_t new_uid) // 1. Normal app: zygote -> appuid // 2. Isolated process forked from zygote: zygote -> isolated_process // 3. App zygote forked from zygote: zygote -> appuid - // 4. Webview zygote forked from zygote: zygote -> webview_zygote (controlled by feature policy) + // 4. Webview zygote forked from zygote: zygote -> webview_zygote // 5. Isolated process forked from app zygote: appuid -> isolated_process (already handled by 3) // 6. Isolated process forked from webview zygote (already handled by 4) if (!is_appuid(new_uid) && new_uid != WEBVIEW_ZYGOTE_UID && !is_isolated_process(new_uid)) { @@ -153,13 +130,9 @@ void __init ksu_kernel_umount_init(void) if (ksu_register_feature_handler(&kernel_umount_handler)) { pr_err("Failed to register kernel_umount feature handler\n"); } - if (ksu_register_feature_handler(&webview_zygote_umount_handler)) { - pr_err("Failed to register webview_zygote_umount feature handler\n"); - } } void __exit ksu_kernel_umount_exit(void) { - ksu_unregister_feature_handler(KSU_FEATURE_WEBVIEW_ZYGOTE_UMOUNT); ksu_unregister_feature_handler(KSU_FEATURE_KERNEL_UMOUNT); } diff --git a/kernel/feature/kernel_umount.h b/kernel/feature/kernel_umount.h index d7e5bebfe147..e54489557409 100644 --- a/kernel/feature/kernel_umount.h +++ b/kernel/feature/kernel_umount.h @@ -7,7 +7,6 @@ void ksu_kernel_umount_init(void); void ksu_kernel_umount_exit(void); -extern bool ksu_webview_zygote_umount_enabled; // Handler function to be called from setresuid hook int ksu_handle_umount(uid_t old_uid, uid_t new_uid); diff --git a/kernel/policy/allowlist.c b/kernel/policy/allowlist.c index 8cf50d6aab76..879d58b4005a 100644 --- a/kernel/policy/allowlist.c +++ b/kernel/policy/allowlist.c @@ -19,7 +19,6 @@ #include "klog.h" // IWYU pragma: keep #include "ksu.h" -#include "feature/kernel_umount.h" #include "runtime/ksud_boot.h" #include "selinux/selinux.h" #include "policy/allowlist.h" @@ -299,9 +298,6 @@ bool ksu_uid_should_umount(uid_t uid) // we should not umount on manager! return false; } - if (unlikely(uid == WEBVIEW_ZYGOTE_UID)) { - return ksu_webview_zygote_umount_enabled; - } #ifdef CONFIG_KSU_DISABLE_POLICY return !__ksu_is_allow_uid(uid); #else @@ -594,7 +590,7 @@ void ksu_prune_allowlist(bool (*is_uid_valid)(uid_t, char *, void *), void *data uid_t uid = np->profile.curr_uid; char *package = np->profile.key; // we use this uid for special cases, don't prune it! - bool is_preserved_uid = uid == KSU_APP_PROFILE_PRESERVE_UID; + bool is_preserved_uid = uid == KSU_APP_PROFILE_PRESERVE_UID || uid == WEBVIEW_ZYGOTE_UID; if (!is_preserved_uid && !is_uid_valid(uid, package, data)) { modified = true; pr_info("prune uid: %d, package: %s\n", uid, package); diff --git a/kernel/selinux/sepolicy.c b/kernel/selinux/sepolicy.c index e2115a1b132e..7ed54ea3dbc9 100644 --- a/kernel/selinux/sepolicy.c +++ b/kernel/selinux/sepolicy.c @@ -908,10 +908,14 @@ struct selinux_policy *ksu_dup_sepolicy(struct selinux_policy *old_pol) void *data; struct policy_file fp; - len = old_pol->policydb.len; + // Some MTK device policy db seems not marking type itself in type_attr_map_array + // policydb_read() adds each type to its own attribute map, so old_pol->policydb.len may be smaller + // preserve one ebitmap entry for this condition to avoid trigger -EINVAL + len = old_pol->policydb.len + (size_t)old_pol->policydb.p_types.nprim * (sizeof(u32) + sizeof(u64)); + data = vmalloc(len); if (!data) { - pr_err("alloc policy len %ld\n", len); + pr_err("alloc policy buffer len %zu\n", len); ret = -ENOMEM; goto out_free_data; } @@ -924,6 +928,7 @@ struct selinux_policy *ksu_dup_sepolicy(struct selinux_policy *old_pol) pr_err("sepolicy: policydb_write: %d\n", ret); goto out_free_data; } + len -= fp.len; // https://android.googlesource.com/kernel/common/+/35a7845718734ae638b85b420534cb859498dab6%5E%21 #if LINUX_VERSION_CODE < KERNEL_VERSION(6, 18, 0) // https://android-review.googlesource.com/c/kernel/common/+/3009995/11/security/selinux/ss/policydb.c @@ -961,7 +966,7 @@ struct selinux_policy *ksu_dup_sepolicy(struct selinux_policy *old_pol) pr_err("sepolicy: policydb_read: %d\n", ret); goto out_free_policydb; } - new_pol->policydb.len = old_pol->policydb.len; + new_pol->policydb.len = len; kvfree(data); return new_pol; diff --git a/manager/app/src/main/cpp/jni.cc b/manager/app/src/main/cpp/jni.cc index e1c1981d5977..f4278f98ba46 100644 --- a/manager/app/src/main/cpp/jni.cc +++ b/manager/app/src/main/cpp/jni.cc @@ -347,18 +347,6 @@ Java_me_weishu_kernelsu_Natives_setKernelUmountEnabled(JNIEnv *env, jobject thiz return set_kernel_umount_enabled(enabled); } -extern "C" -JNIEXPORT jboolean JNICALL -Java_me_weishu_kernelsu_Natives_isWebViewZygoteUmountEnabled(JNIEnv *env, jobject thiz) { - return is_webview_zygote_umount_enabled(); -} - -extern "C" -JNIEXPORT jboolean JNICALL -Java_me_weishu_kernelsu_Natives_setWebViewZygoteUmountEnabled(JNIEnv *env, jobject thiz, jboolean enabled) { - return set_webview_zygote_umount_enabled(enabled); -} - extern "C" JNIEXPORT jboolean JNICALL Java_me_weishu_kernelsu_Natives_isSelinuxHideEnabled(JNIEnv *env, jobject thiz) { diff --git a/manager/app/src/main/cpp/ksu.cc b/manager/app/src/main/cpp/ksu.cc index fed677ac865e..f2148b07b8f2 100644 --- a/manager/app/src/main/cpp/ksu.cc +++ b/manager/app/src/main/cpp/ksu.cc @@ -216,22 +216,6 @@ bool is_kernel_umount_enabled() { return value != 0; } -bool set_webview_zygote_umount_enabled(bool enabled) { - return set_feature(KSU_FEATURE_WEBVIEW_ZYGOTE_UMOUNT, enabled ? 1 : 0); -} - -bool is_webview_zygote_umount_enabled() { - uint64_t value = 0; - bool supported = false; - if (!get_feature(KSU_FEATURE_WEBVIEW_ZYGOTE_UMOUNT, &value, &supported)) { - return false; - } - if (!supported) { - return false; - } - return value != 0; -} - int set_selinux_hide_enabled(bool enabled) { if (!set_feature(KSU_FEATURE_SELINUX_HIDE, enabled ? 1 : 0)) { return -errno; diff --git a/manager/app/src/main/cpp/ksu.h b/manager/app/src/main/cpp/ksu.h index 4ef8d63f2604..011f9e0e746f 100644 --- a/manager/app/src/main/cpp/ksu.h +++ b/manager/app/src/main/cpp/ksu.h @@ -46,11 +46,6 @@ bool set_kernel_umount_enabled(bool enabled); bool is_kernel_umount_enabled(); -// WebView zygote umount -bool set_webview_zygote_umount_enabled(bool enabled); - -bool is_webview_zygote_umount_enabled(); - // SELinux hide int set_selinux_hide_enabled(bool enabled); diff --git a/manager/app/src/main/java/me/weishu/kernelsu/Natives.kt b/manager/app/src/main/java/me/weishu/kernelsu/Natives.kt index aee6a152888c..54daa874bcbb 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/Natives.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/Natives.kt @@ -80,9 +80,6 @@ object Natives { external fun isKernelUmountEnabled(): Boolean external fun setKernelUmountEnabled(enabled: Boolean): Boolean - external fun isWebViewZygoteUmountEnabled(): Boolean - external fun setWebViewZygoteUmountEnabled(enabled: Boolean): Boolean - /** * SELinux hide can be disabled temporarily. * 0: disabled diff --git a/manager/app/src/main/java/me/weishu/kernelsu/data/model/AppInfo.kt b/manager/app/src/main/java/me/weishu/kernelsu/data/model/AppInfo.kt index 9a61bfd575a1..13987b51dc27 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/data/model/AppInfo.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/data/model/AppInfo.kt @@ -5,26 +5,39 @@ import android.os.Parcelable import kotlinx.parcelize.Parcelize import me.weishu.kernelsu.Natives +const val WEBVIEW_ZYGOTE_UID = 1053 +const val WEBVIEW_ZYGOTE_PROFILE_KEY = "webview_zygote" + @Parcelize data class AppInfo( val label: String, val packageInfo: PackageInfo, val profile: Natives.Profile?, + val profileKey: String = packageInfo.packageName ?: "", + val special: Boolean = false, ) : Parcelable { val packageName: String - get() = packageInfo.packageName + get() = packageInfo.packageName ?: "" + + val displayIdentifier: String + get() = if (special) profileKey else packageName val uid: Int get() = packageInfo.applicationInfo!!.uid + val isWebViewZygote: Boolean + get() = special && uid == WEBVIEW_ZYGOTE_UID + val allowSu: Boolean - get() = profile != null && profile.allowSu + get() = !isWebViewZygote && profile != null && profile.allowSu val hasCustomProfile: Boolean get() { if (profile == null) { return false } - return if (profile.allowSu) { + return if (isWebViewZygote) { + !profile.nonRootUseDefault + } else if (profile.allowSu) { !profile.rootUseDefault } else { !profile.nonRootUseDefault diff --git a/manager/app/src/main/java/me/weishu/kernelsu/data/repository/SettingsRepository.kt b/manager/app/src/main/java/me/weishu/kernelsu/data/repository/SettingsRepository.kt index ad321e9afda3..29611a58d070 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/data/repository/SettingsRepository.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/data/repository/SettingsRepository.kt @@ -38,10 +38,6 @@ interface SettingsRepository { fun isKernelUmountEnabled(): Boolean fun setKernelUmountEnabled(enabled: Boolean): Boolean - suspend fun getWebViewZygoteUmountStatus(): String - fun isWebViewZygoteUmountEnabled(): Boolean - fun setWebViewZygoteUmountEnabled(enabled: Boolean): Boolean - suspend fun getSelinuxHideStatus(): String fun isSelinuxHideEnabled(): Boolean fun setSelinuxHideEnabled(enabled: Boolean): Int diff --git a/manager/app/src/main/java/me/weishu/kernelsu/data/repository/SettingsRepositoryImpl.kt b/manager/app/src/main/java/me/weishu/kernelsu/data/repository/SettingsRepositoryImpl.kt index 0c540248ad1b..b93202047a25 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/data/repository/SettingsRepositoryImpl.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/data/repository/SettingsRepositoryImpl.kt @@ -174,13 +174,6 @@ class SettingsRepositoryImpl : SettingsRepository { override fun setKernelUmountEnabled(enabled: Boolean): Boolean = Natives.setKernelUmountEnabled(enabled) - override suspend fun getWebViewZygoteUmountStatus(): String = getFeatureStatus("webview_zygote_umount") - - override fun isWebViewZygoteUmountEnabled(): Boolean = Natives.isWebViewZygoteUmountEnabled() - - override fun setWebViewZygoteUmountEnabled(enabled: Boolean): Boolean = - Natives.setWebViewZygoteUmountEnabled(enabled) - override suspend fun getSelinuxHideStatus(): String = getFeatureStatus("selinux_hide") override fun isSelinuxHideEnabled(): Boolean = Natives.isSelinuxHideEnabled() diff --git a/manager/app/src/main/java/me/weishu/kernelsu/data/repository/SuperUserRepositoryImpl.kt b/manager/app/src/main/java/me/weishu/kernelsu/data/repository/SuperUserRepositoryImpl.kt index 25a1b5ca8267..9158c6b5a1b0 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/data/repository/SuperUserRepositoryImpl.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/data/repository/SuperUserRepositoryImpl.kt @@ -4,6 +4,7 @@ import android.content.ComponentName import android.content.Intent import android.content.ServiceConnection import android.content.pm.ApplicationInfo +import android.content.pm.PackageInfo import android.os.Handler import android.os.IBinder import android.os.Looper @@ -17,6 +18,8 @@ import kotlinx.coroutines.withContext import me.weishu.kernelsu.IKsuInterface import me.weishu.kernelsu.Natives import me.weishu.kernelsu.data.model.AppInfo +import me.weishu.kernelsu.data.model.WEBVIEW_ZYGOTE_PROFILE_KEY +import me.weishu.kernelsu.data.model.WEBVIEW_ZYGOTE_UID import me.weishu.kernelsu.ksuApp import me.weishu.kernelsu.ui.KsuService import me.weishu.kernelsu.ui.util.KsuCli @@ -69,7 +72,8 @@ class SuperUserRepositoryImpl : SuperUserRepository { val packages = slice.list val newApps = packages.filter { val ai = it.applicationInfo ?: return@filter false - (ai.flags and ApplicationInfo.FLAG_HAS_CODE) != 0 + ai.uid != WEBVIEW_ZYGOTE_UID && + (ai.flags and ApplicationInfo.FLAG_HAS_CODE) != 0 }.map { val appInfo = it.applicationInfo!! val profile = Natives.getAppProfile(it.packageName, appInfo.uid) @@ -78,7 +82,23 @@ class SuperUserRepositoryImpl : SuperUserRepository { packageInfo = it, profile = profile, ) + }.toMutableList() + + // WebView Zygote is a single system UID, not a per-user package. Reuse the system icon. + val systemInfo = ApplicationInfo(pm.getApplicationInfo("android", 0)).apply { + uid = WEBVIEW_ZYGOTE_UID + } + val placeholder = PackageInfo().apply { + packageName = "" + applicationInfo = systemInfo } + newApps += AppInfo( + label = "WebView Zygote", + packageInfo = placeholder, + profile = Natives.getAppProfile(WEBVIEW_ZYGOTE_PROFILE_KEY, WEBVIEW_ZYGOTE_UID), + profileKey = WEBVIEW_ZYGOTE_PROFILE_KEY, + special = true, + ) Log.i(TAG, "load cost: ${SystemClock.elapsedRealtime() - start}") Pair(newApps, idsArray.toList()) @@ -95,7 +115,7 @@ class SuperUserRepositoryImpl : SuperUserRepository { if (currentApps.isEmpty()) return@runCatching emptyList() currentApps.map { - val profile = Natives.getAppProfile(it.packageName, it.uid) + val profile = Natives.getAppProfile(it.profileKey, it.uid) it.copy(profile = profile) } } diff --git a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/appprofile/AppProfileMaterial.kt b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/appprofile/AppProfileMaterial.kt index c2e7581b6633..0c1c0fb91342 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/appprofile/AppProfileMaterial.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/appprofile/AppProfileMaterial.kt @@ -93,6 +93,7 @@ fun AppProfileScreenMaterial( onBack = actions.onBack, scrollBehavior = scrollBehavior, isUidGroup = state.isUidGroup, + showActions = !state.appGroup.primary.isWebViewZygote, packageName = state.packageName, userId = state.uid / 100000, onLaunchApp = actions.onLaunchApp, @@ -110,7 +111,11 @@ fun AppProfileScreenMaterial( .imePadding() .nestedScroll(scrollBehavior.nestedScrollConnection) .verticalScroll(rememberScrollState()), - packageName = if (state.isUidGroup) "" else state.appGroup.primary.packageName, + packageName = if (state.isUidGroup) { + "" + } else { + state.appGroup.primary.displayIdentifier + }, appLabel = if (state.isUidGroup) ownerNameForUid(state.appGroup.primary.uid) else state.appGroup.primary.label, appIcon = { AppIconImage( @@ -127,6 +132,7 @@ fun AppProfileScreenMaterial( appVersionCode = if (state.isUidGroup) 0L else state.appGroup.primary.packageInfo.longVersionCode, profile = state.profile, isUidGroup = state.isUidGroup, + isSpecialApp = state.appGroup.primary.special, affectedApps = state.appGroup.apps, onViewTemplate = actions.onViewTemplate, onManageTemplate = actions.onManageTemplate, @@ -147,12 +153,13 @@ private fun AppProfileInner( appVersionCode: Long, profile: Natives.Profile, isUidGroup: Boolean = false, + isSpecialApp: Boolean = false, affectedApps: List = emptyList(), onViewTemplate: (id: String) -> Unit = {}, onManageTemplate: () -> Unit = {}, onProfileChange: (Natives.Profile) -> Unit, ) { - val isRootGranted = profile.allowSu + val isRootGranted = !isSpecialApp && profile.allowSu val userId = appUid / 100000 val appId = appUid % 100000 @@ -174,13 +181,15 @@ private fun AppProfileInner( modifier = Modifier .fillMaxWidth() .padding(horizontal = 16.dp), - content = listOf( - { + content = buildList<@Composable () -> Unit> { + add { SegmentedListItem( headlineContent = { Text(appLabel) }, supportingContent = { Column { - if (!isUidGroup) { + if (isSpecialApp) { + Text(packageName, color = MaterialTheme.colorScheme.onSurfaceVariant) + } else if (!isUidGroup) { Text("$appVersionName ($appVersionCode)", color = MaterialTheme.colorScheme.onSurfaceVariant) Text(packageName, color = MaterialTheme.colorScheme.onSurfaceVariant) } else { @@ -218,23 +227,23 @@ private fun AppProfileInner( } } ) - }, - { + } + if (!isSpecialApp) add { SegmentedSwitchItem( icon = Icons.Filled.Security, title = stringResource(id = R.string.superuser), checked = isRootGranted, onCheckedChange = { onProfileChange(profile.copy(allowSu = it)) }, ) - }, - { + } + add { SegmentedListItem( headlineContent = { Text(stringResource(R.string.profile)) }, supportingContent = { Text(mode.text, color = MaterialTheme.colorScheme.onSurfaceVariant) }, leadingContent = { Icon(Icons.Filled.AccountCircle, null) }, ) } - ) + } ) Crossfade(targetState = isRootGranted, label = "") { current -> @@ -300,7 +309,7 @@ private fun AppProfileInner( { SegmentedListItem( headlineContent = { Text(app.label) }, - supportingContent = { Text(app.packageName) }, + supportingContent = { Text(app.displayIdentifier) }, leadingContent = { AppIconImage( packageInfo = app.packageInfo, @@ -327,6 +336,7 @@ private fun TopBar( onBack: () -> Unit, scrollBehavior: TopAppBarScrollBehavior? = null, isUidGroup: Boolean = false, + showActions: Boolean = true, packageName: String = "", userId: Int = 0, onLaunchApp: (String, Int) -> Unit, @@ -340,7 +350,7 @@ private fun TopBar( TopBarBackButton(onClick = onBack) }, actions = { - if (!isUidGroup) { + if (!isUidGroup && showActions) { var showDropdown by remember { mutableStateOf(false) } IconButton( diff --git a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/appprofile/AppProfileMiuix.kt b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/appprofile/AppProfileMiuix.kt index 51b1bb16b0af..b199795f5d59 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/appprofile/AppProfileMiuix.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/appprofile/AppProfileMiuix.kt @@ -105,7 +105,7 @@ fun AppProfileScreenMiuix( topBar = { TopBar( onBack = actions.onBack, - showActions = !state.isUidGroup, + showActions = !state.isUidGroup && !state.appGroup.primary.isWebViewZygote, packageName = state.packageName, userId = state.uid / 100000, onLaunchApp = actions.onLaunchApp, @@ -132,7 +132,11 @@ fun AppProfileScreenMiuix( ) { item { AppProfileInner( - packageName = if (state.isUidGroup) "" else state.appGroup.primary.packageName, + packageName = if (state.isUidGroup) { + "" + } else { + state.appGroup.primary.displayIdentifier + }, appLabel = if (state.isUidGroup) ownerNameForUid(state.appGroup.primary.uid) else state.appGroup.primary.label, appIcon = { AppIconImage( @@ -147,6 +151,7 @@ fun AppProfileScreenMiuix( appVersionCode = if (state.isUidGroup) 0L else state.appGroup.primary.packageInfo.longVersionCode, profile = state.profile, isUidGroup = state.isUidGroup, + isSpecialApp = state.appGroup.primary.special, affectedApps = state.appGroup.apps, onViewTemplate = actions.onViewTemplate, onManageTemplate = actions.onManageTemplate, @@ -176,12 +181,13 @@ private fun AppProfileInner( appVersionCode: Long, profile: Natives.Profile, isUidGroup: Boolean = false, + isSpecialApp: Boolean = false, affectedApps: List = emptyList(), onViewTemplate: (id: String) -> Unit = {}, onManageTemplate: () -> Unit = {}, onProfileChange: (Natives.Profile) -> Unit, ) { - val isRootGranted = profile.allowSu + val isRootGranted = !isSpecialApp && profile.allowSu val userId = appUid / 100000 val appId = appUid % 100000 val templates = remember { listAppProfileTemplates() } @@ -214,7 +220,17 @@ private fun AppProfileInner( maxLines = 1, softWrap = false ) - if (!isUidGroup) { + if (isSpecialApp) { + Text( + text = packageName, + fontSize = 12.sp, + color = colorScheme.onSurfaceVariantSummary, + fontWeight = FontWeight.Medium, + modifier = Modifier.basicMarquee(), + maxLines = 1, + softWrap = false + ) + } else if (!isUidGroup) { Text( text = "$appVersionName ($appVersionCode)", fontSize = 12.sp, @@ -287,25 +303,27 @@ private fun AppProfileInner( } } - Card( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 12.dp) - .padding(bottom = 12.dp), - ) { - SwitchPreference( - startAction = { - Icon( - imageVector = Icons.Rounded.Security, - contentDescription = null, - modifier = Modifier.padding(end = 6.dp), - tint = colorScheme.onBackground - ) - }, - title = stringResource(id = R.string.superuser), - checked = isRootGranted, - onCheckedChange = { onProfileChange(profile.copy(allowSu = it)) }, - ) + if (!isSpecialApp) { + Card( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 12.dp) + .padding(bottom = 12.dp), + ) { + SwitchPreference( + startAction = { + Icon( + imageVector = Icons.Rounded.Security, + contentDescription = null, + modifier = Modifier.padding(end = 6.dp), + tint = colorScheme.onBackground + ) + }, + title = stringResource(id = R.string.superuser), + checked = isRootGranted, + onCheckedChange = { onProfileChange(profile.copy(allowSu = it)) }, + ) + } } val initialRootMode = if (profile.rootUseDefault) { @@ -455,7 +473,7 @@ private fun AppProfileInner( ) }, title = app.label, - summary = app.packageName, + summary = app.displayIdentifier, insideMargin = PaddingValues(start = 11.dp, end = 16.dp, top = 8.dp, bottom = 8.dp) ) } diff --git a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/appprofile/AppProfileScreen.kt b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/appprofile/AppProfileScreen.kt index 3b280a904e66..a978f27c2907 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/appprofile/AppProfileScreen.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/appprofile/AppProfileScreen.kt @@ -52,16 +52,18 @@ fun AppProfileScreen(uid: Int) { return } - val packageName = primaryAppInfo.packageName + val packageName = primaryAppInfo.profileKey val sharedUserId = remember(uid) { primaryAppInfo.packageInfo.sharedUserId ?: appGroup.apps.firstOrNull { it.packageInfo.sharedUserId != null }?.packageInfo?.sharedUserId ?: "" } - val initialProfile = remember(uid, packageName) { - Natives.getAppProfile(packageName, uid).also { - if (it.allowSu) { + val initialProfile = remember(uid, packageName, primaryAppInfo.special) { + Natives.getAppProfile(packageName, uid).let { + if (primaryAppInfo.special) it.copy(allowSu = false) else it + }.also { + if (it.allowSu && !primaryAppInfo.special) { it.rules = getSepolicy(packageName) } } @@ -107,23 +109,29 @@ fun AppProfileScreen(uid: Int) { }, onProfileChange = { updatedProfile -> scope.launch { - if (updatedProfile.allowSu) { + val profileToSave = if (primaryAppInfo.special) { + updatedProfile.copy(allowSu = false) + } else { + updatedProfile + } + if (profileToSave.allowSu) { if (uid < 2000 && uid != 1000) { showMessage(suNotAllowed) return@launch } - if (!updatedProfile.rootUseDefault - && updatedProfile.rules.isNotEmpty() - && !setSepolicy(profile.name, updatedProfile.rules) + if (!profileToSave.rootUseDefault + && profileToSave.rules.isNotEmpty() + && !primaryAppInfo.special + && !setSepolicy(profileToSave.name, profileToSave.rules) ) { showMessage(failToUpdateSepolicy) return@launch } } - if (!Natives.setAppProfile(updatedProfile)) { + if (!Natives.setAppProfile(profileToSave)) { showMessage(failToUpdateAppProfile) } else { - profile = updatedProfile + profile = profileToSave if (uiMode == UiMode.Material) { viewModel.loadAppList() } diff --git a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/settings/SettingsMaterial.kt b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/settings/SettingsMaterial.kt index b65f49ba33e5..f67028024c00 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/settings/SettingsMaterial.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/settings/SettingsMaterial.kt @@ -21,7 +21,6 @@ import androidx.compose.material.icons.filled.DeveloperMode import androidx.compose.material.icons.filled.ElectricalServices import androidx.compose.material.icons.filled.Fence import androidx.compose.material.icons.filled.FolderDelete -import androidx.compose.material.icons.filled.Language import androidx.compose.material.icons.filled.Palette import androidx.compose.material.icons.filled.Policy import androidx.compose.material.icons.filled.RemoveCircle @@ -212,21 +211,6 @@ fun SettingPagerMaterial( onCheckedChange = actions.onSetKernelUmountEnabled ) }, - { - val webViewUmountSummary = when (uiState.webViewZygoteUmountStatus) { - "unsupported" -> stringResource(id = R.string.feature_status_unsupported_summary) - "managed" -> stringResource(id = R.string.feature_status_managed_summary) - else -> stringResource(id = R.string.settings_webview_zygote_umount_summary) - } - SegmentedSwitchItem( - icon = Icons.Filled.Language, - title = stringResource(id = R.string.settings_webview_zygote_umount), - summary = webViewUmountSummary, - enabled = uiState.webViewZygoteUmountStatus == "supported", - checked = uiState.isWebViewZygoteUmountEnabled, - onCheckedChange = actions.onSetWebViewZygoteUmountEnabled - ) - }, { val selinuxHideSummary = when (uiState.selinuxHideStatus) { "unsupported" -> stringResource(id = R.string.feature_status_unsupported_summary) diff --git a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/settings/SettingsMiuix.kt b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/settings/SettingsMiuix.kt index 845d84167de3..54e2464a065a 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/settings/SettingsMiuix.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/settings/SettingsMiuix.kt @@ -24,7 +24,6 @@ import androidx.compose.material.icons.rounded.DeveloperMode import androidx.compose.material.icons.rounded.ElectricalServices import androidx.compose.material.icons.rounded.Fence import androidx.compose.material.icons.rounded.FolderDelete -import androidx.compose.material.icons.rounded.Language import androidx.compose.material.icons.rounded.Palette import androidx.compose.material.icons.rounded.Policy import androidx.compose.material.icons.rounded.RemoveCircle @@ -257,27 +256,6 @@ fun SettingPagerMiuix( onCheckedChange = actions.onSetKernelUmountEnabled ) - val webViewUmountSummary = when (uiState.webViewZygoteUmountStatus) { - "unsupported" -> stringResource(id = R.string.feature_status_unsupported_summary) - "managed" -> stringResource(id = R.string.feature_status_managed_summary) - else -> stringResource(id = R.string.settings_webview_zygote_umount_summary) - } - SwitchPreference( - title = stringResource(id = R.string.settings_webview_zygote_umount), - summary = webViewUmountSummary, - startAction = { - Icon( - Icons.Rounded.Language, - modifier = Modifier.padding(end = 6.dp), - contentDescription = stringResource(id = R.string.settings_webview_zygote_umount), - tint = colorScheme.onBackground - ) - }, - enabled = uiState.webViewZygoteUmountStatus == "supported", - checked = uiState.isWebViewZygoteUmountEnabled, - onCheckedChange = actions.onSetWebViewZygoteUmountEnabled - ) - val selinuxHideSummary = when (uiState.selinuxHideStatus) { "unsupported" -> stringResource(id = R.string.feature_status_unsupported_summary) "managed" -> stringResource(id = R.string.feature_status_managed_summary) diff --git a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/settings/SettingsScreen.kt b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/settings/SettingsScreen.kt index a5260ee9998a..639ea90d3f06 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/settings/SettingsScreen.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/settings/SettingsScreen.kt @@ -35,7 +35,6 @@ fun SettingPager( onOpenProfileTemplate = { navigator.push(Route.AppProfileTemplate) }, onSetSuCompatMode = viewModel::setSuCompatMode, onSetKernelUmountEnabled = viewModel::setKernelUmountEnabled, - onSetWebViewZygoteUmountEnabled = viewModel::setWebViewZygoteUmountEnabled, onSetSelinuxHideEnabled = viewModel::setSelinuxHideEnabled, onSetSulogEnabled = viewModel::setSulogEnabled, onSetAdbRootEnabled = viewModel::setAdbRootEnabled, diff --git a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/settings/SettingsUiState.kt b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/settings/SettingsUiState.kt index 69251cde118f..8de49ca25087 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/settings/SettingsUiState.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/settings/SettingsUiState.kt @@ -32,10 +32,6 @@ data class SettingsUiState( val kernelUmountStatus: String = "", val isKernelUmountEnabled: Boolean = false, - // WebView Zygote Umount - val webViewZygoteUmountStatus: String = "", - val isWebViewZygoteUmountEnabled: Boolean = false, - // SELinux Hide val selinuxHideStatus: String = "", val isSelinuxHideEnabled: Boolean = false, @@ -70,7 +66,6 @@ data class SettingsScreenActions( val onOpenProfileTemplate: () -> Unit, val onSetSuCompatMode: (Int) -> Unit, val onSetKernelUmountEnabled: (Boolean) -> Unit, - val onSetWebViewZygoteUmountEnabled: (Boolean) -> Unit, val onSetSelinuxHideEnabled: (Boolean) -> Unit, val onSetSulogEnabled: (Boolean) -> Unit, val onSetAdbRootEnabled: (Boolean) -> Unit, diff --git a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/superuser/SuperUserMaterial.kt b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/superuser/SuperUserMaterial.kt index 5b94612f9687..95217bb2f5a5 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/superuser/SuperUserMaterial.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/superuser/SuperUserMaterial.kt @@ -419,7 +419,7 @@ private fun SearchGroupItem( group.apps.forEach { app -> SimpleAppItem( app = app, - matched = group.matchedPackageNames.contains(app.packageName), + matched = group.matchedIdentifiers.contains(app.displayIdentifier), ) { closeSearch() onOpenProfile(group) @@ -447,7 +447,7 @@ private fun SimpleAppItem( } ), content = { Text(app.label, overflow = TextOverflow.Ellipsis, maxLines = 1) }, - supportingContent = { Text(app.packageName, overflow = TextOverflow.Ellipsis, maxLines = 1) }, + supportingContent = { Text(app.displayIdentifier, overflow = TextOverflow.Ellipsis, maxLines = 1) }, leadingContent = { AppIconImage( packageInfo = app.packageInfo, @@ -495,7 +495,7 @@ private fun GroupItem( val summaryText = if (group.apps.size > 1) { stringResource(R.string.group_contains_apps, group.apps.size) } else { - group.primary.packageName + group.primary.displayIdentifier } SegmentedListItem( selected = selected, diff --git a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/superuser/SuperUserMiuix.kt b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/superuser/SuperUserMiuix.kt index 0b4a52af66a5..e30b6d4457f9 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/superuser/SuperUserMiuix.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/superuser/SuperUserMiuix.kt @@ -380,7 +380,7 @@ fun SuperUserPagerMiuix( group.apps.forEach { app -> SimpleAppItem( app = app, - matched = group.matchedPackageNames.contains(app.packageName), + matched = group.matchedIdentifiers.contains(app.displayIdentifier), ) } Spacer(Modifier.height(6.dp)) @@ -508,7 +508,7 @@ private fun SimpleAppItem( ) { BasicComponent( title = app.label, - summary = app.packageName, + summary = app.displayIdentifier, startAction = { AppIconImage( packageInfo = app.packageInfo, @@ -582,7 +582,7 @@ private fun GroupItem( text = if (group.apps.size > 1) { stringResource(R.string.group_contains_apps, group.apps.size) } else { - group.primary.packageName + group.primary.displayIdentifier }, modifier = Modifier .basicMarquee(), diff --git a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/superuser/SuperUserUiState.kt b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/superuser/SuperUserUiState.kt index ba119f77c53a..ddc08c9eaf5a 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/superuser/SuperUserUiState.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/superuser/SuperUserUiState.kt @@ -16,7 +16,7 @@ data class GroupedApps( val anyCustom: Boolean, val shouldUmount: Boolean, val ownerName: String? = null, - val matchedPackageNames: Set = emptySet(), + val matchedIdentifiers: Set = emptySet(), ) @Stable diff --git a/manager/app/src/main/java/me/weishu/kernelsu/ui/viewmodel/SettingsViewModel.kt b/manager/app/src/main/java/me/weishu/kernelsu/ui/viewmodel/SettingsViewModel.kt index 176c681884c5..9a8b9f2abdc1 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/ui/viewmodel/SettingsViewModel.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/ui/viewmodel/SettingsViewModel.kt @@ -57,8 +57,6 @@ class SettingsViewModel( val kernelUmountStatus = repo.getKernelUmountStatus() val isKernelUmountEnabled = repo.isKernelUmountEnabled() - val webViewZygoteUmountStatus = repo.getWebViewZygoteUmountStatus() - val isWebViewZygoteUmountEnabled = repo.isWebViewZygoteUmountEnabled() val selinuxHideStatus = repo.getSelinuxHideStatus() val isSelinuxHideEnabled = repo.isSelinuxHideEnabled() val sulogStatus = repo.getSulogStatus() @@ -95,8 +93,6 @@ class SettingsViewModel( isAdbRootEnabled = isAdbRootEnabled, kernelUmountStatus = kernelUmountStatus, isKernelUmountEnabled = isKernelUmountEnabled, - webViewZygoteUmountStatus = webViewZygoteUmountStatus, - isWebViewZygoteUmountEnabled = isWebViewZygoteUmountEnabled, selinuxHideStatus = selinuxHideStatus, isSelinuxHideEnabled = isSelinuxHideEnabled, sulogStatus = sulogStatus, @@ -267,15 +263,6 @@ class SettingsViewModel( } } - fun setWebViewZygoteUmountEnabled(enabled: Boolean) { - viewModelScope.launch(Dispatchers.IO) { - if (repo.setWebViewZygoteUmountEnabled(enabled)) { - repo.execKsudFeatureSave() - _uiState.update { it.copy(isWebViewZygoteUmountEnabled = enabled) } - } - } - } - fun setSelinuxHideEnabled(enabled: Boolean) { viewModelScope.launch(Dispatchers.IO) { val status = repo.setSelinuxHideEnabled(enabled) diff --git a/manager/app/src/main/java/me/weishu/kernelsu/ui/viewmodel/SuperUserViewModel.kt b/manager/app/src/main/java/me/weishu/kernelsu/ui/viewmodel/SuperUserViewModel.kt index 5aff0025dd42..62d45bb82fa1 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/ui/viewmodel/SuperUserViewModel.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/ui/viewmodel/SuperUserViewModel.kt @@ -177,21 +177,21 @@ class SuperUserViewModel( if (text.isEmpty()) return emptyList() return groups.mapNotNull { group -> - val matchedPackageNames = group.apps.filter { + val matchedIdentifiers = group.apps.filter { it.label.contains(text, true) || - it.packageName.contains(text, true) || + it.displayIdentifier.contains(text, true) || PinyinUtil.toPinyin(it.label).contains(text, true) - }.mapTo(linkedSetOf()) { it.packageName } + }.mapTo(linkedSetOf()) { it.displayIdentifier } - if (matchedPackageNames.isEmpty()) { + if (matchedIdentifiers.isEmpty()) { null } else { val sortedApps = group.apps.sortedWith( - compareByDescending { it.packageName in matchedPackageNames } + compareByDescending { it.displayIdentifier in matchedIdentifiers } ) group.copy( apps = sortedApps, - matchedPackageNames = matchedPackageNames, + matchedIdentifiers = matchedIdentifiers, ) } } @@ -258,6 +258,8 @@ class SuperUserViewModel( return list.filter { if (it.packageName == ksuApp.packageName) return@filter false + // UID 1053 is the single system-wide WebView zygote (primary user only). + if (it.isWebViewZygote) return@filter true if (it.allowSu || it.hasCustomProfile) { return@filter true } @@ -314,7 +316,7 @@ class SuperUserViewModel( private fun sortGroups(groups: List, config: AppSortConfig): List { val collator = Collator.getInstance(Locale.getDefault()) val base: Comparator = when (config.sortType) { - AppSortType.PACKAGE_NAME -> compareBy { it.primary.packageName } + AppSortType.PACKAGE_NAME -> compareBy { it.primary.displayIdentifier } AppSortType.INSTALL_TIME -> compareBy { it.primary.packageInfo.firstInstallTime } AppSortType.UPDATE_TIME -> compareBy { it.primary.packageInfo.lastUpdateTime } AppSortType.NAME -> Comparator { a, b -> collator.compare(a.primary.label, b.primary.label) } diff --git a/manager/app/src/main/java/me/weishu/kernelsu/ui/webui/WebViewInterface.kt b/manager/app/src/main/java/me/weishu/kernelsu/ui/webui/WebViewInterface.kt index f3cdbe937838..407fc6c5b9bd 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/ui/webui/WebViewInterface.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/ui/webui/WebViewInterface.kt @@ -208,6 +208,7 @@ class WebViewInterface(private val state: WebUIState) { fun listPackages(type: String): String { val packageNames = SuperUserViewModel.apps .filter { appInfo -> + if (appInfo.special) return@filter false val flags = appInfo.packageInfo.applicationInfo?.flags ?: 0 when (type.lowercase()) { "system" -> (flags and ApplicationInfo.FLAG_SYSTEM) != 0 @@ -229,7 +230,7 @@ class WebViewInterface(private val state: WebUIState) { fun getPackagesInfo(packageNamesJson: String): String { val packageNames = JSONArray(packageNamesJson) val jsonArray = JSONArray() - val appMap = SuperUserViewModel.apps.associateBy { it.packageName } + val appMap = SuperUserViewModel.apps.filterNot { it.special }.associateBy { it.packageName } for (i in 0 until packageNames.length()) { val pkgName = packageNames.getString(i) val appInfo = appMap[pkgName] diff --git a/manager/app/src/main/res/values-in/strings.xml b/manager/app/src/main/res/values-in/strings.xml index bc558d09e117..b61a5ffce7cd 100644 --- a/manager/app/src/main/res/values-in/strings.xml +++ b/manager/app/src/main/res/values-in/strings.xml @@ -55,7 +55,7 @@ Bintang Kode sumber Ya - Hapus + Copot Pasang Pasang Mulai ulang @@ -67,10 +67,10 @@ Mulai ulang ke Download Mulai ulang ke EDL Tentang - Yakin ingin menghapus modul %s? - Yakin ingin menghapus modul %s? Tindakan ini akan memengaruhi semua modul, dan fitur tertentu yang disediakan oleh metamodul (seperti mounting) tidak tersedia. - %s berhasil dihapus - Gagal menghapus: %s + Yakin ingin mencopot modul %s? + Yakin ingin mencopot modul %s? Tindakan ini akan mempengaruhi semua modul, dan fitur tertentu yang disediakan oleh metamodul (seperti mounting) tidak tersedia. + %s berhasil dicopot + Gagal mencopot: %s Versi Oleh Tampilkan aplikasi sistem @@ -79,7 +79,7 @@ Mode jailbreak Jailbreak Proses jailbreak mungkin gagal, harap periksa log - Anda sedang dalam mode jailbreak. Memulai ulang penuh akan menghilangkan akses Root, dan Anda harus melakukan jailbreak lagi setelah perangkat menyala. Tetap ingin memulai ulang? + Anda sedang dalam mode jailbreak. Memulai ulang penuh akan menghilangkan akses Root, dan Anda harus melakukan jailbreak lagi setelah perangkat menyala. Tetap ingin mulai ulang? Pemasangan modul dinonaktifkan pada mode aman Mulai ulang untuk menerapkan Modul tidak tersedia karena konflik dengan Magisk! @@ -87,20 +87,20 @@ https://kernelsu.org/id_ID/guide/what-is-kernelsu.html Pelajari cara memasang KernelSU dan menggunakan modul Dukung Kami - KernelSU akan selalu gratis dan serta bersumber terbuka. Bagaimanapun juga, Anda dapat menunjukan kepedulian Anda kepada kami dengan memberikan donasi. + KernelSU gratis dan sumber terbuka, sekarang dan selamanya. Namun, Anda dapat menunjukkan kepedulian Anda kepada kami dengan memberikan donasi. Mulai dari v3.0.0, fungsi mode GKI dibatasi untuk lingkungan pengujian. Kami tidak menyarankan untuk penggunaan harian, dan berkas image tidak akan lagi disediakan. Gabung saluran %2$s kami]]> Profil Aplikasi Bawaan Templat - Khusus + Kustom Nama profil Ruang nama mount Diwariskan Global Individual Grup - Kemampuan + Kapabilitas Atribut Konteks SELinux Umount modul @@ -128,7 +128,7 @@ Templat Profil Aplikasi Kelola templat lokal dan daring dari Profil Aplikasi Buat templat - Edit templat + Ubah templat ID ID templat tidak valid Nama @@ -177,13 +177,13 @@ Hanya berkas .ko yang didukung %1$s partisi image disarankan Pilih KMI - Hapus - Hapus sementara - Hapus permanen + Copot + Copot sementara + Copot permanen Pulihkan image bawaan - Hapus sementara KernelSU, dipulihkan ke keadaan semula setelah mulai ulang berikutnya. - Hapus KernelSU (Root dan semua modul) sepenuhnya dan secara permanen. - Pulihkan image bawaan (jika cadangan ada), biasanya digunakan sebelum OTA; jika Anda perlu menghapus KernelSU, harap gunakan \"Hapus permanen\". + Copot sementara KernelSU, dipulihkan ke keadaan semula setelah mulai ulang berikutnya. + Copot KernelSU (Root dan semua modul) sepenuhnya dan secara permanen. + Pulihkan image bawaan (jika cadangan ada), biasanya digunakan sebelum OTA; jika Anda perlu mencopot KernelSU, harap gunakan \"Copot permanen\". Memasang Pemasangan berhasil Pemasangan gagal @@ -210,9 +210,9 @@ Lepas untuk menyegarkan Menyegarkan… Penyegaran berhasil - Batalkan - Berhasil membatalkan penghapusan %s - Gagal membatalkan penghapusan: %s + Urungkan + Berhasil mengurungkan pencopotan %s + Gagal mengurungkan pencopotan: %s Berisi %d aplikasi Tema Pilih mode tema aplikasi diff --git a/manager/app/src/main/res/values-zh-rCN/strings.xml b/manager/app/src/main/res/values-zh-rCN/strings.xml index 4d25f1a78b93..a391d481cd52 100644 --- a/manager/app/src/main/res/values-zh-rCN/strings.xml +++ b/manager/app/src/main/res/values-zh-rCN/strings.xml @@ -174,8 +174,6 @@ 允许通过 /system/bin/su 获取 Root 权限 卸载模块(内核级) 在内核给需要的应用卸载模块 - 为 WebView 卸载模块 - 防止 WebView 进程泄露信息,但可能会导致模块失效。重启后生效 将安装以下模块:%1$s 确认 处理中… diff --git a/manager/app/src/main/res/values/strings.xml b/manager/app/src/main/res/values/strings.xml index 721bb2ce3ceb..a3441efbfc8a 100644 --- a/manager/app/src/main/res/values/strings.xml +++ b/manager/app/src/main/res/values/strings.xml @@ -194,8 +194,6 @@ Allow Root access via /system/bin/su, in new processes Kernel umount Unmount modules from kernel in App Profile - Unmount for WebView - Prevent information leaks from WebView process but may break modules. Reboot to apply Hide SELinux modification Prevent applications from detecting SELinux modifications Reboot to take effect diff --git a/uapi/feature.h b/uapi/feature.h index 1049457c2e1b..df2f68c154d4 100644 --- a/uapi/feature.h +++ b/uapi/feature.h @@ -7,7 +7,6 @@ enum ksu_feature_id { KSU_FEATURE_SULOG = 2, KSU_FEATURE_ADB_ROOT = 3, KSU_FEATURE_SELINUX_HIDE = 4, - KSU_FEATURE_WEBVIEW_ZYGOTE_UMOUNT = 5, KSU_FEATURE_MAX }; diff --git a/userspace/ksud/src/cli.rs b/userspace/ksud/src/cli.rs index 49ca63d0899a..831d858a2f4d 100644 --- a/userspace/ksud/src/cli.rs +++ b/userspace/ksud/src/cli.rs @@ -417,7 +417,7 @@ enum Profile { enum Feature { /// Get feature value and support status Get { - /// Feature ID or name (su_compat, kernel_umount, sulog, adb_root, selinux_hide, webview_zygote_umount) + /// Feature ID or name (su_compat, kernel_umount, sulog, adb_root, selinux_hide) id: String, /// Read from config file #[arg(long, default_value_t = false)] @@ -437,7 +437,7 @@ enum Feature { /// Check feature status (supported/unsupported/managed) Check { - /// Feature ID or name (su_compat, kernel_umount, sulog, adb_root, selinux_hide, webview_zygote_umount) + /// Feature ID or name (su_compat, kernel_umount, sulog, adb_root, selinux_hide) id: String, }, diff --git a/userspace/ksud/src/feature.rs b/userspace/ksud/src/feature.rs index dbdbb552c599..f64a16f61368 100644 --- a/userspace/ksud/src/feature.rs +++ b/userspace/ksud/src/feature.rs @@ -21,7 +21,6 @@ pub enum FeatureId { Sulog = 2, AdbRoot = 3, SelinuxHide = 4, - WebviewZygoteUmount = 5, } impl FeatureId { @@ -32,7 +31,6 @@ impl FeatureId { 2 => Some(Self::Sulog), 3 => Some(Self::AdbRoot), 4 => Some(Self::SelinuxHide), - 5 => Some(Self::WebviewZygoteUmount), _ => None, } } @@ -44,7 +42,6 @@ impl FeatureId { Self::Sulog => "sulog", Self::AdbRoot => "adb_root", Self::SelinuxHide => "selinux_hide", - Self::WebviewZygoteUmount => "webview_zygote_umount", } } @@ -63,9 +60,6 @@ impl FeatureId { Self::SelinuxHide => { "SELinux Hide - sanitize /sys/fs/selinux access results for app UIDs" } - Self::WebviewZygoteUmount => { - "WebView Zygote Umount - unmount modules from WebView zygote and its isolated children" - } } } } @@ -77,7 +71,6 @@ fn parse_feature_id(name: &str) -> Result { "sulog" | "2" => Ok(FeatureId::Sulog), "adb_root" | "3" => Ok(FeatureId::AdbRoot), "selinux_hide" | "4" => Ok(FeatureId::SelinuxHide), - "webview_zygote_umount" | "5" => Ok(FeatureId::WebviewZygoteUmount), _ => bail!("Unknown feature: {name}"), } } @@ -324,7 +317,6 @@ pub fn list_features() { FeatureId::Sulog, FeatureId::AdbRoot, FeatureId::SelinuxHide, - FeatureId::WebviewZygoteUmount, ]; for feature_id in &all_features { @@ -388,7 +380,6 @@ pub fn save_config() -> Result<()> { FeatureId::Sulog, FeatureId::AdbRoot, FeatureId::SelinuxHide, - FeatureId::WebviewZygoteUmount, ]; for feature_id in &all_features { diff --git a/website/docs/guide/installation.md b/website/docs/guide/installation.md index 817599d04ebd..2c6419b7937f 100644 --- a/website/docs/guide/installation.md +++ b/website/docs/guide/installation.md @@ -108,7 +108,7 @@ Open the manager, click the installation icon in the upper right corner, and sev Using the manager's "Direct install" can automatically back up the stock boot (or init_boot) image for temporarily restoring it during incremental OTA updates. Note that this backup is created only if the current slot has not already been patched by KernelSU. The SHA1 of the backup image is stored in the patched boot image, and the backup file is saved at `/data/adb/ksu/ksu_backup_$SHA1`. When you use the manager's "Uninstall → Restore stock image" feature, if there is a matching backup file for the SHA1 recorded in the currently patched image, it will be restored directly. -Since 3.2.6, if you are installing KernelSU for the first time without root, after patching the boot image via "Select a file" you can choose "Backup as stock image". In that case, the backup image is stored in the manager's internal storage; after flashing and booting the patched image, opening the manager for the first time will automatically move that backup to `/data/adb/ksu`. +Since 3.3.0, if you are installing KernelSU for the first time without root, after patching the boot image via "Select a file" you can choose "Backup as stock image". In that case, the backup image is stored in the manager's internal storage; after flashing and booting the patched image, opening the manager for the first time will automatically move that backup to `/data/adb/ksu`. ::: ### Use the command line diff --git a/website/docs/guide/x86_64-support.md b/website/docs/guide/x86_64-support.md index c0c35ce35fe0..728882c2f822 100644 --- a/website/docs/guide/x86_64-support.md +++ b/website/docs/guide/x86_64-support.md @@ -19,9 +19,9 @@ You only need to use one of them. Do not apply both at the same time. ### Option 1: Enable `KSU_X86_PATCH_SYSCALL_DISPATCHER` -KernelSU 3.2.6 introduced an official mechanism for `x86_64`: the build option `KSU_X86_PATCH_SYSCALL_DISPATCHER`. +KernelSU 3.3.0 introduced an official mechanism for `x86_64`: the build option `KSU_X86_PATCH_SYSCALL_DISPATCHER`. -When this option is enabled, KernelSU dynamically patches the hardened syscall dispatcher at runtime so the syscall hook can work without requiring the previous kernel source patch set. This is the recommended approach if you are building a kernel with KernelSU 3.2.6 or newer. +When this option is enabled, KernelSU dynamically patches the hardened syscall dispatcher at runtime so the syscall hook can work without requiring the previous kernel source patch set. This is the recommended approach if you are building a kernel with KernelSU 3.3.0 or newer. ### Option 2: Apply the original kernel source patches @@ -53,6 +53,6 @@ https://github.com/android-generic/kernel-zenith/commit/f5813e10b7630e1ccd86fc2c ## Which method should I choose? -- If you are using KernelSU 3.2.6 or newer and can change the KernelSU build configuration, enable `KSU_X86_PATCH_SYSCALL_DISPATCHER`. +- If you are using KernelSU 3.3.0 or newer and can change the KernelSU build configuration, enable `KSU_X86_PATCH_SYSCALL_DISPATCHER`. - If you prefer to keep your current kernel-side patch workflow, continue using the original source patches above. diff --git a/website/docs/id_ID/guide/installation.md b/website/docs/id_ID/guide/installation.md index 65405a23bc23..ba0e49940cba 100644 --- a/website/docs/id_ID/guide/installation.md +++ b/website/docs/id_ID/guide/installation.md @@ -108,7 +108,7 @@ Buka manajer, klik ikon instalasi di sudut kanan atas, dan beberapa opsi akan mu Menggunakan opsi "Langsung pasang (Disarankan)" di manajer dapat secara otomatis mencadangkan boot image stok (atau init_boot) agar dapat dipulihkan sementara saat pembaruan OTA inkremental. Perlu diperhatikan bahwa cadangan ini hanya dibuat jika slot saat ini belum pernah di-patch oleh KernelSU. Nilai SHA1 dari image cadangan disimpan di dalam image boot yang sudah di-patch, dan file cadangan disimpan di `/data/adb/ksu/ksu_backup_$SHA1`. Saat Anda menggunakan fitur "Hapus → Pulihkan image asli" di manajer, jika ada file cadangan yang cocok dengan SHA1 yang tercatat pada image yang sedang di-patch, cadangan tersebut akan langsung dipulihkan. -Mulai versi 3.2.6, jika ini adalah pertama kalinya Anda memasang KernelSU tanpa root, setelah mem-patch boot image melalui "Pilih berkas" Anda dapat memilih "Cadangkan sebagai image stok". Dalam kasus ini, image cadangan akan disimpan di penyimpanan internal manajer; setelah image yang sudah di-patch di-flash dan perangkat berhasil boot, saat pertama kali membuka manajer cadangan tersebut akan otomatis dipindahkan ke `/data/adb/ksu`. +Mulai versi 3.3.0, jika ini adalah pertama kalinya Anda memasang KernelSU tanpa root, setelah mem-patch boot image melalui "Pilih berkas" Anda dapat memilih "Cadangkan sebagai image stok". Dalam kasus ini, image cadangan akan disimpan di penyimpanan internal manajer; setelah image yang sudah di-patch di-flash dan perangkat berhasil boot, saat pertama kali membuka manajer cadangan tersebut akan otomatis dipindahkan ke `/data/adb/ksu`. ::: ### Gunakan baris perintah diff --git a/website/docs/id_ID/guide/x86_64-support.md b/website/docs/id_ID/guide/x86_64-support.md index fe2887c01fdf..48dff33f4a3b 100644 --- a/website/docs/id_ID/guide/x86_64-support.md +++ b/website/docs/id_ID/guide/x86_64-support.md @@ -19,9 +19,9 @@ Anda hanya perlu memakai salah satunya. Jangan menerapkan keduanya sekaligus. ### Opsi 1: Aktifkan `KSU_X86_PATCH_SYSCALL_DISPATCHER` -KernelSU 3.2.6 memperkenalkan mekanisme resmi baru untuk `x86_64`, yaitu opsi build `KSU_X86_PATCH_SYSCALL_DISPATCHER`. +KernelSU 3.3.0 memperkenalkan mekanisme resmi baru untuk `x86_64`, yaitu opsi build `KSU_X86_PATCH_SYSCALL_DISPATCHER`. -Saat opsi ini diaktifkan, KernelSU akan melakukan patch dinamis pada hardened syscall dispatcher saat runtime sehingga syscall hook dapat bekerja tanpa memerlukan kumpulan patch kode sumber kernel lama. Ini adalah pendekatan yang direkomendasikan jika Anda membangun kernel dengan KernelSU 3.2.6 atau yang lebih baru. +Saat opsi ini diaktifkan, KernelSU akan melakukan patch dinamis pada hardened syscall dispatcher saat runtime sehingga syscall hook dapat bekerja tanpa memerlukan kumpulan patch kode sumber kernel lama. Ini adalah pendekatan yang direkomendasikan jika Anda membangun kernel dengan KernelSU 3.3.0 atau yang lebih baru. ### Opsi 2: Terapkan patch kode sumber kernel lama @@ -53,5 +53,5 @@ https://github.com/android-generic/kernel-zenith/commit/f5813e10b7630e1ccd86fc2c ## Metode mana yang sebaiknya dipilih? -- Jika Anda menggunakan KernelSU 3.2.6 atau lebih baru dan bisa mengubah konfigurasi build KernelSU, aktifkan `KSU_X86_PATCH_SYSCALL_DISPATCHER`. +- Jika Anda menggunakan KernelSU 3.3.0 atau lebih baru dan bisa mengubah konfigurasi build KernelSU, aktifkan `KSU_X86_PATCH_SYSCALL_DISPATCHER`. - Jika Anda ingin mempertahankan alur kerja patch kernel saat ini, lanjutkan menggunakan patch kode sumber di atas. diff --git a/website/docs/ja_JP/guide/installation.md b/website/docs/ja_JP/guide/installation.md index 20173419d3b7..add3460d323f 100644 --- a/website/docs/ja_JP/guide/installation.md +++ b/website/docs/ja_JP/guide/installation.md @@ -106,7 +106,7 @@ GKI モードとは異なり、LKM モードは `ramdisk` を展開します。 マネージャーの「直接インストール」を使うと、増分 OTA の際に一時的に復元できるよう、純正の boot(または init_boot)イメージを自動的にバックアップできます。このバックアップが作成されるのは、現在のスロットがまだ KernelSU によってパッチされていない場合のみです。 バックアップイメージの SHA1 はパッチ済みの boot イメージに保存され、バックアップファイルは `/data/adb/ksu/ksu_backup_$SHA1` に保存されます。 マネージャーの「アンインストール → ストックイメージを復元」を使うと、現在パッチされているイメージに記録された SHA1 に対応するバックアップファイルが存在する場合、そのバックアップが直接復元されます。 -3.2.6 以降、root なしで初めて KernelSU をインストールする場合は、「ファイルを選択しパッチを当てる」で boot イメージをパッチしたあとに「純正イメージとしてバックアップ」を選択できます。この場合、バックアップイメージはマネージャーの内部ストレージに保存され、パッチ済みイメージを書き込んで起動したあと、初回起動時にそのバックアップが自動的に `/data/adb/ksu` へ移動されます。 +3.3.0 以降、root なしで初めて KernelSU をインストールする場合は、「ファイルを選択しパッチを当てる」で boot イメージをパッチしたあとに「純正イメージとしてバックアップ」を選択できます。この場合、バックアップイメージはマネージャーの内部ストレージに保存され、パッチ済みイメージを書き込んで起動したあと、初回起動時にそのバックアップが自動的に `/data/adb/ksu` へ移動されます。 ::: ### コマンドラインを使う diff --git a/website/docs/ja_JP/guide/x86_64-support.md b/website/docs/ja_JP/guide/x86_64-support.md index db361e8a460a..f888320ff2e1 100644 --- a/website/docs/ja_JP/guide/x86_64-support.md +++ b/website/docs/ja_JP/guide/x86_64-support.md @@ -19,9 +19,9 @@ KernelSU の `syscall_hook` は、フックしたシステムコールを統一 ### 方法 1: `KSU_X86_PATCH_SYSCALL_DISPATCHER` を有効にする -KernelSU 3.2.6 では、`x86_64` 向けの新しい公式メカニズムとして `KSU_X86_PATCH_SYSCALL_DISPATCHER` ビルドオプションが追加されました。 +KernelSU 3.3.0 では、`x86_64` 向けの新しい公式メカニズムとして `KSU_X86_PATCH_SYSCALL_DISPATCHER` ビルドオプションが追加されました。 -このオプションを有効にすると、KernelSU は hardened syscall dispatcher を実行時に動的パッチし、従来のカーネルソースパッチを要求せずに syscall hook を動作させます。KernelSU 3.2.6 以降でカーネルをビルドする場合は、この方法を推奨します。 +このオプションを有効にすると、KernelSU は hardened syscall dispatcher を実行時に動的パッチし、従来のカーネルソースパッチを要求せずに syscall hook を動作させます。KernelSU 3.3.0 以降でカーネルをビルドする場合は、この方法を推奨します。 ### 方法 2: 従来のカーネルソースパッチを適用する @@ -53,5 +53,5 @@ https://github.com/android-generic/kernel-zenith/commit/f5813e10b7630e1ccd86fc2c ## どちらを選ぶべきですか? -- KernelSU 3.2.6 以降を使っていて、KernelSU のビルド設定を変更できるなら `KSU_X86_PATCH_SYSCALL_DISPATCHER` を有効にしてください。 +- KernelSU 3.3.0 以降を使っていて、KernelSU のビルド設定を変更できるなら `KSU_X86_PATCH_SYSCALL_DISPATCHER` を有効にしてください。 - 現在のカーネルパッチ運用を維持したいなら、上記の従来のソースパッチを使い続けてください。 diff --git a/website/docs/pt_BR/guide/installation.md b/website/docs/pt_BR/guide/installation.md index cf59f6d956ea..c8f83fb4613e 100644 --- a/website/docs/pt_BR/guide/installation.md +++ b/website/docs/pt_BR/guide/installation.md @@ -108,7 +108,7 @@ Abra o gerenciador, clique no ícone de instalação no canto superior direito e Usar a opção "Instalação direta" do gerenciador pode fazer backup automaticamente da imagem boot original (ou init_boot), para restaurá-la temporariamente durante atualizações OTA incrementais. Observe que esse backup só é criado se o slot atual ainda não tiver sido corrigido pelo KernelSU. O valor SHA1 da imagem de backup é salvo na imagem boot corrigida, e o arquivo de backup é armazenado em `/data/adb/ksu/ksu_backup_$SHA1`. Ao usar a função "Desinstalar → Restaurar imagem de fábrica" do gerenciador, se existir um arquivo de backup correspondente ao SHA1 registrado na imagem atualmente corrigida, ele será restaurado diretamente. -Desde a versão 3.2.6, se esta for a sua primeira instalação do KernelSU sem root, depois de corrigir a imagem boot por meio de "Selecione um arquivo", você poderá escolher "Fazer backup como imagem original". Nesse caso, a imagem de backup será armazenada no armazenamento interno do gerenciador; depois de fazer o flash e inicializar a imagem corrigida, ao abrir o gerenciador pela primeira vez esse backup será movido automaticamente para `/data/adb/ksu`. +Desde a versão 3.3.0, se esta for a sua primeira instalação do KernelSU sem root, depois de corrigir a imagem boot por meio de "Selecione um arquivo", você poderá escolher "Fazer backup como imagem original". Nesse caso, a imagem de backup será armazenada no armazenamento interno do gerenciador; depois de fazer o flash e inicializar a imagem corrigida, ao abrir o gerenciador pela primeira vez esse backup será movido automaticamente para `/data/adb/ksu`. ::: ### Use a linha de comando diff --git a/website/docs/pt_BR/guide/x86_64-support.md b/website/docs/pt_BR/guide/x86_64-support.md index c2938e054be7..22c3fe7a9472 100644 --- a/website/docs/pt_BR/guide/x86_64-support.md +++ b/website/docs/pt_BR/guide/x86_64-support.md @@ -19,9 +19,9 @@ Você só precisa usar uma delas. Não aplique ambas ao mesmo tempo. ### Opção 1: Ativar `KSU_X86_PATCH_SYSCALL_DISPATCHER` -O KernelSU 3.2.6 introduziu um novo mecanismo oficial para `x86_64`: a opção de build `KSU_X86_PATCH_SYSCALL_DISPATCHER`. +O KernelSU 3.3.0 introduziu um novo mecanismo oficial para `x86_64`: a opção de build `KSU_X86_PATCH_SYSCALL_DISPATCHER`. -Quando essa opção está ativada, o KernelSU aplica um patch dinâmico no dispatcher hardened de syscall em tempo de execução, permitindo que o syscall hook funcione sem exigir o conjunto anterior de patches no código-fonte do kernel. Essa é a abordagem recomendada se você estiver compilando um kernel com KernelSU 3.2.6 ou mais recente. +Quando essa opção está ativada, o KernelSU aplica um patch dinâmico no dispatcher hardened de syscall em tempo de execução, permitindo que o syscall hook funcione sem exigir o conjunto anterior de patches no código-fonte do kernel. Essa é a abordagem recomendada se você estiver compilando um kernel com KernelSU 3.3.0 ou mais recente. ### Opção 2: Aplicar os patches originais no código-fonte do kernel @@ -53,5 +53,5 @@ https://github.com/android-generic/kernel-zenith/commit/f5813e10b7630e1ccd86fc2c ## Qual método devo escolher? -- Se você estiver usando KernelSU 3.2.6 ou mais recente e puder alterar a configuração de build do KernelSU, ative `KSU_X86_PATCH_SYSCALL_DISPATCHER`. +- Se você estiver usando KernelSU 3.3.0 ou mais recente e puder alterar a configuração de build do KernelSU, ative `KSU_X86_PATCH_SYSCALL_DISPATCHER`. - Se preferir manter seu fluxo atual baseado em patches no kernel, continue usando os patches de código-fonte acima. diff --git a/website/docs/ru_RU/guide/installation.md b/website/docs/ru_RU/guide/installation.md index a2f9563950a6..2f609cea0083 100644 --- a/website/docs/ru_RU/guide/installation.md +++ b/website/docs/ru_RU/guide/installation.md @@ -109,7 +109,7 @@ Open the manager, click the installation icon in the upper right corner, and sev Использование пункта «Прямая установка (Рекомендуется)» в менеджере позволяет автоматически сохранить резервную копию стокового boot-образа (или init_boot), чтобы временно восстановить его во время инкрементальных OTA-обновлений. Обратите внимание: такая резервная копия создаётся только в том случае, если текущий слот ещё не был пропатчен KernelSU. SHA1 резервной копии сохраняется внутри пропатченного boot-образа, а сам файл резервной копии хранится по пути `/data/adb/ksu/ksu_backup_$SHA1`. Когда вы используете функцию менеджера «Удалить → Восстановить сток образ», и для SHA1, записанного в текущем пропатченном образе, существует соответствующий файл резервной копии, он будет восстановлен напрямую. -Начиная с версии 3.2.6, если вы впервые устанавливаете KernelSU без root, после патча boot-образа через пункт «Выбрать файл» можно выбрать «Сохранить резервную копию как оригинальный образ». В этом случае резервная копия будет сохранена во внутреннем хранилище менеджера; после прошивки и загрузки пропатченного образа при первом открытии менеджера эта копия автоматически переместится в `/data/adb/ksu`. +Начиная с версии 3.3.0, если вы впервые устанавливаете KernelSU без root, после патча boot-образа через пункт «Выбрать файл» можно выбрать «Сохранить резервную копию как оригинальный образ». В этом случае резервная копия будет сохранена во внутреннем хранилище менеджера; после прошивки и загрузки пропатченного образа при первом открытии менеджера эта копия автоматически переместится в `/data/adb/ksu`. ::: ### Использование командной строки diff --git a/website/docs/ru_RU/guide/x86_64-support.md b/website/docs/ru_RU/guide/x86_64-support.md index 59ce56a12bf1..a90bd14cfadc 100644 --- a/website/docs/ru_RU/guide/x86_64-support.md +++ b/website/docs/ru_RU/guide/x86_64-support.md @@ -19,9 +19,9 @@ KernelSU полностью поддерживает архитектуру `x86 ### Вариант 1: включить `KSU_X86_PATCH_SYSCALL_DISPATCHER` -В KernelSU 3.2.6 был добавлен новый официальный механизм для `x86_64`: опция сборки `KSU_X86_PATCH_SYSCALL_DISPATCHER`. +В KernelSU 3.3.0 был добавлен новый официальный механизм для `x86_64`: опция сборки `KSU_X86_PATCH_SYSCALL_DISPATCHER`. -Когда эта опция включена, KernelSU динамически патчит hardened dispatcher системных вызовов во время выполнения, чтобы syscall hook работал без прежнего набора патчей исходного кода ядра. Это рекомендуемый вариант, если вы собираете ядро с KernelSU 3.2.6 или новее. +Когда эта опция включена, KernelSU динамически патчит hardened dispatcher системных вызовов во время выполнения, чтобы syscall hook работал без прежнего набора патчей исходного кода ядра. Это рекомендуемый вариант, если вы собираете ядро с KernelSU 3.3.0 или новее. ### Вариант 2: применить исходные патчи к исходному коду ядра @@ -53,5 +53,5 @@ https://github.com/android-generic/kernel-zenith/commit/f5813e10b7630e1ccd86fc2c ## Какой вариант выбрать? -- Если вы используете KernelSU 3.2.6 или новее и можете изменить конфигурацию сборки KernelSU, включите `KSU_X86_PATCH_SYSCALL_DISPATCHER`. +- Если вы используете KernelSU 3.3.0 или новее и можете изменить конфигурацию сборки KernelSU, включите `KSU_X86_PATCH_SYSCALL_DISPATCHER`. - Если вы хотите сохранить текущий workflow с патчами ядра, продолжайте использовать исходные патчи выше. diff --git a/website/docs/vi_VN/guide/installation.md b/website/docs/vi_VN/guide/installation.md index c32fa687a47d..064f23c73733 100644 --- a/website/docs/vi_VN/guide/installation.md +++ b/website/docs/vi_VN/guide/installation.md @@ -109,7 +109,7 @@ Open the manager, click the installation icon in the upper right corner, and sev Sử dụng tùy chọn "Cài đặt trực tiếp (Khuyến nghị)" trong trình quản lý có thể tự động sao lưu boot image gốc (hoặc init_boot) để tạm thời khôi phục trong các bản cập nhật OTA gia tăng. Lưu ý rằng bản sao lưu này chỉ được tạo nếu khe hiện tại chưa từng được KernelSU patch. Giá trị SHA1 của image sao lưu sẽ được lưu trong boot image đã patch, và tệp sao lưu được lưu tại `/data/adb/ksu/ksu_backup_$SHA1`. Khi bạn dùng tính năng "Gỡ cài đặt → Khôi phục image gốc" trong trình quản lý, nếu tồn tại tệp sao lưu khớp với SHA1 được ghi trong image hiện đang được patch, tệp đó sẽ được khôi phục trực tiếp. -Kể từ phiên bản 3.2.6, nếu đây là lần đầu bạn cài KernelSU mà không có root, sau khi patch boot image bằng tùy chọn "Chọn file", bạn có thể chọn "Sao lưu thành ảnh gốc". Khi đó, image sao lưu sẽ được lưu trong bộ nhớ trong của trình quản lý; sau khi flash và khởi động bằng image đã patch, lần đầu mở trình quản lý sẽ tự động chuyển bản sao lưu đó tới `/data/adb/ksu`. +Kể từ phiên bản 3.3.0, nếu đây là lần đầu bạn cài KernelSU mà không có root, sau khi patch boot image bằng tùy chọn "Chọn file", bạn có thể chọn "Sao lưu thành ảnh gốc". Khi đó, image sao lưu sẽ được lưu trong bộ nhớ trong của trình quản lý; sau khi flash và khởi động bằng image đã patch, lần đầu mở trình quản lý sẽ tự động chuyển bản sao lưu đó tới `/data/adb/ksu`. ::: ### Sử dụng dòng lệnh diff --git a/website/docs/vi_VN/guide/x86_64-support.md b/website/docs/vi_VN/guide/x86_64-support.md index 7cad39ae492c..b915cb3c4122 100644 --- a/website/docs/vi_VN/guide/x86_64-support.md +++ b/website/docs/vi_VN/guide/x86_64-support.md @@ -19,9 +19,9 @@ Bạn chỉ cần dùng một trong hai. Không áp dụng cả hai cùng lúc. ### Cách 1: Bật `KSU_X86_PATCH_SYSCALL_DISPATCHER` -KernelSU 3.2.6 đã giới thiệu cơ chế chính thức mới cho `x86_64`: tùy chọn build `KSU_X86_PATCH_SYSCALL_DISPATCHER`. +KernelSU 3.3.0 đã giới thiệu cơ chế chính thức mới cho `x86_64`: tùy chọn build `KSU_X86_PATCH_SYSCALL_DISPATCHER`. -Khi tùy chọn này được bật, KernelSU sẽ tự động vá động hardened syscall dispatcher trong lúc chạy để syscall hook hoạt động mà không cần bộ vá mã nguồn kernel cũ. Đây là cách được khuyến nghị nếu bạn đang build kernel với KernelSU 3.2.6 hoặc mới hơn. +Khi tùy chọn này được bật, KernelSU sẽ tự động vá động hardened syscall dispatcher trong lúc chạy để syscall hook hoạt động mà không cần bộ vá mã nguồn kernel cũ. Đây là cách được khuyến nghị nếu bạn đang build kernel với KernelSU 3.3.0 hoặc mới hơn. ### Cách 2: Áp dụng bộ vá mã nguồn kernel cũ @@ -53,5 +53,5 @@ https://github.com/android-generic/kernel-zenith/commit/f5813e10b7630e1ccd86fc2c ## Nên chọn cách nào? -- Nếu bạn đang dùng KernelSU 3.2.6 trở lên và có thể thay đổi cấu hình build của KernelSU, hãy bật `KSU_X86_PATCH_SYSCALL_DISPATCHER`. +- Nếu bạn đang dùng KernelSU 3.3.0 trở lên và có thể thay đổi cấu hình build của KernelSU, hãy bật `KSU_X86_PATCH_SYSCALL_DISPATCHER`. - Nếu bạn muốn giữ quy trình vá kernel hiện tại, hãy tiếp tục dùng bộ vá mã nguồn ở trên. diff --git a/website/docs/zh_CN/guide/installation.md b/website/docs/zh_CN/guide/installation.md index 9b9c9bd324cc..5161ce03ab0e 100644 --- a/website/docs/zh_CN/guide/installation.md +++ b/website/docs/zh_CN/guide/installation.md @@ -108,7 +108,7 @@ GKI 模式会替换掉设备原有的内核,使用 KernelSU 提供的通用内 使用管理器的「直接安装」可自动备份原厂 boot (或 init_boot)镜像,以备增量 OTA 时临时还原。请注意,这种情况下只有当前分区没有被 KernelSU 修补过,才会产生备份。 备份镜像的 SHA1 值会保存到修补的 boot 镜像中,备份的文件存储在 `/data/adb/ksu/ksu_backup_$SHA1` 。 当使用管理器的「卸载 → 还原原厂镜像」功能时,如果当前修补的镜像记录的 SHA1 存在对应的备份文件,则会直接恢复。 -自 3.2.6 起,如果是在没有 Root 的情况下首次安装 KernelSU ,使用「选择并修补一个文件」方式修补 boot 镜像后可选择「备份为原厂镜像」,此时备份镜像会保存到管理器的内部存储中,这样刷入修补后的镜像后启动,首次打开管理器就会自动将备份移动到 `/data/adb/ksu` 。 +自 3.3.0 起,如果是在没有 Root 的情况下首次安装 KernelSU ,使用「选择并修补一个文件」方式修补 boot 镜像后可选择「备份为原厂镜像」,此时备份镜像会保存到管理器的内部存储中,这样刷入修补后的镜像后启动,首次打开管理器就会自动将备份移动到 `/data/adb/ksu` 。 ::: ### 使用命令行 diff --git a/website/docs/zh_CN/guide/x86_64-support.md b/website/docs/zh_CN/guide/x86_64-support.md index f651fa3e0983..810523a7137f 100644 --- a/website/docs/zh_CN/guide/x86_64-support.md +++ b/website/docs/zh_CN/guide/x86_64-support.md @@ -19,9 +19,9 @@ KernelSU 的 `syscall_hook` 机制依赖对系统调用表的修改,从而把 ### 方案 1:启用 `KSU_X86_PATCH_SYSCALL_DISPATCHER` -KernelSU 3.2.6 为 `x86_64` 新增了官方机制,即编译选项 `KSU_X86_PATCH_SYSCALL_DISPATCHER`。 +KernelSU 3.3.0 为 `x86_64` 新增了官方机制,即编译选项 `KSU_X86_PATCH_SYSCALL_DISPATCHER`。 -启用后,KernelSU 会在运行时动态 patch 已加固的 syscall dispatcher,使 syscall hook 可以正常工作,而不再依赖之前那组内核源码补丁。如果你使用的是 KernelSU 3.2.6 或更新版本,并且可以调整 KernelSU 的构建配置,建议优先采用这种方式。 +启用后,KernelSU 会在运行时动态 patch 已加固的 syscall dispatcher,使 syscall hook 可以正常工作,而不再依赖之前那组内核源码补丁。如果你使用的是 KernelSU 3.3.0 或更新版本,并且可以调整 KernelSU 的构建配置,建议优先采用这种方式。 ### 方案 2:应用原有的内核源码补丁 @@ -53,5 +53,5 @@ https://github.com/android-generic/kernel-zenith/commit/f5813e10b7630e1ccd86fc2c ## 应该选择哪种方案? -- 如果你使用的是 KernelSU 3.2.6 或更新版本,且可以修改 KernelSU 构建配置,建议启用 `KSU_X86_PATCH_SYSCALL_DISPATCHER`。 +- 如果你使用的是 KernelSU 3.3.0 或更新版本,且可以修改 KernelSU 构建配置,建议启用 `KSU_X86_PATCH_SYSCALL_DISPATCHER`。 - 如果你希望继续保持现有的内核补丁工作流,则继续使用上面的源码补丁方案。 diff --git a/website/docs/zh_TW/guide/installation.md b/website/docs/zh_TW/guide/installation.md index 0f84eaddd147..fde9e6c46397 100644 --- a/website/docs/zh_TW/guide/installation.md +++ b/website/docs/zh_TW/guide/installation.md @@ -109,7 +109,7 @@ GKI 模式會替換掉裝置原有的核心,使用 KernelSU 提供的通用核 使用管理器的「直接安裝」可自動備份原廠 boot(或 init_boot)映像,以便在增量 OTA 時臨時還原。請注意,只有當前分區尚未被 KernelSU 修補過時,才會建立此備份。 備份映像的 SHA1 會寫入修補後的 boot 映像中,備份檔則儲存在 `/data/adb/ksu/ksu_backup_$SHA1`。 當你使用管理器的「解除安裝 → 恢復原廠映像檔」功能時,如果目前修補映像中記錄的 SHA1 有對應的備份檔案,便會直接進行還原。 -自 3.2.6 起,如果是在沒有 root 的情況下首次安裝 KernelSU,在透過「選擇檔案」修補 boot 映像後,可選擇「備份為原廠映像」。此時備份映像會儲存在管理器的內部儲存空間中;刷入並啟動修補後的映像後,首次開啟管理器時會自動將該備份移動到 `/data/adb/ksu`。 +自 3.3.0 起,如果是在沒有 root 的情況下首次安裝 KernelSU,在透過「選擇檔案」修補 boot 映像後,可選擇「備份為原廠映像」。此時備份映像會儲存在管理器的內部儲存空間中;刷入並啟動修補後的映像後,首次開啟管理器時會自動將該備份移動到 `/data/adb/ksu`。 ::: ### 使用命令列{#use-the-command-line} diff --git a/website/docs/zh_TW/guide/x86_64-support.md b/website/docs/zh_TW/guide/x86_64-support.md index 2cfd9135869b..24259615d3cd 100644 --- a/website/docs/zh_TW/guide/x86_64-support.md +++ b/website/docs/zh_TW/guide/x86_64-support.md @@ -19,9 +19,9 @@ KernelSU 的 `syscall_hook` 機制依賴對系統呼叫表的修改,藉此將 ### 方案 1:啟用 `KSU_X86_PATCH_SYSCALL_DISPATCHER` -KernelSU 3.2.6 為 `x86_64` 新增了官方機制,也就是編譯選項 `KSU_X86_PATCH_SYSCALL_DISPATCHER`。 +KernelSU 3.3.0 為 `x86_64` 新增了官方機制,也就是編譯選項 `KSU_X86_PATCH_SYSCALL_DISPATCHER`。 -啟用後,KernelSU 會在執行時動態 patch 已加固的 syscall dispatcher,讓 syscall hook 可以正常運作,而不再依賴先前那組核心原始碼補丁。如果你使用的是 KernelSU 3.2.6 或更新版本,且可以調整 KernelSU 的建置設定,建議優先採用這種方式。 +啟用後,KernelSU 會在執行時動態 patch 已加固的 syscall dispatcher,讓 syscall hook 可以正常運作,而不再依賴先前那組核心原始碼補丁。如果你使用的是 KernelSU 3.3.0 或更新版本,且可以調整 KernelSU 的建置設定,建議優先採用這種方式。 ### 方案 2:套用原本的核心原始碼補丁 @@ -53,5 +53,5 @@ https://github.com/android-generic/kernel-zenith/commit/f5813e10b7630e1ccd86fc2c ## 應該選哪種方案? -- 如果你使用的是 KernelSU 3.2.6 或更新版本,且可以修改 KernelSU 建置設定,建議啟用 `KSU_X86_PATCH_SYSCALL_DISPATCHER`。 +- 如果你使用的是 KernelSU 3.3.0 或更新版本,且可以修改 KernelSU 建置設定,建議啟用 `KSU_X86_PATCH_SYSCALL_DISPATCHER`。 - 如果你想維持既有的核心補丁工作流程,則繼續使用上面的原始碼補丁方案。