Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4690f60df1 | ||
| c5b5a845ca | |||
| 040a963057 | |||
| 748f871653 | |||
| 05f1f0e8ed | |||
| de0192dc4a | |||
| 80e2aa98df | |||
|
|
a55c22fb49 | ||
|
|
c2ed70f194 | ||
|
|
a8e2438ed7 | ||
|
|
80f8e3c2cd | ||
| 82e165bf0f | |||
| 554cb1a323 | |||
| ad59cb74fb | |||
|
|
279a6593f7 | ||
|
|
8ca971ee16 | ||
|
|
4ae147b467 | ||
|
|
a085d1695a | ||
| b6a9ff0178 |
3
KernelSU-Next/.gitignore
vendored
3
KernelSU-Next/.gitignore
vendored
@@ -1,5 +1,2 @@
|
||||
.idea
|
||||
.vscode
|
||||
*.orig
|
||||
*.rej
|
||||
*.patch
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# This script builds the KernelSU Next manager APK.
|
||||
|
||||
# Ensure you have the setup Android SDK & NDK installed and necessary environment variables set and sourced.
|
||||
|
||||
# For LKM make sure you have imported the androidX-X.X_kernelsu.ko drivers to userspace/ksud_*/bin/aarch64 directory.
|
||||
|
||||
cross build --target aarch64-linux-android --release --manifest-path ./userspace/ksud_magic/Cargo.toml
|
||||
|
||||
cp userspace/ksud_magic/target/aarch64-linux-android/release/ksud manager/app/src/main/jniLibs/arm64-v8a/libksud_magic.so
|
||||
|
||||
cross build --target aarch64-linux-android --release --manifest-path ./userspace/ksud_overlayfs/Cargo.toml
|
||||
|
||||
cp userspace/ksud_overlayfs/target/aarch64-linux-android/release/ksud manager/app/src/main/jniLibs/arm64-v8a/libksud_overlayfs.so
|
||||
|
||||
cd userspace/susfsd/jni
|
||||
|
||||
ndk-build
|
||||
|
||||
cp ../libs/arm64-v8a/susfsd ../../../manager/app/src/main/jniLibs/arm64-v8a/libsusfsd.so
|
||||
|
||||
cd ../../..
|
||||
|
||||
cd manager
|
||||
|
||||
./setup.sh
|
||||
|
||||
cd ..
|
||||
|
||||
adb install manager/app/build/outputs/apk/release/KernelSU_Next_v*.apk
|
||||
@@ -74,7 +74,6 @@ If you’d like to support the project:
|
||||
|
||||
- **USDT (BEP20, ERC20)**: `0x12b5224b7aca0121c2f003240a901e1d064371c1`
|
||||
- **USDT (TRC20)**: `TYUVMWGTcnR5svnDoX85DWHyqUAeyQcdjh`
|
||||
- **USDT (SOL)**: `A4wqBXYd6Ey4nK4SJ2bmjeMgGyaLKT9TwDLh8BEo8Zu6`
|
||||
- **ETH (ERC20)**: `0x12b5224b7aca0121c2f003240a901e1d064371c1`
|
||||
- **LTC**: `Ld238uYBuRQdZB5YwdbkuU6ektBAAUByoL`
|
||||
- **BTC**: `19QgifcjMjSr1wB2DJcea5cxitvWVcXMT6`
|
||||
@@ -88,4 +87,5 @@ If you’d like to support the project:
|
||||
- [Genuine](https://github.com/brevent/genuine/) – APK v2 signature validation
|
||||
- [Diamorphine](https://github.com/m0nad/Diamorphine) – Rootkit techniques
|
||||
- [KernelSU](https://github.com/tiann/KernelSU) – The original base that made KernelSU Next possible
|
||||
- [Magic Mount Port](https://github.com/5ec1cff/KernelSU/blob/main/userspace/ksud/src/magic_mount.rs) – For magic mount support
|
||||
- [Magic Mount Port](https://github.com/5ec1cff/KernelSU/blob/main/userspace/ksud/src/magic_mount.rs) – 💜 to 5ec1cff for keeping KernelSU alive
|
||||
- [Crowdin Translators](https://crowdin.com/project/kernelsu-next/members) – 💬 Thanks to everyone for helping make KernelSU Next multi-lingual!
|
||||
|
||||
@@ -40,139 +40,4 @@ config KSU_LSM_SECURITY_HOOKS
|
||||
Disabling this is mostly only useful for kernel 4.1 and older.
|
||||
Make sure to implement manual hooks on security/security.c.
|
||||
|
||||
menu "KernelSU - SUSFS"
|
||||
config KSU_SUSFS
|
||||
bool "KernelSU addon - SUSFS"
|
||||
depends on KSU
|
||||
depends on THREAD_INFO_IN_TASK
|
||||
default y
|
||||
help
|
||||
Patch and Enable SUSFS to kernel with KernelSU.
|
||||
|
||||
config KSU_SUSFS_HAS_MAGIC_MOUNT
|
||||
bool "Say yes if the current KernelSU repo has magic mount implemented (default y)"
|
||||
depends on KSU_SUSFS
|
||||
default y
|
||||
help
|
||||
- Enable to indicate that the current SUSFS kernel supports the auto hide features for 5ec1cff's Magic Mount KernelSU
|
||||
- Every mounts from /debug_ramdisk/workdir will be treated as magic mount and processed differently by susfs
|
||||
|
||||
config KSU_SUSFS_SUS_PATH
|
||||
bool "Enable to hide suspicious path (NOT recommended)"
|
||||
depends on KSU_SUSFS
|
||||
default y
|
||||
help
|
||||
- Allow hiding the user-defined path and all its sub-paths from various system calls.
|
||||
- Includes temp fix for the leaks of app path in /sdcard/Android/data directory.
|
||||
- Effective only on zygote spawned user app process.
|
||||
- Use with cautious as it may cause performance loss and will be vulnerable to side channel attacks,
|
||||
just disable this feature if it doesn't work for you or you don't need it at all.
|
||||
|
||||
config KSU_SUSFS_SUS_MOUNT
|
||||
bool "Enable to hide suspicious mounts"
|
||||
depends on KSU_SUSFS
|
||||
default y
|
||||
help
|
||||
- Allow hiding the user-defined mount paths from /proc/self/[mounts|mountinfo|mountstat].
|
||||
- Effective on all processes for hiding mount entries.
|
||||
- Mounts mounted by process with ksu domain will be forced to be assigned the dev name "KSU".
|
||||
- mnt_id and mnt_group_id of the sus mount will be assigned to a much bigger number to solve the issue of id not being contiguous.
|
||||
|
||||
config KSU_SUSFS_AUTO_ADD_SUS_KSU_DEFAULT_MOUNT
|
||||
bool "Enable to hide KSU's default mounts automatically (experimental)"
|
||||
depends on KSU_SUSFS_SUS_MOUNT
|
||||
default y
|
||||
help
|
||||
- Automatically add KSU's default mounts to sus_mount.
|
||||
- No susfs command is needed in userspace.
|
||||
- Only mount operation from process with ksu domain will be checked.
|
||||
|
||||
config KSU_SUSFS_AUTO_ADD_SUS_BIND_MOUNT
|
||||
bool "Enable to hide suspicious bind mounts automatically (experimental)"
|
||||
depends on KSU_SUSFS_SUS_MOUNT
|
||||
default y
|
||||
help
|
||||
- Automatically add binded mounts to sus_mount.
|
||||
- No susfs command is needed in userspace.
|
||||
- Only mount operation from process with ksu domain will be checked.
|
||||
|
||||
config KSU_SUSFS_SUS_KSTAT
|
||||
bool "Enable to spoof suspicious kstat"
|
||||
depends on KSU_SUSFS
|
||||
default y
|
||||
help
|
||||
- Allow spoofing the kstat of user-defined file/directory.
|
||||
- Effective only on zygote spawned user app process.
|
||||
|
||||
config KSU_SUSFS_TRY_UMOUNT
|
||||
bool "Enable to use ksu's ksu_try_umount"
|
||||
depends on KSU_SUSFS
|
||||
default y
|
||||
help
|
||||
- Allow using ksu_try_umount to umount other user-defined mount paths prior to ksu's default umount paths.
|
||||
- Effective on all NO-root-access-granted processes.
|
||||
|
||||
config KSU_SUSFS_AUTO_ADD_TRY_UMOUNT_FOR_BIND_MOUNT
|
||||
bool "Enable to add bind mounts to ksu's ksu_try_umount automatically (experimental)"
|
||||
depends on KSU_SUSFS_TRY_UMOUNT
|
||||
default y
|
||||
help
|
||||
- Automatically add binded mounts to ksu's ksu_try_umount.
|
||||
- No susfs command is needed in userspace.
|
||||
- Only mount operation from process with ksu domain will be checked.
|
||||
|
||||
config KSU_SUSFS_SPOOF_UNAME
|
||||
bool "Enable to spoof uname"
|
||||
depends on KSU_SUSFS
|
||||
default y
|
||||
help
|
||||
- Allow spoofing the string returned by uname syscall to user-defined string.
|
||||
- Effective on all processes.
|
||||
|
||||
config KSU_SUSFS_ENABLE_LOG
|
||||
bool "Enable logging susfs log to kernel"
|
||||
depends on KSU_SUSFS
|
||||
default y
|
||||
help
|
||||
- Allow logging susfs log to kernel, uncheck it to completely disable all susfs log.
|
||||
|
||||
config KSU_SUSFS_HIDE_KSU_SUSFS_SYMBOLS
|
||||
bool "Enable to automatically hide ksu and susfs symbols from /proc/kallsyms"
|
||||
depends on KSU_SUSFS
|
||||
default y
|
||||
help
|
||||
- Automatically hide ksu and susfs symbols from '/proc/kallsyms'.
|
||||
- Effective on all processes.
|
||||
|
||||
config KSU_SUSFS_SPOOF_CMDLINE_OR_BOOTCONFIG
|
||||
bool "Enable to spoof /proc/bootconfig (gki) or /proc/cmdline (non-gki)"
|
||||
depends on KSU_SUSFS
|
||||
default y
|
||||
help
|
||||
- Spoof the output of /proc/bootconfig (gki) or /proc/cmdline (non-gki) with a user-defined file.
|
||||
- Effective on all processes.
|
||||
|
||||
config KSU_SUSFS_OPEN_REDIRECT
|
||||
bool "Enable to redirect a path to be opened with another path (experimental)"
|
||||
depends on KSU_SUSFS
|
||||
default y
|
||||
help
|
||||
- Allow redirecting a target path to be opened with another user-defined path.
|
||||
- Effective only on processes with uid < 2000.
|
||||
- Please be reminded that process with open access to the target and redirected path can be detected.
|
||||
|
||||
config KSU_SUSFS_SUS_SU
|
||||
bool "Enable SUS-SU in runtime temporarily"
|
||||
depends on KSU_SUSFS && KPROBES && HAVE_KPROBES && KPROBE_EVENTS
|
||||
default y
|
||||
help
|
||||
- Allow user to enable or disable core ksu kprobes hooks temporarily in runtime. There are 2 working modes for sus_su.
|
||||
- Mode 0 (default): Disable sus_su, and enable ksu kprobe hooks for su instead.
|
||||
- Mode 1 (deprecated):
|
||||
- Mode 2: Enable sus_su, and disable ksu kprobe hooks for su, which means the kernel inline hooks are enabled,
|
||||
the same as the su implementaion of non-gki kernel without kprobe supported.
|
||||
- Only apps with root access granted by ksu manager are allowed to get root.
|
||||
|
||||
endmenu
|
||||
|
||||
endmenu
|
||||
|
||||
@@ -57,14 +57,6 @@ ifndef KSU_NEXT_EXPECTED_HASH
|
||||
KSU_NEXT_EXPECTED_HASH := 79e590113c4c4c0c222978e413a5faa801666957b1212a328e46c00c69821bf7
|
||||
endif
|
||||
|
||||
ifndef KSU_NEXT_WILD_EXPECTED_SIZE
|
||||
KSU_NEXT_WILD_EXPECTED_SIZE := 0x39b
|
||||
endif
|
||||
|
||||
ifndef KSU_NEXT_WILD_EXPECTED_HASH
|
||||
KSU_NEXT_WILD_EXPECTED_HASH := 593d4ce870c02468639efeef631e07ca4d852d63f154be56706229f9a5be0800
|
||||
endif
|
||||
|
||||
ifdef KSU_MANAGER_PACKAGE
|
||||
ccflags-y += -DKSU_MANAGER_PACKAGE=\"$(KSU_MANAGER_PACKAGE)\"
|
||||
$(info -- KernelSU-Next Manager package name: $(KSU_MANAGER_PACKAGE))
|
||||
@@ -72,13 +64,9 @@ endif
|
||||
|
||||
$(info -- KernelSU-Next Manager signature size: $(KSU_NEXT_EXPECTED_SIZE))
|
||||
$(info -- KernelSU-Next Manager signature hash: $(KSU_NEXT_EXPECTED_HASH))
|
||||
$(info -- KernelSU-Next Wild Manager signature size: $(KSU_NEXT_WILD_EXPECTED_SIZE))
|
||||
$(info -- KernelSU-Next Wild Manager signature hash: $(KSU_NEXT_WILD_EXPECTED_HASH))
|
||||
|
||||
ccflags-y += -DEXPECTED_NEXT_SIZE=$(KSU_NEXT_EXPECTED_SIZE)
|
||||
ccflags-y += -DEXPECTED_NEXT_HASH=\"$(KSU_NEXT_EXPECTED_HASH)\"
|
||||
ccflags-y += -DEXPECTED_WILD_NEXT_SIZE=$(KSU_NEXT_WILD_EXPECTED_SIZE)
|
||||
ccflags-y += -DEXPECTED_WILD_NEXT_HASH=\"$(KSU_NEXT_WILD_EXPECTED_HASH)\"
|
||||
|
||||
ccflags-y += -DKSU_UMOUNT
|
||||
|
||||
@@ -128,81 +116,4 @@ endif
|
||||
ccflags-y += -Wno-implicit-function-declaration -Wno-strict-prototypes -Wno-int-conversion -Wno-gcc-compat
|
||||
ccflags-y += -Wno-declaration-after-statement -Wno-unused-function
|
||||
|
||||
## For non-gki compatiblity ##
|
||||
ifeq ($(shell grep -q " current_sid(void)" $(srctree)/security/selinux/include/objsec.h; echo $$?),0)
|
||||
ccflags-y += -DKSU_COMPAT_HAS_CURRENT_SID
|
||||
endif
|
||||
|
||||
ifeq ($(shell grep -q "struct selinux_state " $(srctree)/security/selinux/include/security.h; echo $$?),0)
|
||||
ccflags-y += -DKSU_COMPAT_HAS_SELINUX_STATE
|
||||
endif
|
||||
|
||||
ccflags-y += -DKSU_UMOUNT
|
||||
ifneq ($(shell grep -Eq "get_cred_rcu" $(srctree)/include/linux/cred.h; echo $$?),0)
|
||||
$(info -- KSU_SUSFS: adding function 'static inline const struct cred *get_cred_rcu();' to $(srctree)/include/linux/cred.h)
|
||||
GET_CRED_RCU = static inline const struct cred *get_cred_rcu(const struct cred *cred)\n\
|
||||
{\n\t\
|
||||
struct cred *nonconst_cred = (struct cred *) cred;\n\t\
|
||||
if (!cred)\n\t\t\
|
||||
return NULL;\n\t\
|
||||
if (!atomic_inc_not_zero(&nonconst_cred->usage))\n\t\t\
|
||||
return NULL;\n\t\
|
||||
validate_creds(cred);\n\t\
|
||||
return cred;\n\
|
||||
}\n
|
||||
$(shell sed -i '/^static inline void put_cred/i $(GET_CRED_RCU)' $(srctree)/include/linux/cred.h;)
|
||||
endif
|
||||
|
||||
ifneq ($(shell grep -Eq "^static int can_umount" $(srctree)/fs/namespace.c; echo $$?),0)
|
||||
$(info -- KSU_SUSFS: adding function 'static int can_umount(const struct path *path, int flags);' to $(srctree)/fs/namespace.c)
|
||||
CAN_UMOUNT = static int can_umount(const struct path *path, int flags)\n\
|
||||
{\n\t\
|
||||
struct mount *mnt = real_mount(path->mnt);\n\t\
|
||||
if (flags & ~(MNT_FORCE | MNT_DETACH | MNT_EXPIRE | UMOUNT_NOFOLLOW))\n\t\t\
|
||||
return -EINVAL;\n\t\
|
||||
if (!may_mount())\n\t\t\
|
||||
return -EPERM;\n\t\
|
||||
if (path->dentry != path->mnt->mnt_root)\n\t\t\
|
||||
return -EINVAL;\n\t\
|
||||
if (!check_mnt(mnt))\n\t\t\
|
||||
return -EINVAL;\n\t\
|
||||
if (mnt->mnt.mnt_flags & MNT_LOCKED)\n\t\t\
|
||||
return -EINVAL;\n\t\
|
||||
if (flags & MNT_FORCE && !capable(CAP_SYS_ADMIN))\n\t\t\
|
||||
return -EPERM;\n\t\
|
||||
return 0;\n\
|
||||
}\n
|
||||
$(shell sed -i '/^static bool is_mnt_ns_file/i $(CAN_UMOUNT)' $(srctree)/fs/namespace.c;)
|
||||
endif
|
||||
|
||||
ifneq ($(shell grep -Eq "^int path_umount" $(srctree)/fs/namespace.c; echo $$?),0)
|
||||
$(info -- KSU_SUSFS: adding function 'int path_umount(struct path *path, int flags);' to $(srctree)/fs/namespace.c)
|
||||
PATH_UMOUNT = int path_umount(struct path *path, int flags)\n\
|
||||
{\n\t\
|
||||
struct mount *mnt = real_mount(path->mnt);\n\t\
|
||||
int ret;\n\t\
|
||||
ret = can_umount(path, flags);\n\t\
|
||||
if (!ret)\n\t\t\
|
||||
ret = do_umount(mnt, flags);\n\t\
|
||||
dput(path->dentry);\n\t\
|
||||
mntput_no_expire(mnt);\n\t\
|
||||
return ret;\n\
|
||||
}\n
|
||||
$(shell sed -i '/^static bool is_mnt_ns_file/i $(PATH_UMOUNT)' $(srctree)/fs/namespace.c;)
|
||||
endif
|
||||
|
||||
ifneq ($(shell grep -Eq "^int path_umount" $(srctree)/fs/internal.h; echo $$?),0)
|
||||
$(shell sed -i '/^extern void __init mnt_init/a int path_umount(struct path *path, int flags);' $(srctree)/fs/internal.h;)
|
||||
$(info -- KSU_SUSFS: adding 'int path_umount(struct path *path, int flags);' to $(srctree)/fs/internal.h)
|
||||
endif
|
||||
|
||||
## For susfs stuff ##
|
||||
ifeq ($(shell test -e $(srctree)/fs/susfs.c; echo $$?),0)
|
||||
$(eval SUSFS_VERSION=$(shell cat $(srctree)/include/linux/susfs.h | grep -E '^#define SUSFS_VERSION' | cut -d' ' -f3 | sed 's/"//g'))
|
||||
$(info )
|
||||
$(info -- SUSFS_VERSION: $(SUSFS_VERSION))
|
||||
else
|
||||
$(info -- You have not integrate susfs in your kernel.)
|
||||
$(info -- Read: https://gitlab.com/simonpunk/susfs4ksu)
|
||||
endif
|
||||
# Keep a new line here!! Because someone may append config
|
||||
|
||||
@@ -95,7 +95,7 @@ static uint8_t allow_list_bitmap[PAGE_SIZE] __read_mostly __aligned(PAGE_SIZE);
|
||||
static struct work_struct ksu_save_work;
|
||||
static struct work_struct ksu_load_work;
|
||||
|
||||
static bool persistent_allow_list(void);
|
||||
bool persistent_allow_list(void);
|
||||
|
||||
void ksu_show_allow_list(void)
|
||||
{
|
||||
@@ -266,7 +266,7 @@ bool __ksu_is_allow_uid(uid_t uid)
|
||||
|
||||
if (unlikely(uid == 0)) {
|
||||
// already root, but only allow our domain.
|
||||
return ksu_is_ksu_domain();
|
||||
return is_ksu_domain();
|
||||
}
|
||||
|
||||
if (forbid_system_uid(uid)) {
|
||||
@@ -351,7 +351,7 @@ bool ksu_get_allow_list(int *array, int *length, bool allow)
|
||||
return true;
|
||||
}
|
||||
|
||||
static void do_save_allow_list(struct work_struct *work)
|
||||
void do_save_allow_list(struct work_struct *work)
|
||||
{
|
||||
u32 magic = FILE_MAGIC;
|
||||
u32 version = FILE_FORMAT_VERSION;
|
||||
@@ -393,7 +393,7 @@ exit:
|
||||
filp_close(fp, 0);
|
||||
}
|
||||
|
||||
static void do_load_allow_list(struct work_struct *work)
|
||||
void do_load_allow_list(struct work_struct *work)
|
||||
{
|
||||
loff_t off = 0;
|
||||
ssize_t ret = 0;
|
||||
@@ -483,7 +483,7 @@ void ksu_prune_allowlist(bool (*is_uid_valid)(uid_t, char *, void *), void *data
|
||||
}
|
||||
|
||||
// make sure allow list works cross boot
|
||||
static bool persistent_allow_list(void)
|
||||
bool persistent_allow_list(void)
|
||||
{
|
||||
return ksu_queue_work(&ksu_save_work);
|
||||
}
|
||||
|
||||
@@ -315,7 +315,7 @@ module_param_cb(ksu_debug_manager_uid, &expected_size_ops,
|
||||
|
||||
#endif
|
||||
|
||||
bool ksu_is_manager_apk(char *path)
|
||||
bool is_manager_apk(char *path)
|
||||
{
|
||||
int tries = 0;
|
||||
|
||||
@@ -333,5 +333,5 @@ bool ksu_is_manager_apk(char *path)
|
||||
return false;
|
||||
}
|
||||
|
||||
return (check_v2_signature(path, EXPECTED_NEXT_SIZE, EXPECTED_NEXT_HASH) || check_v2_signature(path, EXPECTED_WILD_NEXT_SIZE, EXPECTED_WILD_NEXT_HASH));
|
||||
return check_v2_signature(path, EXPECTED_NEXT_SIZE, EXPECTED_NEXT_HASH);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
bool ksu_is_manager_apk(char *path);
|
||||
bool is_manager_apk(char *path);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -35,10 +35,6 @@
|
||||
#include <linux/vmalloc.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS
|
||||
#include <linux/susfs.h>
|
||||
#endif // #ifdef CONFIG_KSU_SUSFS
|
||||
|
||||
#include "allowlist.h"
|
||||
#include "arch.h"
|
||||
#include "core_hook.h"
|
||||
@@ -48,94 +44,20 @@
|
||||
#include "manager.h"
|
||||
#include "selinux/selinux.h"
|
||||
#include "throne_tracker.h"
|
||||
#include "throne_tracker.h"
|
||||
#include "kernel_compat.h"
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS
|
||||
bool susfs_is_allow_su(void)
|
||||
{
|
||||
if (ksu_is_manager()) {
|
||||
// we are manager, allow!
|
||||
return true;
|
||||
}
|
||||
return ksu_is_allow_uid(current_uid().val);
|
||||
}
|
||||
|
||||
extern u32 susfs_zygote_sid;
|
||||
extern bool susfs_is_mnt_devname_ksu(struct path *path);
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
extern void susfs_run_sus_path_loop(uid_t uid);
|
||||
#endif // #ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
#ifdef CONFIG_KSU_SUSFS_ENABLE_LOG
|
||||
extern bool susfs_is_log_enabled __read_mostly;
|
||||
#endif // #ifdef CONFIG_KSU_SUSFS_ENABLE_LOG
|
||||
#ifdef CONFIG_KSU_SUSFS_TRY_UMOUNT
|
||||
extern void susfs_run_try_umount_for_current_mnt_ns(void);
|
||||
#endif // #ifdef CONFIG_KSU_SUSFS_TRY_UMOUNT
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT
|
||||
static bool susfs_is_umount_for_zygote_system_process_enabled = false;
|
||||
static bool susfs_is_umount_for_zygote_iso_service_enabled = false;
|
||||
extern bool susfs_hide_sus_mnts_for_all_procs;
|
||||
#endif // #ifdef CONFIG_KSU_SUSFS_SUS_MOUNT
|
||||
#ifdef CONFIG_KSU_SUSFS_AUTO_ADD_SUS_BIND_MOUNT
|
||||
extern bool susfs_is_auto_add_sus_bind_mount_enabled;
|
||||
#endif // #ifdef CONFIG_KSU_SUSFS_AUTO_ADD_SUS_BIND_MOUNT
|
||||
#ifdef CONFIG_KSU_SUSFS_AUTO_ADD_SUS_KSU_DEFAULT_MOUNT
|
||||
extern bool susfs_is_auto_add_sus_ksu_default_mount_enabled;
|
||||
#endif // #ifdef CONFIG_KSU_SUSFS_AUTO_ADD_SUS_KSU_DEFAULT_MOUNT
|
||||
#ifdef CONFIG_KSU_SUSFS_AUTO_ADD_TRY_UMOUNT_FOR_BIND_MOUNT
|
||||
extern bool susfs_is_auto_add_try_umount_for_bind_mount_enabled;
|
||||
#endif // #ifdef CONFIG_KSU_SUSFS_AUTO_ADD_TRY_UMOUNT_FOR_BIND_MOUNT
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_SU
|
||||
extern bool susfs_is_sus_su_ready;
|
||||
extern int susfs_sus_su_working_mode;
|
||||
extern bool susfs_is_sus_su_hooks_enabled __read_mostly;
|
||||
extern bool ksu_devpts_hook;
|
||||
#endif // #ifdef CONFIG_KSU_SUSFS_SUS_SU
|
||||
|
||||
static inline void susfs_on_post_fs_data(void) {
|
||||
struct path path;
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT
|
||||
if (!kern_path(DATA_ADB_UMOUNT_FOR_ZYGOTE_SYSTEM_PROCESS, 0, &path)) {
|
||||
susfs_is_umount_for_zygote_system_process_enabled = true;
|
||||
path_put(&path);
|
||||
}
|
||||
pr_info("susfs_is_umount_for_zygote_system_process_enabled: %d\n", susfs_is_umount_for_zygote_system_process_enabled);
|
||||
#endif // #ifdef CONFIG_KSU_SUSFS_SUS_MOUNT
|
||||
#ifdef CONFIG_KSU_SUSFS_AUTO_ADD_SUS_BIND_MOUNT
|
||||
if (!kern_path(DATA_ADB_NO_AUTO_ADD_SUS_BIND_MOUNT, 0, &path)) {
|
||||
susfs_is_auto_add_sus_bind_mount_enabled = false;
|
||||
path_put(&path);
|
||||
}
|
||||
pr_info("susfs_is_auto_add_sus_bind_mount_enabled: %d\n", susfs_is_auto_add_sus_bind_mount_enabled);
|
||||
#endif // #ifdef CONFIG_KSU_SUSFS_AUTO_ADD_SUS_BIND_MOUNT
|
||||
#ifdef CONFIG_KSU_SUSFS_AUTO_ADD_SUS_KSU_DEFAULT_MOUNT
|
||||
if (!kern_path(DATA_ADB_NO_AUTO_ADD_SUS_KSU_DEFAULT_MOUNT, 0, &path)) {
|
||||
susfs_is_auto_add_sus_ksu_default_mount_enabled = false;
|
||||
path_put(&path);
|
||||
}
|
||||
pr_info("susfs_is_auto_add_sus_ksu_default_mount_enabled: %d\n", susfs_is_auto_add_sus_ksu_default_mount_enabled);
|
||||
#endif // #ifdef CONFIG_KSU_SUSFS_AUTO_ADD_SUS_KSU_DEFAULT_MOUNT
|
||||
#ifdef CONFIG_KSU_SUSFS_AUTO_ADD_TRY_UMOUNT_FOR_BIND_MOUNT
|
||||
if (!kern_path(DATA_ADB_NO_AUTO_ADD_TRY_UMOUNT_FOR_BIND_MOUNT, 0, &path)) {
|
||||
susfs_is_auto_add_try_umount_for_bind_mount_enabled = false;
|
||||
path_put(&path);
|
||||
}
|
||||
pr_info("susfs_is_auto_add_try_umount_for_bind_mount_enabled: %d\n", susfs_is_auto_add_try_umount_for_bind_mount_enabled);
|
||||
#endif // #ifdef CONFIG_KSU_SUSFS_AUTO_ADD_TRY_UMOUNT_FOR_BIND_MOUNT
|
||||
}
|
||||
#endif // #ifdef CONFIG_KSU_SUSFS
|
||||
|
||||
static bool ksu_module_mounted = false;
|
||||
|
||||
extern int ksu_handle_sepolicy(unsigned long arg3, void __user *arg4);
|
||||
extern int handle_sepolicy(unsigned long arg3, void __user *arg4);
|
||||
|
||||
bool ksu_su_compat_enabled = true;
|
||||
static bool ksu_su_compat_enabled = true;
|
||||
extern void ksu_sucompat_init();
|
||||
extern void ksu_sucompat_exit();
|
||||
|
||||
static inline bool is_allow_su()
|
||||
{
|
||||
if (ksu_is_manager()) {
|
||||
if (is_manager()) {
|
||||
// we are manager, allow!
|
||||
return true;
|
||||
}
|
||||
@@ -213,7 +135,7 @@ static void disable_seccomp(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
void ksu_escape_to_root(void)
|
||||
void escape_to_root(void)
|
||||
{
|
||||
struct cred *cred;
|
||||
|
||||
@@ -271,7 +193,7 @@ void ksu_escape_to_root(void)
|
||||
disable_seccomp();
|
||||
spin_unlock_irq(¤t->sighand->siglock);
|
||||
|
||||
ksu_setup_selinux(profile->selinux_domain);
|
||||
setup_selinux(profile->selinux_domain);
|
||||
}
|
||||
|
||||
int ksu_handle_rename(struct dentry *old_dentry, struct dentry *new_dentry)
|
||||
@@ -308,7 +230,7 @@ int ksu_handle_rename(struct dentry *old_dentry, struct dentry *new_dentry)
|
||||
pr_info("renameat: %s -> %s, new path: %s\n", old_dentry->d_iname,
|
||||
new_dentry->d_iname, buf);
|
||||
|
||||
ksu_track_throne();
|
||||
track_throne();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -333,34 +255,6 @@ static void nuke_ext4_sysfs() {
|
||||
path_put(&path);
|
||||
}
|
||||
|
||||
static bool is_system_bin_su(void)
|
||||
{
|
||||
static const char *su_paths[] = {
|
||||
"/system/bin/su",
|
||||
"/vendor/bin/su",
|
||||
"/product/bin/su",
|
||||
"/system_ext/bin/su",
|
||||
"/odm/bin/su",
|
||||
"/system/xbin/su",
|
||||
"/system_ext/xbin/su"
|
||||
};
|
||||
char path_buf[256];
|
||||
char *pathname;
|
||||
int i;
|
||||
|
||||
struct mm_struct *mm = current->mm;
|
||||
if (mm && mm->exe_file) {
|
||||
pathname = d_path(&mm->exe_file->f_path, path_buf, sizeof(path_buf));
|
||||
if (!IS_ERR(pathname)) {
|
||||
for (i = 0; i < ARRAY_SIZE(su_paths); i++) {
|
||||
if (strcmp(pathname, su_paths[i]) == 0)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
|
||||
unsigned long arg4, unsigned long arg5)
|
||||
{
|
||||
@@ -381,20 +275,12 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
|
||||
}
|
||||
|
||||
bool from_root = 0 == current_uid().val;
|
||||
bool from_manager = ksu_is_manager();
|
||||
bool from_manager = is_manager();
|
||||
|
||||
#ifdef CONFIG_KSU_KPROBES_HOOK
|
||||
if (!from_root && !from_manager
|
||||
&& !(is_allow_su() && is_system_bin_su())) {
|
||||
// only root or manager can access this interface
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
if (!from_root && !from_manager) {
|
||||
// only root or manager can access this interface
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KSU_DEBUG
|
||||
pr_info("option: 0x%x, cmd: %ld\n", option, arg2);
|
||||
@@ -413,7 +299,7 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
|
||||
if (arg2 == CMD_GRANT_ROOT) {
|
||||
if (is_allow_su()) {
|
||||
pr_info("allow root for: %d\n", current_uid().val);
|
||||
ksu_escape_to_root();
|
||||
escape_to_root();
|
||||
if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) {
|
||||
pr_err("grant_root: prctl reply error\n");
|
||||
}
|
||||
@@ -468,13 +354,10 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
|
||||
switch (arg3) {
|
||||
case EVENT_POST_FS_DATA: {
|
||||
static bool post_fs_data_lock = false;
|
||||
#ifdef CONFIG_KSU_SUSFS
|
||||
susfs_on_post_fs_data();
|
||||
#endif
|
||||
if (!post_fs_data_lock) {
|
||||
post_fs_data_lock = true;
|
||||
pr_info("post-fs-data triggered\n");
|
||||
ksu_on_post_fs_data();
|
||||
on_post_fs_data();
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -502,7 +385,7 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
|
||||
if (!from_root) {
|
||||
return 0;
|
||||
}
|
||||
if (!ksu_handle_sepolicy(arg3, arg4)) {
|
||||
if (!handle_sepolicy(arg3, arg4)) {
|
||||
if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) {
|
||||
pr_err("sepolicy: prctl reply error\n");
|
||||
}
|
||||
@@ -563,394 +446,6 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_KSU_KPROBES_HOOK
|
||||
if (arg2 == CMD_ENABLE_SU) {
|
||||
bool enabled = (arg3 != 0);
|
||||
if (enabled == ksu_su_compat_enabled) {
|
||||
pr_info("cmd enable su but no need to change.\n");
|
||||
if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) {// return the reply_ok directly
|
||||
pr_err("prctl reply error, cmd: %lu\n", arg2);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (enabled) {
|
||||
ksu_sucompat_init();
|
||||
} else {
|
||||
ksu_sucompat_exit();
|
||||
}
|
||||
ksu_su_compat_enabled = enabled;
|
||||
|
||||
if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) {
|
||||
pr_err("prctl reply error, cmd: %lu\n", arg2);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS
|
||||
if (current_uid_val == 0) {
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
if (arg2 == CMD_SUSFS_ADD_SUS_PATH) {
|
||||
int error = 0;
|
||||
if (!ksu_access_ok((void __user*)arg3, sizeof(struct st_susfs_sus_path))) {
|
||||
pr_err("susfs: CMD_SUSFS_ADD_SUS_PATH -> arg3 is not accessible\n");
|
||||
return 0;
|
||||
}
|
||||
if (!ksu_access_ok((void __user*)arg5, sizeof(error))) {
|
||||
pr_err("susfs: CMD_SUSFS_ADD_SUS_PATH -> arg5 is not accessible\n");
|
||||
return 0;
|
||||
}
|
||||
error = susfs_add_sus_path((struct st_susfs_sus_path __user*)arg3);
|
||||
pr_info("susfs: CMD_SUSFS_ADD_SUS_PATH -> ret: %d\n", error);
|
||||
if (copy_to_user((void __user*)arg5, &error, sizeof(error)))
|
||||
pr_info("susfs: copy_to_user() failed\n");
|
||||
return 0;
|
||||
}
|
||||
if (arg2 == CMD_SUSFS_ADD_SUS_PATH_LOOP) {
|
||||
int error = 0;
|
||||
if (!ksu_access_ok((void __user*)arg3, sizeof(struct st_susfs_sus_path))) {
|
||||
pr_err("susfs: CMD_SUSFS_ADD_SUS_PATH_LOOP -> arg3 is not accessible\n");
|
||||
return 0;
|
||||
}
|
||||
if (!ksu_access_ok((void __user*)arg5, sizeof(error))) {
|
||||
pr_err("susfs: CMD_SUSFS_ADD_SUS_PATH_LOOP -> arg5 is not accessible\n");
|
||||
return 0;
|
||||
}
|
||||
error = susfs_add_sus_path_loop((struct st_susfs_sus_path __user*)arg3);
|
||||
pr_info("susfs: CMD_SUSFS_ADD_SUS_PATH_LOOP -> ret: %d\n", error);
|
||||
if (copy_to_user((void __user*)arg5, &error, sizeof(error)))
|
||||
pr_info("susfs: copy_to_user() failed\n");
|
||||
return 0;
|
||||
}
|
||||
if (arg2 == CMD_SUSFS_SET_ANDROID_DATA_ROOT_PATH) {
|
||||
int error = 0;
|
||||
if (!ksu_access_ok((void __user*)arg3, SUSFS_MAX_LEN_PATHNAME)) {
|
||||
pr_err("susfs: CMD_SUSFS_SET_ANDROID_DATA_ROOT_PATH -> arg3 is not accessible\n");
|
||||
return 0;
|
||||
}
|
||||
if (!ksu_access_ok((void __user*)arg5, sizeof(error))) {
|
||||
pr_err("susfs: CMD_SUSFS_SET_ANDROID_DATA_ROOT_PATH -> arg5 is not accessible\n");
|
||||
return 0;
|
||||
}
|
||||
error = susfs_set_i_state_on_external_dir((char __user*)arg3, CMD_SUSFS_SET_ANDROID_DATA_ROOT_PATH);
|
||||
pr_info("susfs: CMD_SUSFS_SET_ANDROID_DATA_ROOT_PATH -> ret: %d\n", error);
|
||||
if (copy_to_user((void __user*)arg5, &error, sizeof(error)))
|
||||
pr_info("susfs: copy_to_user() failed\n");
|
||||
return 0;
|
||||
}
|
||||
if (arg2 == CMD_SUSFS_SET_SDCARD_ROOT_PATH) {
|
||||
int error = 0;
|
||||
if (!ksu_access_ok((void __user*)arg3, SUSFS_MAX_LEN_PATHNAME)) {
|
||||
pr_err("susfs: CMD_SUSFS_SET_SDCARD_ROOT_PATH -> arg3 is not accessible\n");
|
||||
return 0;
|
||||
}
|
||||
if (!ksu_access_ok((void __user*)arg5, sizeof(error))) {
|
||||
pr_err("susfs: CMD_SUSFS_SET_SDCARD_ROOT_PATH -> arg5 is not accessible\n");
|
||||
return 0;
|
||||
}
|
||||
error = susfs_set_i_state_on_external_dir((char __user*)arg3, CMD_SUSFS_SET_SDCARD_ROOT_PATH);
|
||||
pr_info("susfs: CMD_SUSFS_SET_SDCARD_ROOT_PATH -> ret: %d\n", error);
|
||||
if (copy_to_user((void __user*)arg5, &error, sizeof(error)))
|
||||
pr_info("susfs: copy_to_user() failed\n");
|
||||
return 0;
|
||||
}
|
||||
#endif //#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT
|
||||
if (arg2 == CMD_SUSFS_ADD_SUS_MOUNT) {
|
||||
int error = 0;
|
||||
if (!ksu_access_ok((void __user*)arg3, sizeof(struct st_susfs_sus_mount))) {
|
||||
pr_err("susfs: CMD_SUSFS_ADD_SUS_MOUNT -> arg3 is not accessible\n");
|
||||
return 0;
|
||||
}
|
||||
if (!ksu_access_ok((void __user*)arg5, sizeof(error))) {
|
||||
pr_err("susfs: CMD_SUSFS_ADD_SUS_MOUNT -> arg5 is not accessible\n");
|
||||
return 0;
|
||||
}
|
||||
error = susfs_add_sus_mount((struct st_susfs_sus_mount __user*)arg3);
|
||||
pr_info("susfs: CMD_SUSFS_ADD_SUS_MOUNT -> ret: %d\n", error);
|
||||
if (copy_to_user((void __user*)arg5, &error, sizeof(error)))
|
||||
pr_info("susfs: copy_to_user() failed\n");
|
||||
return 0;
|
||||
}
|
||||
if (arg2 == CMD_SUSFS_HIDE_SUS_MNTS_FOR_ALL_PROCS) {
|
||||
int error = 0;
|
||||
if (arg3 != 0 && arg3 != 1) {
|
||||
pr_err("susfs: CMD_SUSFS_HIDE_SUS_MNTS_FOR_ALL_PROCS -> arg3 can only be 0 or 1\n");
|
||||
return 0;
|
||||
}
|
||||
susfs_hide_sus_mnts_for_all_procs = arg3;
|
||||
pr_info("susfs: CMD_SUSFS_HIDE_SUS_MNTS_FOR_ALL_PROCS -> susfs_hide_sus_mnts_for_all_procs: %lu\n", arg3);
|
||||
if (copy_to_user((void __user*)arg5, &error, sizeof(error)))
|
||||
pr_info("susfs: copy_to_user() failed\n");
|
||||
return 0;
|
||||
}
|
||||
if (arg2 == CMD_SUSFS_UMOUNT_FOR_ZYGOTE_ISO_SERVICE) {
|
||||
int error = 0;
|
||||
if (arg3 != 0 && arg3 != 1) {
|
||||
pr_err("susfs: CMD_SUSFS_UMOUNT_FOR_ZYGOTE_ISO_SERVICE -> arg3 can only be 0 or 1\n");
|
||||
return 0;
|
||||
}
|
||||
susfs_is_umount_for_zygote_iso_service_enabled = arg3;
|
||||
pr_info("susfs: CMD_SUSFS_UMOUNT_FOR_ZYGOTE_ISO_SERVICE -> susfs_is_umount_for_zygote_iso_service_enabled: %lu\n", arg3);
|
||||
if (copy_to_user((void __user*)arg5, &error, sizeof(error)))
|
||||
pr_info("susfs: copy_to_user() failed\n");
|
||||
return 0;
|
||||
}
|
||||
#endif //#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_KSTAT
|
||||
if (arg2 == CMD_SUSFS_ADD_SUS_KSTAT) {
|
||||
int error = 0;
|
||||
if (!ksu_access_ok((void __user*)arg3, sizeof(struct st_susfs_sus_kstat))) {
|
||||
pr_err("susfs: CMD_SUSFS_ADD_SUS_KSTAT -> arg3 is not accessible\n");
|
||||
return 0;
|
||||
}
|
||||
if (!ksu_access_ok((void __user*)arg5, sizeof(error))) {
|
||||
pr_err("susfs: CMD_SUSFS_ADD_SUS_KSTAT -> arg5 is not accessible\n");
|
||||
return 0;
|
||||
}
|
||||
error = susfs_add_sus_kstat((struct st_susfs_sus_kstat __user*)arg3);
|
||||
pr_info("susfs: CMD_SUSFS_ADD_SUS_KSTAT -> ret: %d\n", error);
|
||||
if (copy_to_user((void __user*)arg5, &error, sizeof(error)))
|
||||
pr_info("susfs: copy_to_user() failed\n");
|
||||
return 0;
|
||||
}
|
||||
if (arg2 == CMD_SUSFS_UPDATE_SUS_KSTAT) {
|
||||
int error = 0;
|
||||
if (!ksu_access_ok((void __user*)arg3, sizeof(struct st_susfs_sus_kstat))) {
|
||||
pr_err("susfs: CMD_SUSFS_UPDATE_SUS_KSTAT -> arg3 is not accessible\n");
|
||||
return 0;
|
||||
}
|
||||
if (!ksu_access_ok((void __user*)arg5, sizeof(error))) {
|
||||
pr_err("susfs: CMD_SUSFS_UPDATE_SUS_KSTAT -> arg5 is not accessible\n");
|
||||
return 0;
|
||||
}
|
||||
error = susfs_update_sus_kstat((struct st_susfs_sus_kstat __user*)arg3);
|
||||
pr_info("susfs: CMD_SUSFS_UPDATE_SUS_KSTAT -> ret: %d\n", error);
|
||||
if (copy_to_user((void __user*)arg5, &error, sizeof(error)))
|
||||
pr_info("susfs: copy_to_user() failed\n");
|
||||
return 0;
|
||||
}
|
||||
if (arg2 == CMD_SUSFS_ADD_SUS_KSTAT_STATICALLY) {
|
||||
int error = 0;
|
||||
if (!ksu_access_ok((void __user*)arg3, sizeof(struct st_susfs_sus_kstat))) {
|
||||
pr_err("susfs: CMD_SUSFS_ADD_SUS_KSTAT_STATICALLY -> arg3 is not accessible\n");
|
||||
return 0;
|
||||
}
|
||||
if (!ksu_access_ok((void __user*)arg5, sizeof(error))) {
|
||||
pr_err("susfs: CMD_SUSFS_ADD_SUS_KSTAT_STATICALLY -> arg5 is not accessible\n");
|
||||
return 0;
|
||||
}
|
||||
error = susfs_add_sus_kstat((struct st_susfs_sus_kstat __user*)arg3);
|
||||
pr_info("susfs: CMD_SUSFS_ADD_SUS_KSTAT_STATICALLY -> ret: %d\n", error);
|
||||
if (copy_to_user((void __user*)arg5, &error, sizeof(error)))
|
||||
pr_info("susfs: copy_to_user() failed\n");
|
||||
return 0;
|
||||
}
|
||||
#endif //#ifdef CONFIG_KSU_SUSFS_SUS_KSTAT
|
||||
#ifdef CONFIG_KSU_SUSFS_TRY_UMOUNT
|
||||
if (arg2 == CMD_SUSFS_ADD_TRY_UMOUNT) {
|
||||
int error = 0;
|
||||
if (!ksu_access_ok((void __user*)arg3, sizeof(struct st_susfs_try_umount))) {
|
||||
pr_err("susfs: CMD_SUSFS_ADD_TRY_UMOUNT -> arg3 is not accessible\n");
|
||||
return 0;
|
||||
}
|
||||
if (!ksu_access_ok((void __user*)arg5, sizeof(error))) {
|
||||
pr_err("susfs: CMD_SUSFS_ADD_TRY_UMOUNT -> arg5 is not accessible\n");
|
||||
return 0;
|
||||
}
|
||||
error = susfs_add_try_umount((struct st_susfs_try_umount __user*)arg3);
|
||||
pr_info("susfs: CMD_SUSFS_ADD_TRY_UMOUNT -> ret: %d\n", error);
|
||||
if (copy_to_user((void __user*)arg5, &error, sizeof(error)))
|
||||
pr_info("susfs: copy_to_user() failed\n");
|
||||
return 0;
|
||||
}
|
||||
if (arg2 == CMD_SUSFS_RUN_UMOUNT_FOR_CURRENT_MNT_NS) {
|
||||
int error = 0;
|
||||
susfs_run_try_umount_for_current_mnt_ns();
|
||||
pr_info("susfs: CMD_SUSFS_RUN_UMOUNT_FOR_CURRENT_MNT_NS -> ret: %d\n", error);
|
||||
}
|
||||
#endif //#ifdef CONFIG_KSU_SUSFS_TRY_UMOUNT
|
||||
#ifdef CONFIG_KSU_SUSFS_SPOOF_UNAME
|
||||
if (arg2 == CMD_SUSFS_SET_UNAME) {
|
||||
int error = 0;
|
||||
if (!ksu_access_ok((void __user*)arg3, sizeof(struct st_susfs_uname))) {
|
||||
pr_err("susfs: CMD_SUSFS_SET_UNAME -> arg3 is not accessible\n");
|
||||
return 0;
|
||||
}
|
||||
if (!ksu_access_ok((void __user*)arg5, sizeof(error))) {
|
||||
pr_err("susfs: CMD_SUSFS_SET_UNAME -> arg5 is not accessible\n");
|
||||
return 0;
|
||||
}
|
||||
error = susfs_set_uname((struct st_susfs_uname __user*)arg3);
|
||||
pr_info("susfs: CMD_SUSFS_SET_UNAME -> ret: %d\n", error);
|
||||
if (copy_to_user((void __user*)arg5, &error, sizeof(error)))
|
||||
pr_info("susfs: copy_to_user() failed\n");
|
||||
return 0;
|
||||
}
|
||||
#endif //#ifdef CONFIG_KSU_SUSFS_SPOOF_UNAME
|
||||
#ifdef CONFIG_KSU_SUSFS_ENABLE_LOG
|
||||
if (arg2 == CMD_SUSFS_ENABLE_LOG) {
|
||||
int error = 0;
|
||||
if (arg3 != 0 && arg3 != 1) {
|
||||
pr_err("susfs: CMD_SUSFS_ENABLE_LOG -> arg3 can only be 0 or 1\n");
|
||||
return 0;
|
||||
}
|
||||
susfs_set_log(arg3);
|
||||
if (copy_to_user((void __user*)arg5, &error, sizeof(error)))
|
||||
pr_info("susfs: copy_to_user() failed\n");
|
||||
return 0;
|
||||
}
|
||||
#endif //#ifdef CONFIG_KSU_SUSFS_ENABLE_LOG
|
||||
#ifdef CONFIG_KSU_SUSFS_SPOOF_CMDLINE_OR_BOOTCONFIG
|
||||
if (arg2 == CMD_SUSFS_SET_CMDLINE_OR_BOOTCONFIG) {
|
||||
int error = 0;
|
||||
if (!ksu_access_ok((void __user*)arg3, SUSFS_FAKE_CMDLINE_OR_BOOTCONFIG_SIZE)) {
|
||||
pr_err("susfs: CMD_SUSFS_SET_CMDLINE_OR_BOOTCONFIG -> arg3 is not accessible\n");
|
||||
return 0;
|
||||
}
|
||||
if (!ksu_access_ok((void __user*)arg5, sizeof(error))) {
|
||||
pr_err("susfs: CMD_SUSFS_SET_CMDLINE_OR_BOOTCONFIG -> arg5 is not accessible\n");
|
||||
return 0;
|
||||
}
|
||||
error = susfs_set_cmdline_or_bootconfig((char __user*)arg3);
|
||||
pr_info("susfs: CMD_SUSFS_SET_CMDLINE_OR_BOOTCONFIG -> ret: %d\n", error);
|
||||
if (copy_to_user((void __user*)arg5, &error, sizeof(error)))
|
||||
pr_info("susfs: copy_to_user() failed\n");
|
||||
return 0;
|
||||
}
|
||||
#endif //#ifdef CONFIG_KSU_SUSFS_SPOOF_CMDLINE_OR_BOOTCONFIG
|
||||
#ifdef CONFIG_KSU_SUSFS_OPEN_REDIRECT
|
||||
if (arg2 == CMD_SUSFS_ADD_OPEN_REDIRECT) {
|
||||
int error = 0;
|
||||
if (!ksu_access_ok((void __user*)arg3, sizeof(struct st_susfs_open_redirect))) {
|
||||
pr_err("susfs: CMD_SUSFS_ADD_OPEN_REDIRECT -> arg3 is not accessible\n");
|
||||
return 0;
|
||||
}
|
||||
if (!ksu_access_ok((void __user*)arg5, sizeof(error))) {
|
||||
pr_err("susfs: CMD_SUSFS_ADD_OPEN_REDIRECT -> arg5 is not accessible\n");
|
||||
return 0;
|
||||
}
|
||||
error = susfs_add_open_redirect((struct st_susfs_open_redirect __user*)arg3);
|
||||
pr_info("susfs: CMD_SUSFS_ADD_OPEN_REDIRECT -> ret: %d\n", error);
|
||||
if (copy_to_user((void __user*)arg5, &error, sizeof(error)))
|
||||
pr_info("susfs: copy_to_user() failed\n");
|
||||
return 0;
|
||||
}
|
||||
#endif //#ifdef CONFIG_KSU_SUSFS_OPEN_REDIRECT
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_SU
|
||||
if (arg2 == CMD_SUSFS_SUS_SU) {
|
||||
int error = 0;
|
||||
if (!ksu_access_ok((void __user*)arg3, sizeof(struct st_sus_su))) {
|
||||
pr_err("susfs: CMD_SUSFS_SUS_SU -> arg3 is not accessible\n");
|
||||
return 0;
|
||||
}
|
||||
if (!ksu_access_ok((void __user*)arg5, sizeof(error))) {
|
||||
pr_err("susfs: CMD_SUSFS_SUS_SU -> arg5 is not accessible\n");
|
||||
return 0;
|
||||
}
|
||||
error = susfs_sus_su((struct st_sus_su __user*)arg3);
|
||||
pr_info("susfs: CMD_SUSFS_SUS_SU -> ret: %d\n", error);
|
||||
if (copy_to_user((void __user*)arg5, &error, sizeof(error)))
|
||||
pr_info("susfs: copy_to_user() failed\n");
|
||||
return 0;
|
||||
}
|
||||
#endif //#ifdef CONFIG_KSU_SUSFS_SUS_SU
|
||||
if (arg2 == CMD_SUSFS_SHOW_VERSION) {
|
||||
int error = 0;
|
||||
int len_of_susfs_version = strlen(SUSFS_VERSION);
|
||||
char *susfs_version = SUSFS_VERSION;
|
||||
if (!ksu_access_ok((void __user*)arg3, len_of_susfs_version+1)) {
|
||||
pr_err("susfs: CMD_SUSFS_SHOW_VERSION -> arg3 is not accessible\n");
|
||||
return 0;
|
||||
}
|
||||
if (!ksu_access_ok((void __user*)arg5, sizeof(error))) {
|
||||
pr_err("susfs: CMD_SUSFS_SHOW_VERSION -> arg5 is not accessible\n");
|
||||
return 0;
|
||||
}
|
||||
error = copy_to_user((void __user*)arg3, (void*)susfs_version, len_of_susfs_version+1);
|
||||
pr_info("susfs: CMD_SUSFS_SHOW_VERSION -> ret: %d\n", error);
|
||||
if (copy_to_user((void __user*)arg5, &error, sizeof(error)))
|
||||
pr_info("susfs: copy_to_user() failed\n");
|
||||
return 0;
|
||||
}
|
||||
if (arg2 == CMD_SUSFS_SHOW_ENABLED_FEATURES) {
|
||||
int error = 0;
|
||||
if (arg4 <= 0) {
|
||||
pr_err("susfs: CMD_SUSFS_SHOW_ENABLED_FEATURES -> arg4 cannot be <= 0\n");
|
||||
return 0;
|
||||
}
|
||||
if (!ksu_access_ok((void __user*)arg3, arg4)) {
|
||||
pr_err("susfs: CMD_SUSFS_SHOW_ENABLED_FEATURES -> arg3 is not accessible\n");
|
||||
return 0;
|
||||
}
|
||||
if (!ksu_access_ok((void __user*)arg5, sizeof(error))) {
|
||||
pr_err("susfs: CMD_SUSFS_SHOW_ENABLED_FEATURES -> arg5 is not accessible\n");
|
||||
return 0;
|
||||
}
|
||||
error = susfs_get_enabled_features((char __user*)arg3, arg4);
|
||||
pr_info("susfs: CMD_SUSFS_SHOW_ENABLED_FEATURES -> ret: %d\n", error);
|
||||
if (copy_to_user((void __user*)arg5, &error, sizeof(error)))
|
||||
pr_info("susfs: copy_to_user() failed\n");
|
||||
return 0;
|
||||
}
|
||||
if (arg2 == CMD_SUSFS_SHOW_VARIANT) {
|
||||
int error = 0;
|
||||
int len_of_variant = strlen(SUSFS_VARIANT);
|
||||
char *susfs_variant = SUSFS_VARIANT;
|
||||
if (!ksu_access_ok((void __user*)arg3, len_of_variant+1)) {
|
||||
pr_err("susfs: CMD_SUSFS_SHOW_VARIANT -> arg3 is not accessible\n");
|
||||
return 0;
|
||||
}
|
||||
if (!ksu_access_ok((void __user*)arg5, sizeof(error))) {
|
||||
pr_err("susfs: CMD_SUSFS_SHOW_VARIANT -> arg5 is not accessible\n");
|
||||
return 0;
|
||||
}
|
||||
error = copy_to_user((void __user*)arg3, (void*)susfs_variant, len_of_variant+1);
|
||||
pr_info("susfs: CMD_SUSFS_SHOW_VARIANT -> ret: %d\n", error);
|
||||
if (copy_to_user((void __user*)arg5, &error, sizeof(error)))
|
||||
pr_info("susfs: copy_to_user() failed\n");
|
||||
return 0;
|
||||
}
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_SU
|
||||
if (arg2 == CMD_SUSFS_IS_SUS_SU_READY) {
|
||||
int error = 0;
|
||||
if (!ksu_access_ok((void __user*)arg3, sizeof(susfs_is_sus_su_ready))) {
|
||||
pr_err("susfs: CMD_SUSFS_IS_SUS_SU_READY -> arg3 is not accessible\n");
|
||||
return 0;
|
||||
}
|
||||
if (!ksu_access_ok((void __user*)arg5, sizeof(error))) {
|
||||
pr_err("susfs: CMD_SUSFS_IS_SUS_SU_READY -> arg5 is not accessible\n");
|
||||
return 0;
|
||||
}
|
||||
error = copy_to_user((void __user*)arg3, (void*)&susfs_is_sus_su_ready, sizeof(susfs_is_sus_su_ready));
|
||||
pr_info("susfs: CMD_SUSFS_IS_SUS_SU_READY -> ret: %d\n", error);
|
||||
if (copy_to_user((void __user*)arg5, &error, sizeof(error)))
|
||||
pr_info("susfs: copy_to_user() failed\n");
|
||||
return 0;
|
||||
}
|
||||
if (arg2 == CMD_SUSFS_SHOW_SUS_SU_WORKING_MODE) {
|
||||
int error = 0;
|
||||
int working_mode = susfs_get_sus_su_working_mode();
|
||||
if (!ksu_access_ok((void __user*)arg3, sizeof(working_mode))) {
|
||||
pr_err("susfs: CMD_SUSFS_SHOW_SUS_SU_WORKING_MODE -> arg3 is not accessible\n");
|
||||
return 0;
|
||||
}
|
||||
if (!ksu_access_ok((void __user*)arg5, sizeof(error))) {
|
||||
pr_err("susfs: CMD_SUSFS_SHOW_SUS_SU_WORKING_MODE -> arg5 is not accessible\n");
|
||||
return 0;
|
||||
}
|
||||
error = copy_to_user((void __user*)arg3, (void*)&working_mode, sizeof(working_mode));
|
||||
pr_info("susfs: CMD_SUSFS_SHOW_SUS_SU_WORKING_MODE -> ret: %d\n", error);
|
||||
if (copy_to_user((void __user*)arg5, &error, sizeof(error)))
|
||||
pr_info("susfs: copy_to_user() failed\n");
|
||||
return 0;
|
||||
}
|
||||
#endif // #ifdef CONFIG_KSU_SUSFS_SUS_SU
|
||||
}
|
||||
#endif //#ifdef CONFIG_KSU_SUSFS
|
||||
|
||||
// all other cmds are for 'root manager'
|
||||
if (!from_manager) {
|
||||
return 0;
|
||||
@@ -1004,7 +499,7 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#ifndef CONFIG_KSU_KPROBES_HOOK
|
||||
|
||||
if (arg2 == CMD_ENABLE_SU) {
|
||||
bool enabled = (arg3 != 0);
|
||||
if (enabled == ksu_su_compat_enabled) {
|
||||
@@ -1016,12 +511,6 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
|
||||
}
|
||||
|
||||
if (enabled) {
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_SU
|
||||
// We disable all sus_su hook whenever user toggle on su_kps
|
||||
susfs_is_sus_su_hooks_enabled = false;
|
||||
ksu_devpts_hook = false;
|
||||
susfs_sus_su_working_mode = SUS_SU_DISABLED;
|
||||
#endif
|
||||
ksu_sucompat_init();
|
||||
} else {
|
||||
ksu_sucompat_exit();
|
||||
@@ -1034,8 +523,6 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1062,15 +549,11 @@ static bool should_umount(struct path *path)
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS
|
||||
return susfs_is_mnt_devname_ksu(path);
|
||||
#else
|
||||
if (path->mnt && path->mnt->mnt_sb && path->mnt->mnt_sb->s_type) {
|
||||
const char *fstype = path->mnt->mnt_sb->s_type->name;
|
||||
return strcmp(fstype, "overlay") == 0;
|
||||
}
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int ksu_umount_mnt(struct path *path, int flags)
|
||||
@@ -1083,11 +566,7 @@ static int ksu_umount_mnt(struct path *path, int flags)
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_TRY_UMOUNT
|
||||
void ksu_try_umount(const char *mnt, bool check_mnt, int flags, uid_t uid)
|
||||
#else
|
||||
static void ksu_try_umount(const char *mnt, bool check_mnt, int flags)
|
||||
#endif
|
||||
static void try_umount(const char *mnt, bool check_mnt, int flags)
|
||||
{
|
||||
struct path path;
|
||||
int err = kern_path(mnt, 0, &path);
|
||||
@@ -1107,35 +586,12 @@ static void ksu_try_umount(const char *mnt, bool check_mnt, int flags)
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_KSU_SUSFS_TRY_UMOUNT) && defined(CONFIG_KSU_SUSFS_ENABLE_LOG)
|
||||
if (susfs_is_log_enabled) {
|
||||
pr_info("susfs: umounting '%s' for uid: %d\n", mnt, uid);
|
||||
}
|
||||
#endif
|
||||
|
||||
err = ksu_umount_mnt(&path, flags);
|
||||
if (err) {
|
||||
pr_warn("umount %s failed: %d\n", mnt, err);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_TRY_UMOUNT
|
||||
void susfs_try_umount_all(uid_t uid) {
|
||||
susfs_try_umount(uid);
|
||||
/* For Legacy KSU only */
|
||||
ksu_try_umount("/system", true, 0, uid);
|
||||
ksu_try_umount("/system_ext", true, 0, uid);
|
||||
ksu_try_umount("/vendor", true, 0, uid);
|
||||
ksu_try_umount("/product", true, 0, uid);
|
||||
ksu_try_umount("/odm", true, 0, uid);
|
||||
// - For '/data/adb/modules' we pass 'false' here because it is a loop device that we can't determine whether
|
||||
// its dev_name is KSU or not, and it is safe to just umount it if it is really a mountpoint
|
||||
ksu_try_umount("/data/adb/modules", false, MNT_DETACH, uid);
|
||||
/* For both Legacy KSU and Magic Mount KSU */
|
||||
ksu_try_umount("/debug_ramdisk", true, MNT_DETACH, uid);
|
||||
}
|
||||
#endif
|
||||
|
||||
int ksu_handle_setuid(struct cred *new, const struct cred *old)
|
||||
{
|
||||
// this hook is used for umounting overlayfs for some uid, if there isn't any module mounted, just ignore it!
|
||||
@@ -1155,53 +611,6 @@ int ksu_handle_setuid(struct cred *new, const struct cred *old)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS
|
||||
// check if current process is zygote
|
||||
bool is_zygote_child = susfs_is_sid_equal(old->security, susfs_zygote_sid);
|
||||
if (likely(is_zygote_child)) {
|
||||
// if spawned process is non user app process
|
||||
if (unlikely(new_uid.val < 10000 && new_uid.val >= 1000)) {
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_SU
|
||||
// set flag if zygote spawned system process is allowed for root access
|
||||
if (!ksu_is_allow_uid(new_uid.val)) {
|
||||
task_lock(current);
|
||||
susfs_set_current_proc_su_not_allowed();
|
||||
task_unlock(current);
|
||||
}
|
||||
#endif // #ifdef CONFIG_KSU_SUSFS_SUS_SU
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT
|
||||
// umount for the system process if path DATA_ADB_UMOUNT_FOR_ZYGOTE_SYSTEM_PROCESS exists
|
||||
if (susfs_is_umount_for_zygote_system_process_enabled) {
|
||||
goto out_ksu_try_umount;
|
||||
}
|
||||
#endif // #ifdef CONFIG_KSU_SUSFS_SUS_MOUNT
|
||||
}
|
||||
// - here we check if uid is a isolated service spawned by zygote directly
|
||||
// - Apps that do not use "useAppZyogte" to start a isolated service will be directly
|
||||
// spawned by zygote which KSU will ignore it by default, the only fix for now is to
|
||||
// force a umount for those uid
|
||||
// - Therefore make sure your root app doesn't use isolated service for root access
|
||||
// - Kudos to ThePedroo, the author and maintainer of Rezygisk for finding and reporting
|
||||
// the detection, really big helps here!
|
||||
else if (new_uid.val >= 90000 && new_uid.val < 1000000) {
|
||||
task_lock(current);
|
||||
susfs_set_current_non_root_user_app_proc();
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_SU
|
||||
susfs_set_current_proc_su_not_allowed();
|
||||
#endif // #ifdef CONFIG_KSU_SUSFS_SUS_SU
|
||||
task_unlock(current);
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
susfs_run_sus_path_loop(new_uid.val);
|
||||
#endif // #ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT
|
||||
if (susfs_is_umount_for_zygote_iso_service_enabled) {
|
||||
goto out_susfs_try_umount_all;
|
||||
}
|
||||
#endif // #ifdef CONFIG_KSU_SUSFS_SUS_MOUNT
|
||||
}
|
||||
}
|
||||
#endif // #ifdef CONFIG_KSU_SUSFS
|
||||
|
||||
if (!is_appuid(new_uid) || is_unsupported_uid(new_uid.val)) {
|
||||
// pr_info("handle setuid ignore non application or isolated uid: %d\n", new_uid.val);
|
||||
return 0;
|
||||
@@ -1211,23 +620,7 @@ int ksu_handle_setuid(struct cred *new, const struct cred *old)
|
||||
// pr_info("handle setuid ignore allowed application: %d\n", new_uid.val);
|
||||
return 0;
|
||||
}
|
||||
#ifdef CONFIG_KSU_SUSFS
|
||||
else {
|
||||
task_lock(current);
|
||||
susfs_set_current_non_root_user_app_proc();
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_SU
|
||||
susfs_set_current_proc_su_not_allowed();
|
||||
#endif // #ifdef CONFIG_KSU_SUSFS_SUS_SU
|
||||
task_unlock(current);
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
susfs_run_sus_path_loop(new_uid.val);
|
||||
#endif // #ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
}
|
||||
#endif // #ifdef CONFIG_KSU_SUSFS
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT
|
||||
out_ksu_try_umount:
|
||||
#endif
|
||||
if (!ksu_uid_should_umount(new_uid.val)) {
|
||||
return 0;
|
||||
} else {
|
||||
@@ -1236,12 +629,10 @@ out_ksu_try_umount:
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef CONFIG_KSU_SUSFS
|
||||
// check old process's selinux context, if it is not zygote, ignore it!
|
||||
// because some su apps may setuid to untrusted_app but they are in global mount namespace
|
||||
// when we umount for such process, that is a disaster!
|
||||
bool is_zygote_child = ksu_is_zygote(old->security);
|
||||
#endif
|
||||
bool is_zygote_child = is_zygote(old->security);
|
||||
if (!is_zygote_child) {
|
||||
pr_info("handle umount ignore non zygote child: %d\n",
|
||||
current->pid);
|
||||
@@ -1253,31 +644,26 @@ out_ksu_try_umount:
|
||||
current->pid);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_TRY_UMOUNT
|
||||
out_susfs_try_umount_all:
|
||||
// susfs come first, and lastly umount by ksu, make sure umount in reversed order
|
||||
susfs_try_umount_all(new_uid.val);
|
||||
#else
|
||||
// fixme: use `collect_mounts` and `iterate_mount` to iterate all mountpoint and
|
||||
// filter the mountpoint whose target is `/data/adb`
|
||||
ksu_try_umount("/odm", true, 0);
|
||||
ksu_try_umount("/system", true, 0);
|
||||
ksu_try_umount("/system_ext", true, 0);
|
||||
ksu_try_umount("/vendor", true, 0);
|
||||
ksu_try_umount("/product", true, 0);
|
||||
ksu_try_umount("/data/adb/modules", false, MNT_DETACH);
|
||||
try_umount("/odm", true, 0);
|
||||
try_umount("/system", true, 0);
|
||||
try_umount("/system_ext", true, 0);
|
||||
try_umount("/vendor", true, 0);
|
||||
try_umount("/product", true, 0);
|
||||
try_umount("/data/adb/modules", false, MNT_DETACH);
|
||||
|
||||
// try umount ksu temp path
|
||||
ksu_try_umount("/debug_ramdisk", false, MNT_DETACH);
|
||||
ksu_try_umount("/sbin", false, MNT_DETACH);
|
||||
try_umount("/debug_ramdisk", false, MNT_DETACH);
|
||||
try_umount("/sbin", false, MNT_DETACH);
|
||||
|
||||
// try umount hosts file
|
||||
ksu_try_umount("/system/etc/hosts", false, MNT_DETACH);
|
||||
try_umount("/system/etc/hosts", false, MNT_DETACH);
|
||||
|
||||
// try umount lsposed dex2oat bins
|
||||
ksu_try_umount("/apex/com.android.art/bin/dex2oat64", false, MNT_DETACH);
|
||||
ksu_try_umount("/apex/com.android.art/bin/dex2oat32", false, MNT_DETACH);
|
||||
#endif // #ifdef CONFIG_KSU_SUSFS_TRY_UMOUNT
|
||||
try_umount("/apex/com.android.art/bin/dex2oat64", false, MNT_DETACH);
|
||||
try_umount("/apex/com.android.art/bin/dex2oat32", false, MNT_DETACH);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -76,16 +76,6 @@ void ksu_android_ns_fs_check()
|
||||
task_unlock(current);
|
||||
}
|
||||
|
||||
int ksu_access_ok(const void *addr, unsigned long size) {
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,0,0)
|
||||
/* For kernels before 5.0.0, pass the type argument to access_ok. */
|
||||
return access_ok(VERIFY_READ, addr, size);
|
||||
#else
|
||||
/* For kernels 5.0.0 and later, ignore the type argument. */
|
||||
return access_ok(addr, size);
|
||||
#endif
|
||||
}
|
||||
|
||||
struct file *ksu_filp_open_compat(const char *filename, int flags, umode_t mode)
|
||||
{
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || defined(CONFIG_IS_HW_HISI) || defined(CONFIG_KSU_ALLOWLIST_WORKAROUND)
|
||||
@@ -183,26 +173,3 @@ long ksu_strncpy_from_user_nofault(char *dst, const void __user *unsafe_addr,
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline int ksu_access_ok(const void *addr, unsigned long size)
|
||||
{
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,0,0)
|
||||
return access_ok(addr, size);
|
||||
#else
|
||||
return access_ok(VERIFY_READ, addr, size);
|
||||
#endif
|
||||
}
|
||||
|
||||
long ksu_strncpy_from_user_retry(char *dst, const void __user *unsafe_addr,
|
||||
long count)
|
||||
{
|
||||
long ret = ksu_strncpy_from_user_nofault(dst, unsafe_addr, count);
|
||||
if (likely(ret >= 0))
|
||||
return ret;
|
||||
|
||||
// we faulted! fallback to slow path
|
||||
if (unlikely(!ksu_access_ok(unsafe_addr, count)))
|
||||
return -EFAULT;
|
||||
|
||||
return strncpy_from_user(dst, unsafe_addr, count);
|
||||
}
|
||||
|
||||
@@ -23,16 +23,12 @@
|
||||
extern long ksu_strncpy_from_user_nofault(char *dst,
|
||||
const void __user *unsafe_addr,
|
||||
long count);
|
||||
extern long ksu_strncpy_from_user_retry(char *dst,
|
||||
const void __user *unsafe_addr,
|
||||
long count);
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || defined(CONFIG_IS_HW_HISI) || defined(CONFIG_KSU_ALLOWLIST_WORKAROUND)
|
||||
extern struct key *init_session_keyring;
|
||||
#endif
|
||||
|
||||
extern void ksu_android_ns_fs_check();
|
||||
extern int ksu_access_ok(const void *addr, unsigned long size);
|
||||
extern struct file *ksu_filp_open_compat(const char *filename, int flags,
|
||||
umode_t mode);
|
||||
extern ssize_t ksu_kernel_read_compat(struct file *p, void *buf, size_t count,
|
||||
|
||||
@@ -11,10 +11,6 @@
|
||||
#include "ksu.h"
|
||||
#include "throne_tracker.h"
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS
|
||||
#include <linux/susfs.h>
|
||||
#endif
|
||||
|
||||
static struct workqueue_struct *ksu_workqueue;
|
||||
|
||||
bool ksu_queue_work(struct work_struct *work)
|
||||
@@ -41,7 +37,7 @@ extern void ksu_sucompat_exit();
|
||||
extern void ksu_ksud_init();
|
||||
extern void ksu_ksud_exit();
|
||||
|
||||
int __init ksu_kernelsu_init(void)
|
||||
int __init kernelsu_init(void)
|
||||
{
|
||||
#ifdef CONFIG_KSU_DEBUG
|
||||
pr_alert("*************************************************************");
|
||||
@@ -53,10 +49,6 @@ int __init ksu_kernelsu_init(void)
|
||||
pr_alert("*************************************************************");
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS
|
||||
susfs_init();
|
||||
#endif
|
||||
|
||||
ksu_core_init();
|
||||
|
||||
ksu_workqueue = alloc_ordered_workqueue("kernelsu_work_queue", 0);
|
||||
@@ -80,7 +72,7 @@ int __init ksu_kernelsu_init(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ksu_kernelsu_exit(void)
|
||||
void kernelsu_exit(void)
|
||||
{
|
||||
ksu_allowlist_exit();
|
||||
|
||||
@@ -96,8 +88,8 @@ void ksu_kernelsu_exit(void)
|
||||
ksu_core_exit();
|
||||
}
|
||||
|
||||
module_init(ksu_kernelsu_init);
|
||||
module_exit(ksu_kernelsu_exit);
|
||||
module_init(kernelsu_init);
|
||||
module_exit(kernelsu_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("weishu");
|
||||
|
||||
@@ -58,15 +58,12 @@ static void stop_input_hook();
|
||||
static struct work_struct stop_vfs_read_work;
|
||||
static struct work_struct stop_execve_hook_work;
|
||||
static struct work_struct stop_input_hook_work;
|
||||
#else
|
||||
#endif
|
||||
|
||||
bool ksu_vfs_read_hook __read_mostly = true;
|
||||
bool ksu_execveat_hook __read_mostly = true;
|
||||
bool ksu_input_hook __read_mostly = true;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_SU
|
||||
bool susfs_is_sus_su_ready = false;
|
||||
#endif // #ifdef CONFIG_KSU_SUSFS_SUS_SU
|
||||
|
||||
u32 ksu_devpts_sid;
|
||||
|
||||
@@ -74,15 +71,15 @@ u32 ksu_devpts_sid;
|
||||
bool ksu_is_compat __read_mostly = false;
|
||||
#endif
|
||||
|
||||
void ksu_on_post_fs_data(void)
|
||||
void on_post_fs_data(void)
|
||||
{
|
||||
static bool done = false;
|
||||
if (done) {
|
||||
pr_info("ksu_on_post_fs_data already done\n");
|
||||
pr_info("on_post_fs_data already done\n");
|
||||
return;
|
||||
}
|
||||
done = true;
|
||||
pr_info("ksu_on_post_fs_data!\n");
|
||||
pr_info("on_post_fs_data!\n");
|
||||
ksu_load_allow_list();
|
||||
// sanity check, this may influence the performance
|
||||
stop_input_hook();
|
||||
@@ -200,13 +197,14 @@ int ksu_handle_execveat_ksud(int *fd, struct filename **filename_ptr,
|
||||
const char __user *p = get_user_arg_ptr(*argv, 1);
|
||||
if (p && !IS_ERR(p)) {
|
||||
char first_arg[16];
|
||||
ksu_strncpy_from_user_retry(
|
||||
ksu_strncpy_from_user_nofault(
|
||||
first_arg, p, sizeof(first_arg));
|
||||
pr_info("/system/bin/init first arg: %s\n",
|
||||
first_arg);
|
||||
if (!strcmp(first_arg, "second_stage")) {
|
||||
if (!strcmp(first_arg, "second_stage") ||
|
||||
(argc == 2 && !strcmp(first_arg, ""))) {
|
||||
pr_info("/system/bin/init second_stage executed\n");
|
||||
ksu_apply_kernelsu_rules();
|
||||
apply_kernelsu_rules();
|
||||
init_second_stage_executed = true;
|
||||
ksu_android_ns_fs_check();
|
||||
}
|
||||
@@ -225,12 +223,12 @@ int ksu_handle_execveat_ksud(int *fd, struct filename **filename_ptr,
|
||||
const char __user *p = get_user_arg_ptr(*argv, 1);
|
||||
if (p && !IS_ERR(p)) {
|
||||
char first_arg[16];
|
||||
ksu_strncpy_from_user_retry(
|
||||
ksu_strncpy_from_user_nofault(
|
||||
first_arg, p, sizeof(first_arg));
|
||||
pr_info("/init first arg: %s\n", first_arg);
|
||||
if (!strcmp(first_arg, "--second-stage")) {
|
||||
pr_info("/init second_stage executed\n");
|
||||
ksu_apply_kernelsu_rules();
|
||||
apply_kernelsu_rules();
|
||||
init_second_stage_executed = true;
|
||||
ksu_android_ns_fs_check();
|
||||
}
|
||||
@@ -250,7 +248,7 @@ int ksu_handle_execveat_ksud(int *fd, struct filename **filename_ptr,
|
||||
}
|
||||
char env[256];
|
||||
// Reading environment variable strings from user space
|
||||
if (ksu_strncpy_from_user_retry(
|
||||
if (ksu_strncpy_from_user_nofault(
|
||||
env, p, sizeof(env)) < 0)
|
||||
continue;
|
||||
// Parsing environment variable names and values
|
||||
@@ -267,7 +265,7 @@ int ksu_handle_execveat_ksud(int *fd, struct filename **filename_ptr,
|
||||
(!strcmp(env_value, "1") ||
|
||||
!strcmp(env_value, "true"))) {
|
||||
pr_info("/init second_stage executed\n");
|
||||
ksu_apply_kernelsu_rules();
|
||||
apply_kernelsu_rules();
|
||||
init_second_stage_executed =
|
||||
true;
|
||||
ksu_android_ns_fs_check();
|
||||
@@ -282,7 +280,7 @@ int ksu_handle_execveat_ksud(int *fd, struct filename **filename_ptr,
|
||||
first_app_process = false;
|
||||
pr_info("exec app_process, /data prepared, second_stage: %d\n",
|
||||
init_second_stage_executed);
|
||||
ksu_on_post_fs_data(); // we keep this for old ksud
|
||||
on_post_fs_data(); // we keep this for old ksud
|
||||
stop_execve_hook();
|
||||
}
|
||||
|
||||
@@ -491,12 +489,10 @@ __maybe_unused int ksu_handle_execve_ksud(const char __user *filename_user,
|
||||
struct filename filename_in, *filename_p;
|
||||
char path[32];
|
||||
|
||||
#ifndef CONFIG_KSU_KPROBES_HOOK
|
||||
// return early if disabled.
|
||||
if (!ksu_execveat_hook) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!filename_user)
|
||||
return 0;
|
||||
@@ -682,10 +678,6 @@ static void stop_execve_hook()
|
||||
ksu_execveat_hook = false;
|
||||
pr_info("stop execve_hook\n");
|
||||
#endif
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_SU
|
||||
susfs_is_sus_su_ready = true;
|
||||
pr_info("susfs: sus_su is ready\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
static void stop_input_hook()
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
#define KSUD_PATH "/data/adb/ksud"
|
||||
|
||||
void ksu_on_post_fs_data(void);
|
||||
void on_post_fs_data(void);
|
||||
|
||||
bool ksu_is_safe_mode(void);
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ static inline bool ksu_is_manager_uid_valid()
|
||||
return ksu_manager_uid != KSU_INVALID_UID;
|
||||
}
|
||||
|
||||
static inline bool ksu_is_manager()
|
||||
static inline bool is_manager()
|
||||
{
|
||||
return unlikely(ksu_manager_uid == current_uid().val);
|
||||
}
|
||||
|
||||
@@ -38,11 +38,11 @@ static struct policydb *get_policydb(void)
|
||||
|
||||
static DEFINE_MUTEX(ksu_rules);
|
||||
|
||||
void ksu_apply_kernelsu_rules()
|
||||
void apply_kernelsu_rules()
|
||||
{
|
||||
struct policydb *db;
|
||||
|
||||
if (!ksu_getenforce()) {
|
||||
if (!getenforce()) {
|
||||
pr_info("SELinux permissive or disabled, apply rules!\n");
|
||||
}
|
||||
|
||||
@@ -139,14 +139,6 @@ void ksu_apply_kernelsu_rules()
|
||||
ksu_allow(db, "system_server", KERNEL_SU_DOMAIN, "process", "getpgid");
|
||||
ksu_allow(db, "system_server", KERNEL_SU_DOMAIN, "process", "sigkill");
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS
|
||||
// Allow umount in zygote process without installing zygisk
|
||||
ksu_allow(db, "zygote", "labeledfs", "filesystem", "unmount");
|
||||
susfs_set_init_sid();
|
||||
susfs_set_ksu_sid();
|
||||
susfs_set_zygote_sid();
|
||||
#endif
|
||||
|
||||
mutex_unlock(&ksu_rules);
|
||||
}
|
||||
|
||||
@@ -236,13 +228,13 @@ static void reset_avc_cache()
|
||||
selinux_xfrm_notify_policyload();
|
||||
}
|
||||
|
||||
int ksu_handle_sepolicy(unsigned long arg3, void __user *arg4)
|
||||
int handle_sepolicy(unsigned long arg3, void __user *arg4)
|
||||
{
|
||||
if (!arg4) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!ksu_getenforce()) {
|
||||
if (!getenforce()) {
|
||||
pr_info("SELinux permissive or disabled when handle policy!\n");
|
||||
}
|
||||
|
||||
|
||||
@@ -8,14 +8,6 @@
|
||||
|
||||
#define KERNEL_SU_DOMAIN "u:r:su:s0"
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS
|
||||
#define KERNEL_INIT_DOMAIN "u:r:init:s0"
|
||||
#define KERNEL_ZYGOTE_DOMAIN "u:r:zygote:s0"
|
||||
u32 susfs_ksu_sid = 0;
|
||||
u32 susfs_init_sid = 0;
|
||||
u32 susfs_zygote_sid = 0;
|
||||
#endif
|
||||
|
||||
static int transive_to_domain(const char *domain)
|
||||
{
|
||||
struct cred *cred;
|
||||
@@ -45,7 +37,7 @@ static int transive_to_domain(const char *domain)
|
||||
return error;
|
||||
}
|
||||
|
||||
void ksu_setup_selinux(const char *domain)
|
||||
void setup_selinux(const char *domain)
|
||||
{
|
||||
if (transive_to_domain(domain)) {
|
||||
pr_err("transive domain failed.\n");
|
||||
@@ -60,7 +52,7 @@ if (!is_domain_permissive) {
|
||||
}*/
|
||||
}
|
||||
|
||||
void ksu_setenforce(bool enforce)
|
||||
void setenforce(bool enforce)
|
||||
{
|
||||
#ifdef CONFIG_SECURITY_SELINUX_DEVELOP
|
||||
#ifdef KSU_COMPAT_USE_SELINUX_STATE
|
||||
@@ -71,7 +63,7 @@ void ksu_setenforce(bool enforce)
|
||||
#endif
|
||||
}
|
||||
|
||||
bool ksu_getenforce()
|
||||
bool getenforce()
|
||||
{
|
||||
#ifdef CONFIG_SECURITY_SELINUX_DISABLE
|
||||
#ifdef KSU_COMPAT_USE_SELINUX_STATE
|
||||
@@ -107,7 +99,7 @@ static inline u32 current_sid(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
bool ksu_is_ksu_domain()
|
||||
bool is_ksu_domain()
|
||||
{
|
||||
char *domain;
|
||||
u32 seclen;
|
||||
@@ -121,7 +113,7 @@ bool ksu_is_ksu_domain()
|
||||
return result;
|
||||
}
|
||||
|
||||
bool ksu_is_zygote(void *sec)
|
||||
bool is_zygote(void *sec)
|
||||
{
|
||||
struct task_security_struct *tsec = (struct task_security_struct *)sec;
|
||||
if (!tsec) {
|
||||
@@ -139,83 +131,6 @@ bool ksu_is_zygote(void *sec)
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS
|
||||
static inline void susfs_set_sid(const char *secctx_name, u32 *out_sid)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (!secctx_name || !out_sid) {
|
||||
pr_err("secctx_name || out_sid is NULL\n");
|
||||
return;
|
||||
}
|
||||
|
||||
err = security_secctx_to_secid(secctx_name, strlen(secctx_name),
|
||||
out_sid);
|
||||
if (err) {
|
||||
pr_err("failed setting sid for '%s', err: %d\n", secctx_name, err);
|
||||
return;
|
||||
}
|
||||
pr_info("sid '%u' is set for secctx_name '%s'\n", *out_sid, secctx_name);
|
||||
}
|
||||
|
||||
bool susfs_is_sid_equal(void *sec, u32 sid2) {
|
||||
struct task_security_struct *tsec = (struct task_security_struct *)sec;
|
||||
if (!tsec) {
|
||||
return false;
|
||||
}
|
||||
return tsec->sid == sid2;
|
||||
}
|
||||
|
||||
u32 susfs_get_sid_from_name(const char *secctx_name)
|
||||
{
|
||||
u32 out_sid = 0;
|
||||
int err;
|
||||
|
||||
if (!secctx_name) {
|
||||
pr_err("secctx_name is NULL\n");
|
||||
return 0;
|
||||
}
|
||||
err = security_secctx_to_secid(secctx_name, strlen(secctx_name),
|
||||
&out_sid);
|
||||
if (err) {
|
||||
pr_err("failed getting sid from secctx_name: %s, err: %d\n", secctx_name, err);
|
||||
return 0;
|
||||
}
|
||||
return out_sid;
|
||||
}
|
||||
|
||||
u32 susfs_get_current_sid(void) {
|
||||
return current_sid();
|
||||
}
|
||||
|
||||
void susfs_set_zygote_sid(void)
|
||||
{
|
||||
susfs_set_sid(KERNEL_ZYGOTE_DOMAIN, &susfs_zygote_sid);
|
||||
}
|
||||
|
||||
bool susfs_is_current_zygote_domain(void) {
|
||||
return unlikely(current_sid() == susfs_zygote_sid);
|
||||
}
|
||||
|
||||
void susfs_set_ksu_sid(void)
|
||||
{
|
||||
susfs_set_sid(KERNEL_SU_DOMAIN, &susfs_ksu_sid);
|
||||
}
|
||||
|
||||
bool susfs_is_current_ksu_domain(void) {
|
||||
return unlikely(current_sid() == susfs_ksu_sid);
|
||||
}
|
||||
|
||||
void susfs_set_init_sid(void)
|
||||
{
|
||||
susfs_set_sid(KERNEL_INIT_DOMAIN, &susfs_init_sid);
|
||||
}
|
||||
|
||||
bool susfs_is_current_init_domain(void) {
|
||||
return unlikely(current_sid() == susfs_init_sid);
|
||||
}
|
||||
#endif
|
||||
|
||||
#define DEVPTS_DOMAIN "u:object_r:ksu_file:s0"
|
||||
|
||||
u32 ksu_get_devpts_sid()
|
||||
|
||||
@@ -8,29 +8,17 @@
|
||||
#define KSU_COMPAT_USE_SELINUX_STATE
|
||||
#endif
|
||||
|
||||
void ksu_setup_selinux(const char *);
|
||||
void setup_selinux(const char *);
|
||||
|
||||
void ksu_setenforce(bool);
|
||||
void setenforce(bool);
|
||||
|
||||
bool ksu_getenforce();
|
||||
bool getenforce();
|
||||
|
||||
bool ksu_is_ksu_domain();
|
||||
bool is_ksu_domain();
|
||||
|
||||
bool ksu_is_zygote(void *cred);
|
||||
bool is_zygote(void *cred);
|
||||
|
||||
void ksu_apply_kernelsu_rules();
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT
|
||||
bool susfs_is_sid_equal(void *sec, u32 sid2);
|
||||
u32 susfs_get_sid_from_name(const char *secctx_name);
|
||||
u32 susfs_get_current_sid(void);
|
||||
void susfs_set_zygote_sid(void);
|
||||
bool susfs_is_current_zygote_domain(void);
|
||||
void susfs_set_ksu_sid(void);
|
||||
bool susfs_is_current_ksu_domain(void);
|
||||
void susfs_set_init_sid(void);
|
||||
bool susfs_is_current_init_domain(void);
|
||||
#endif
|
||||
void apply_kernelsu_rules();
|
||||
|
||||
u32 ksu_get_devpts_sid();
|
||||
|
||||
|
||||
@@ -13,9 +13,6 @@
|
||||
#else
|
||||
#include <linux/sched.h>
|
||||
#endif
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_SU
|
||||
#include <linux/susfs_def.h>
|
||||
#endif
|
||||
|
||||
#include "objsec.h"
|
||||
#include "allowlist.h"
|
||||
@@ -31,13 +28,9 @@
|
||||
static bool ksu_sucompat_non_kp __read_mostly = true;
|
||||
#endif
|
||||
|
||||
extern void ksu_escape_to_root();
|
||||
extern void escape_to_root();
|
||||
|
||||
static const char sh_path[] = "/system/bin/sh";
|
||||
static const char ksud_path[] = KSUD_PATH;
|
||||
static const char su[] = SU_PATH;
|
||||
|
||||
static inline void __user *userspace_stack_buffer(const void *d, size_t len)
|
||||
static void __user *userspace_stack_buffer(const void *d, size_t len)
|
||||
{
|
||||
/* To avoid having to mmap a page in userspace, just write below the stack
|
||||
* pointer. */
|
||||
@@ -46,19 +39,24 @@ static inline void __user *userspace_stack_buffer(const void *d, size_t len)
|
||||
return copy_to_user(p, d, len) ? NULL : p;
|
||||
}
|
||||
|
||||
static inline char __user *sh_user_path(void)
|
||||
static char __user *sh_user_path(void)
|
||||
{
|
||||
static const char sh_path[] = "/system/bin/sh";
|
||||
|
||||
return userspace_stack_buffer(sh_path, sizeof(sh_path));
|
||||
}
|
||||
|
||||
static inline char __user *ksud_user_path(void)
|
||||
static char __user *ksud_user_path(void)
|
||||
{
|
||||
static const char ksud_path[] = KSUD_PATH;
|
||||
|
||||
return userspace_stack_buffer(ksud_path, sizeof(ksud_path));
|
||||
}
|
||||
|
||||
int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode,
|
||||
int *__unused_flags)
|
||||
{
|
||||
const char su[] = SU_PATH;
|
||||
|
||||
#ifndef CONFIG_KSU_KPROBES_HOOK
|
||||
if (!ksu_sucompat_non_kp) {
|
||||
@@ -66,19 +64,12 @@ int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode,
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_KSU_SUSFS_SUS_SU
|
||||
if (!ksu_is_allow_uid(current_uid().val)) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_SU
|
||||
char path[sizeof(su) + 1] = {0};
|
||||
#else
|
||||
char path[sizeof(su) + 1];
|
||||
memset(path, 0, sizeof(path));
|
||||
#endif
|
||||
|
||||
ksu_strncpy_from_user_nofault(path, *filename_user, sizeof(path));
|
||||
|
||||
if (unlikely(!memcmp(path, su, sizeof(su)))) {
|
||||
@@ -89,27 +80,10 @@ int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0) && defined(CONFIG_KSU_SUSFS_SUS_SU)
|
||||
struct filename* susfs_ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags) {
|
||||
struct filename *name = getname_flags(*filename_user, getname_statx_lookup_flags(*flags), NULL);
|
||||
|
||||
if (unlikely(IS_ERR(name) || name->name == NULL)) {
|
||||
return name;
|
||||
}
|
||||
|
||||
if (likely(memcmp(name->name, su, sizeof(su)))) {
|
||||
return name;
|
||||
}
|
||||
|
||||
const char sh[] = SH_PATH;
|
||||
pr_info("vfs_fstatat su->sh!\n");
|
||||
memcpy((void *)name->name, sh, sizeof(sh));
|
||||
return name;
|
||||
}
|
||||
#endif
|
||||
|
||||
int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags)
|
||||
{
|
||||
// const char sh[] = SH_PATH;
|
||||
const char su[] = SU_PATH;
|
||||
|
||||
#ifndef CONFIG_KSU_KPROBES_HOOK
|
||||
if (!ksu_sucompat_non_kp){
|
||||
@@ -117,22 +91,16 @@ int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_KSU_SUSFS_SUS_SU
|
||||
if (!ksu_is_allow_uid(current_uid().val)) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (unlikely(!filename_user)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_SU
|
||||
char path[sizeof(su) + 1] = {0};
|
||||
#else
|
||||
char path[sizeof(su) + 1];
|
||||
memset(path, 0, sizeof(path));
|
||||
#endif
|
||||
char path[sizeof(su) + 1];
|
||||
memset(path, 0, sizeof(path));
|
||||
// Remove this later!! we use syscall hook, so this will never happen!!!!!
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0) && 0
|
||||
// it becomes a `struct filename *` after 5.18
|
||||
@@ -164,6 +132,8 @@ int ksu_handle_execveat_sucompat(int *fd, struct filename **filename_ptr,
|
||||
int *__never_use_flags)
|
||||
{
|
||||
struct filename *filename;
|
||||
const char sh[] = KSUD_PATH;
|
||||
const char su[] = SU_PATH;
|
||||
|
||||
#ifndef CONFIG_KSU_KPROBES_HOOK
|
||||
if (!ksu_sucompat_non_kp) {
|
||||
@@ -182,15 +152,13 @@ int ksu_handle_execveat_sucompat(int *fd, struct filename **filename_ptr,
|
||||
if (likely(memcmp(filename->name, su, sizeof(su))))
|
||||
return 0;
|
||||
|
||||
#ifndef CONFIG_KSU_SUSFS_SUS_SU
|
||||
if (!ksu_is_allow_uid(current_uid().val))
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
pr_info("do_execveat_common su found\n");
|
||||
memcpy((void *)filename->name, ksud_path, sizeof(ksud_path));
|
||||
memcpy((void *)filename->name, sh, sizeof(sh));
|
||||
|
||||
ksu_escape_to_root();
|
||||
escape_to_root();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -199,12 +167,8 @@ int ksu_handle_execve_sucompat(int *fd, const char __user **filename_user,
|
||||
void *__never_use_argv, void *__never_use_envp,
|
||||
int *__never_use_flags)
|
||||
{
|
||||
//const char su[] = SU_PATH;
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_SU
|
||||
char path[sizeof(su) + 1] = {0};
|
||||
#else
|
||||
char path[sizeof(su) + 1];
|
||||
#endif
|
||||
const char su[] = SU_PATH;
|
||||
char path[sizeof(su) + 1];
|
||||
|
||||
#ifndef CONFIG_KSU_KPROBES_HOOK
|
||||
if (!ksu_sucompat_non_kp) {
|
||||
@@ -215,10 +179,23 @@ int ksu_handle_execve_sucompat(int *fd, const char __user **filename_user,
|
||||
if (unlikely(!filename_user))
|
||||
return 0;
|
||||
|
||||
#ifndef CONFIG_KSU_SUSFS_SUS_SU
|
||||
memset(path, 0, sizeof(path));
|
||||
// nofault variant fails probably due to pagefault_disable
|
||||
// some cpus dont really have that good speculative execution
|
||||
// substitute set_fs, check if pointer is valid
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,0,0)
|
||||
if (!access_ok(VERIFY_READ, *filename_user, sizeof(path)))
|
||||
return 0;
|
||||
#else
|
||||
if (!access_ok(*filename_user, sizeof(path)))
|
||||
return 0;
|
||||
#endif
|
||||
ksu_strncpy_from_user_retry(path, *filename_user, sizeof(path));
|
||||
// success = returns number of bytes and should be less than path
|
||||
long len = strncpy_from_user(path, *filename_user, sizeof(path));
|
||||
if (len <= 0 || len > sizeof(path))
|
||||
return 0;
|
||||
|
||||
// strncpy_from_user_nofault does this too
|
||||
path[sizeof(path) - 1] = '\0';
|
||||
|
||||
if (likely(memcmp(path, su, sizeof(su))))
|
||||
return 0;
|
||||
@@ -229,7 +206,7 @@ int ksu_handle_execve_sucompat(int *fd, const char __user **filename_user,
|
||||
pr_info("sys_execve su found\n");
|
||||
*filename_user = ksud_user_path();
|
||||
|
||||
ksu_escape_to_root();
|
||||
escape_to_root();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -375,41 +352,3 @@ void ksu_sucompat_exit()
|
||||
pr_info("ksu_sucompat_exit: hooks disabled: execve/execveat_su, faccessat, stat, devpts\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_SU
|
||||
extern bool ksu_su_compat_enabled;
|
||||
bool ksu_devpts_hook = false;
|
||||
bool susfs_is_sus_su_hooks_enabled __read_mostly = false;
|
||||
int susfs_sus_su_working_mode = 0;
|
||||
|
||||
static bool ksu_is_su_kps_enabled(void) {
|
||||
for (int i = 0; i < ARRAY_SIZE(su_kps); i++) {
|
||||
if (su_kps[i]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ksu_susfs_disable_sus_su(void) {
|
||||
susfs_is_sus_su_hooks_enabled = false;
|
||||
ksu_devpts_hook = false;
|
||||
susfs_sus_su_working_mode = SUS_SU_DISABLED;
|
||||
// Re-enable the su_kps for user, users need to toggle off the kprobe hooks again in ksu manager if they want it disabled.
|
||||
if (!ksu_is_su_kps_enabled()) {
|
||||
ksu_sucompat_init();
|
||||
ksu_su_compat_enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
void ksu_susfs_enable_sus_su(void) {
|
||||
if (ksu_is_su_kps_enabled()) {
|
||||
ksu_sucompat_exit();
|
||||
ksu_su_compat_enabled = false;
|
||||
}
|
||||
susfs_is_sus_su_hooks_enabled = true;
|
||||
ksu_devpts_hook = true;
|
||||
susfs_sus_su_working_mode = SUS_SU_WITH_HOOKS;
|
||||
}
|
||||
#endif // #ifdef CONFIG_KSU_SUSFS_SUS_SU
|
||||
|
||||
|
||||
@@ -192,7 +192,7 @@ FILLDIR_RETURN_TYPE my_actor(struct dir_context *ctx, const char *name,
|
||||
}
|
||||
}
|
||||
|
||||
bool is_manager = ksu_is_manager_apk(dirpath);
|
||||
bool is_manager = is_manager_apk(dirpath);
|
||||
pr_info("Found new base.apk at path: %s, is_manager: %d\n",
|
||||
dirpath, is_manager);
|
||||
if (is_manager) {
|
||||
@@ -351,7 +351,7 @@ static bool is_uid_exist(uid_t uid, char *package, void *data)
|
||||
return exist;
|
||||
}
|
||||
|
||||
void ksu_track_throne()
|
||||
void track_throne()
|
||||
{
|
||||
struct file *fp;
|
||||
int tries = 0;
|
||||
|
||||
@@ -5,7 +5,7 @@ void ksu_throne_tracker_init();
|
||||
|
||||
void ksu_throne_tracker_exit();
|
||||
|
||||
void ksu_track_throne();
|
||||
void track_throne();
|
||||
|
||||
bool is_lock_held(const char *path);
|
||||
|
||||
|
||||
3
KernelSU-Next/manager/.gitignore
vendored
3
KernelSU-Next/manager/.gitignore
vendored
@@ -7,4 +7,5 @@ build
|
||||
captures
|
||||
.cxx
|
||||
local.properties
|
||||
key.jks
|
||||
key.jks
|
||||
setup.sh
|
||||
@@ -16,12 +16,11 @@ object Natives {
|
||||
// 10946: add capabilities
|
||||
// 10977: change groups_count and groups to avoid overflow write
|
||||
// 11071: Fix the issue of failing to set a custom SELinux type.
|
||||
// 12797: zygisk query and get manager uid.
|
||||
const val MINIMAL_SUPPORTED_KERNEL = 12797
|
||||
const val MINIMAL_SUPPORTED_KERNEL = 11071
|
||||
|
||||
// 11640: Support query working mode, LKM or GKI
|
||||
// when MINIMAL_SUPPORTED_KERNEL > 11640, we can remove this constant.
|
||||
const val MINIMAL_SUPPORTED_KERNEL_LKM = 12797
|
||||
const val MINIMAL_SUPPORTED_KERNEL_LKM = 11648
|
||||
|
||||
// 12404: Support disable sucompat mode
|
||||
const val MINIMAL_SUPPORTED_SU_COMPAT = 12404
|
||||
@@ -120,9 +119,6 @@ object Natives {
|
||||
return version < MINIMAL_SUPPORTED_KERNEL
|
||||
}
|
||||
|
||||
val KSU_WORK_DIR = "/data/adb/ksu/"
|
||||
val GLOBAL_NAMESPACE_FILE = KSU_WORK_DIR + ".global_mnt"
|
||||
|
||||
@Immutable
|
||||
@Parcelize
|
||||
@Keep
|
||||
|
||||
@@ -650,7 +650,7 @@ private fun InfoCard(autoExpand: Boolean = false) {
|
||||
|
||||
val suSFS = getSuSFS()
|
||||
if (suSFS == "Supported") {
|
||||
val isSUS_SU = hasSuSFs_SUS_SU() == "Supported"
|
||||
val isSUS_SU = getSuSFSFeatures() == "CONFIG_KSU_SUSFS_SUS_SU"
|
||||
val susSUMode = if (isSUS_SU) {
|
||||
val mode = susfsSUS_SU_Mode()
|
||||
val modeString =
|
||||
|
||||
@@ -81,6 +81,35 @@ import com.rifsxd.ksunext.ui.util.rootAvailable
|
||||
@Destination<RootGraph>
|
||||
@Composable
|
||||
fun InstallScreen(navigator: DestinationsNavigator) {
|
||||
var showLkmWarning by rememberSaveable { mutableStateOf(true) }
|
||||
|
||||
if (showLkmWarning) {
|
||||
AlertDialog(
|
||||
onDismissRequest = {
|
||||
showLkmWarning = false
|
||||
navigator.popBackStack()
|
||||
},
|
||||
title = { Text(
|
||||
text = stringResource(R.string.warning),
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
fontWeight = FontWeight.SemiBold
|
||||
) },
|
||||
text = { Text(stringResource(R.string.lkm_warning_message)) },
|
||||
confirmButton = {
|
||||
TextButton(onClick = { showLkmWarning = false }) {
|
||||
Text(stringResource(R.string.proceed))
|
||||
}
|
||||
},
|
||||
dismissButton = {
|
||||
TextButton(onClick = {
|
||||
showLkmWarning = false
|
||||
navigator.popBackStack()
|
||||
}) {
|
||||
Text(stringResource(R.string.cancel))
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
var installMethod by remember {
|
||||
mutableStateOf<InstallMethod?>(null)
|
||||
|
||||
@@ -88,8 +88,6 @@ import com.rifsxd.ksunext.ui.component.rememberLoadingDialog
|
||||
import com.rifsxd.ksunext.ui.util.LocalSnackbarHost
|
||||
import com.rifsxd.ksunext.ui.util.getBugreportFile
|
||||
import com.rifsxd.ksunext.ui.util.*
|
||||
import com.rifsxd.ksunext.ui.util.isGlobalNamespaceEnabled
|
||||
import com.rifsxd.ksunext.ui.util.setGlobalNamespaceEnabled
|
||||
import java.time.LocalDateTime
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
@@ -103,8 +101,6 @@ import java.time.format.DateTimeFormatter
|
||||
fun SettingScreen(navigator: DestinationsNavigator) {
|
||||
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
|
||||
val snackBarHost = LocalSnackbarHost.current
|
||||
var isGlobalNamespaceEnabled by rememberSaveable { mutableStateOf(false) }
|
||||
isGlobalNamespaceEnabled = isGlobalNamespaceEnabled()
|
||||
|
||||
val isManager = Natives.becomeManager(ksuApp.packageName)
|
||||
val ksuVersion = if (isManager) Natives.version else null
|
||||
@@ -200,31 +196,14 @@ fun SettingScreen(navigator: DestinationsNavigator) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SwitchItem(
|
||||
icon = Icons.Filled.Engineering,
|
||||
title = stringResource(id = R.string.settings_global_namespace_mode),
|
||||
summary = stringResource(id = R.string.settings_global_namespace_mode_summary),
|
||||
checked = isGlobalNamespaceEnabled,
|
||||
onCheckedChange = {
|
||||
setGlobalNamespaceEnabled(
|
||||
if (isGlobalNamespaceEnabled) {
|
||||
"0"
|
||||
} else {
|
||||
"1"
|
||||
}
|
||||
)
|
||||
isGlobalNamespaceEnabled = it
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
val prefs = context.getSharedPreferences("settings", Context.MODE_PRIVATE)
|
||||
|
||||
val suSFS = getSuSFS()
|
||||
val isSUS_SU = hasSuSFs_SUS_SU() == "Supported"
|
||||
val isSUS_SU = getSuSFSFeatures()
|
||||
if (suSFS == "Supported") {
|
||||
if (isSUS_SU) {
|
||||
if (isSUS_SU == "CONFIG_KSU_SUSFS_SUS_SU") {
|
||||
var isEnabled by rememberSaveable {
|
||||
mutableStateOf(susfsSUS_SU_Mode() == "2")
|
||||
}
|
||||
|
||||
@@ -103,10 +103,7 @@ fun Uri.getFileName(context: Context): String? {
|
||||
|
||||
fun createRootShell(globalMnt: Boolean = false): Shell {
|
||||
Shell.enableVerboseLogging = BuildConfig.DEBUG
|
||||
val builder = Shell.Builder.create().apply {
|
||||
setFlags(Shell.FLAG_MOUNT_MASTER)
|
||||
}
|
||||
|
||||
val builder = Shell.Builder.create()
|
||||
return try {
|
||||
if (globalMnt) {
|
||||
builder.build(ksuDaemonMagicPath(), "debug", "su", "-g")
|
||||
@@ -406,22 +403,6 @@ fun hasMagisk(): Boolean {
|
||||
return result.isSuccess
|
||||
}
|
||||
|
||||
fun isGlobalNamespaceEnabled(): Boolean {
|
||||
val shell = getRootShell()
|
||||
val result =
|
||||
ShellUtils.fastCmd(shell, "nsenter --mount=/proc/1/ns/mnt cat ${Natives.GLOBAL_NAMESPACE_FILE}")
|
||||
Log.i(TAG, "is global namespace enabled: $result")
|
||||
return result == "1"
|
||||
}
|
||||
|
||||
fun setGlobalNamespaceEnabled(value: String) {
|
||||
getRootShell().newJob()
|
||||
.add("nsenter --mount=/proc/1/ns/mnt echo $value > ${Natives.GLOBAL_NAMESPACE_FILE}")
|
||||
.submit { result ->
|
||||
Log.i(TAG, "setGlobalNamespaceEnabled result: ${result.isSuccess} [${result.out}]")
|
||||
}
|
||||
}
|
||||
|
||||
fun isSepolicyValid(rules: String?): Boolean {
|
||||
if (rules == null) {
|
||||
return true
|
||||
@@ -610,19 +591,12 @@ fun getSuSFSVariant(): String {
|
||||
val result = ShellUtils.fastCmd(shell, "${getSuSFSDaemonPath()} variant")
|
||||
return result
|
||||
}
|
||||
|
||||
fun getSuSFSFeatures(): String {
|
||||
val shell = getRootShell()
|
||||
val result = ShellUtils.fastCmd(shell, "${getSuSFSDaemonPath()} features")
|
||||
return result
|
||||
}
|
||||
|
||||
fun hasSuSFs_SUS_SU(): String {
|
||||
val shell = getRootShell()
|
||||
val result = ShellUtils.fastCmd(shell, "${getSuSFSDaemonPath()} sus_su support")
|
||||
return result
|
||||
}
|
||||
|
||||
fun susfsSUS_SU_0(): String {
|
||||
val shell = getRootShell()
|
||||
val result = ShellUtils.fastCmd(shell, "${getSuSFSDaemonPath()} sus_su 0")
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
package com.rifsxd.ksunext.ui.webui;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class AppIconUtil {
|
||||
private static final Map<String, Bitmap> iconCache = new HashMap<>();
|
||||
|
||||
public static Bitmap loadAppIconSync(Context context, String packageName, int sizePx) {
|
||||
Bitmap cached = iconCache.get(packageName);
|
||||
if (cached != null) return cached;
|
||||
|
||||
try {
|
||||
PackageManager pm = context.getPackageManager();
|
||||
ApplicationInfo appInfo = pm.getApplicationInfo(packageName, 0);
|
||||
Drawable drawable = pm.getApplicationIcon(appInfo);
|
||||
Bitmap raw = drawableToBitmap(drawable, sizePx);
|
||||
Bitmap icon = Bitmap.createScaledBitmap(raw, sizePx, sizePx, true);
|
||||
iconCache.put(packageName, icon);
|
||||
return icon;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static Bitmap drawableToBitmap(Drawable drawable, int size) {
|
||||
if (drawable instanceof BitmapDrawable) return ((BitmapDrawable) drawable).getBitmap();
|
||||
|
||||
int width = drawable.getIntrinsicWidth() > 0 ? drawable.getIntrinsicWidth() : size;
|
||||
int height = drawable.getIntrinsicHeight() > 0 ? drawable.getIntrinsicHeight() : size;
|
||||
|
||||
Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
||||
Canvas canvas = new Canvas(bmp);
|
||||
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
|
||||
drawable.draw(canvas);
|
||||
return bmp;
|
||||
}
|
||||
}
|
||||
@@ -96,23 +96,7 @@ class WebUIActivity : ComponentActivity() {
|
||||
view: WebView,
|
||||
request: WebResourceRequest
|
||||
): WebResourceResponse? {
|
||||
val url = request.url
|
||||
|
||||
//POC: Handle ksu://icon/[packageName] to serve app icon via WebView
|
||||
if (url.scheme.equals("ksu", ignoreCase = true) && url.host.equals("icon", ignoreCase = true)) {
|
||||
val packageName = url.path?.substring(1)
|
||||
if (!packageName.isNullOrEmpty()) {
|
||||
val icon = AppIconUtil.loadAppIconSync(this@WebUIActivity, packageName, 512)
|
||||
if (icon != null) {
|
||||
val stream = java.io.ByteArrayOutputStream()
|
||||
icon.compress(android.graphics.Bitmap.CompressFormat.PNG, 100, stream)
|
||||
val inputStream = java.io.ByteArrayInputStream(stream.toByteArray())
|
||||
return WebResourceResponse("image/png", null, inputStream)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return webViewAssetLoader.shouldInterceptRequest(url)
|
||||
return webViewAssetLoader.shouldInterceptRequest(request.url)
|
||||
}
|
||||
override fun onPageFinished(view: WebView?, url: String?) {
|
||||
super.onPageFinished(view, url)
|
||||
@@ -135,4 +119,4 @@ class WebUIActivity : ComponentActivity() {
|
||||
super.onDestroy()
|
||||
runCatching { rootShell?.close() }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -233,6 +233,4 @@
|
||||
<string name="module_sort_enabled_first">Sort (Enabled first)</string>
|
||||
<string name="module_sort_action_first">Sort (Action first)</string>
|
||||
<string name="module_sort_webui_first">Sort (WebUI first)</string>
|
||||
<string name="settings_global_namespace_mode">Global Namespace Mode</string>
|
||||
<string name="settings_global_namespace_mode_summary">All root sessions use the global mount namespace</string>
|
||||
</resources>
|
||||
|
||||
@@ -231,6 +231,4 @@
|
||||
<string name="module_sort_enabled_first">Сортиране (първо активирани)</string>
|
||||
<string name="module_sort_action_first">Сортиране (първо действие)</string>
|
||||
<string name="module_sort_webui_first">Сортиране (първо WebUI)</string>
|
||||
<string name="settings_global_namespace_mode">Global Namespace Mode</string>
|
||||
<string name="settings_global_namespace_mode_summary">All root sessions use the global mount namespace</string>
|
||||
</resources>
|
||||
|
||||
@@ -231,6 +231,4 @@
|
||||
<string name="module_sort_enabled_first">Sort (Enabled first)</string>
|
||||
<string name="module_sort_action_first">Sort (Action first)</string>
|
||||
<string name="module_sort_webui_first">Sort (WebUI first)</string>
|
||||
<string name="settings_global_namespace_mode">Global Namespace Mode</string>
|
||||
<string name="settings_global_namespace_mode_summary">All root sessions use the global mount namespace</string>
|
||||
</resources>
|
||||
|
||||
@@ -231,6 +231,4 @@
|
||||
<string name="module_sort_enabled_first">Sortierung (aktivierte zuerst)</string>
|
||||
<string name="module_sort_action_first">Sortierung (Aktion zuerst)</string>
|
||||
<string name="module_sort_webui_first">Sortierung (WebUI zuerst)</string>
|
||||
<string name="settings_global_namespace_mode">Globaler Namensraum-Modus</string>
|
||||
<string name="settings_global_namespace_mode_summary">Alle Root-Sitzungen verwenden den globalen Mount-Namespace</string>
|
||||
</resources>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<string name="home_working">Funcionando</string>
|
||||
<string name="home_working_version">Versión: %d</string>
|
||||
<string name="home_module_update_count">Actualizaciones: %d</string>
|
||||
<string name="home_failure">¡Firma v2 de KernelSU Next no encontrada en el kernel! [ !KSU_NEXT || != size/hash ]</string>
|
||||
<string name="home_failure">¡No se encontró la firma de KernelSU Next v2 en el kernel! [ !KSU_NEXT || != size/hash ]</string>
|
||||
<string name="home_failure_tip">¡Pídele a tu desarrollador de kernel que integre KernelSU Next!</string>
|
||||
<string name="home_kernel">Versión del kernel</string>
|
||||
<string name="hook_mode">Método de intercepción</string>
|
||||
@@ -119,7 +119,7 @@
|
||||
<string name="profile_template">Plantilla</string>
|
||||
<string name="profile_custom">Personalizado</string>
|
||||
<string name="profile_name">Nombre de perfil</string>
|
||||
<string name="profile_namespace">Espacio de montaje aislado</string>
|
||||
<string name="profile_namespace">Espacio de nombres de montaje</string>
|
||||
<string name="profile_namespace_inherited">Heredado</string>
|
||||
<string name="profile_namespace_global">Global</string>
|
||||
<string name="profile_namespace_individual">Individual</string>
|
||||
@@ -228,9 +228,7 @@
|
||||
<string name="home_module_count_singular">Módulo</string>
|
||||
<string name="home_module_count_plural">Módulos</string>
|
||||
<string name="module_backup_message">Respaldar los módulos actualmente instalados.</string>
|
||||
<string name="module_sort_enabled_first">Ordenar (Activados Primero)</string>
|
||||
<string name="module_sort_action_first">Ordenar (Accionables primero)</string>
|
||||
<string name="module_sort_webui_first">Ordenar (WrbUI primero)</string>
|
||||
<string name="settings_global_namespace_mode">Usar el Espacio de Montaje Aislado Global</string>
|
||||
<string name="settings_global_namespace_mode_summary">Todas las sesiones root usan el espacio de montaje aislado global</string>
|
||||
<string name="module_sort_enabled_first">Sort (Enabled first)</string>
|
||||
<string name="module_sort_action_first">Sort (Action first)</string>
|
||||
<string name="module_sort_webui_first">Sort (WebUI first)</string>
|
||||
</resources>
|
||||
|
||||
@@ -232,6 +232,4 @@
|
||||
<string name="module_sort_enabled_first">Sort (Enabled first)</string>
|
||||
<string name="module_sort_action_first">Sort (Action first)</string>
|
||||
<string name="module_sort_webui_first">Sort (WebUI first)</string>
|
||||
<string name="settings_global_namespace_mode">Global Namespace Mode</string>
|
||||
<string name="settings_global_namespace_mode_summary">All root sessions use the global mount namespace</string>
|
||||
</resources>
|
||||
|
||||
@@ -233,6 +233,4 @@
|
||||
<string name="module_sort_enabled_first">Trier (Activé en premier)</string>
|
||||
<string name="module_sort_action_first">Trier (Action en premier)</string>
|
||||
<string name="module_sort_webui_first">Trier (WebUI en premier)</string>
|
||||
<string name="settings_global_namespace_mode">Global Namespace Mode</string>
|
||||
<string name="settings_global_namespace_mode_summary">All root sessions use the global mount namespace</string>
|
||||
</resources>
|
||||
|
||||
@@ -233,6 +233,4 @@
|
||||
<string name="module_sort_enabled_first">Sort (Enabled first)</string>
|
||||
<string name="module_sort_action_first">Sort (Action first)</string>
|
||||
<string name="module_sort_webui_first">Sort (WebUI first)</string>
|
||||
<string name="settings_global_namespace_mode">Global Namespace Mode</string>
|
||||
<string name="settings_global_namespace_mode_summary">All root sessions use the global mount namespace</string>
|
||||
</resources>
|
||||
|
||||
@@ -231,6 +231,4 @@
|
||||
<string name="module_sort_enabled_first">Sort (Enabled first)</string>
|
||||
<string name="module_sort_action_first">Sort (Action first)</string>
|
||||
<string name="module_sort_webui_first">Sort (WebUI first)</string>
|
||||
<string name="settings_global_namespace_mode">Global Namespace Mode</string>
|
||||
<string name="settings_global_namespace_mode_summary">All root sessions use the global mount namespace</string>
|
||||
</resources>
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="issue_report_title">Memiliki kendala?</string>
|
||||
<string name="issue_report_body">Mengalami kesalahan atau memiliki umpan balik?</string>
|
||||
<string name="issue_report_body_2">Laporkan secepatnya!</string>
|
||||
<string name="issue_report_title">Ada kendala?</string>
|
||||
<string name="issue_report_body">Menemukan bug atau memiliki umpan balik?</string>
|
||||
<string name="issue_report_body_2">Laporkan sesegera mungkin!</string>
|
||||
<string name="issue_report_github">Laporkan di GitHub</string>
|
||||
<string name="issue_report_telegram">Hubungi melalui Telegram</string>
|
||||
<string name="issue_report_github_link">https://github.com/KernelSU-Next/KernelSU-Next/issues</string>
|
||||
<string name="issue_report_telegram_link">https://t.me/ksunext</string>
|
||||
<string name="confirm">Ya</string>
|
||||
<string name="confirm">Konfirmasi</string>
|
||||
<string name="app_name">KernelSU Next</string>
|
||||
<string name="home">Beranda</string>
|
||||
<string name="home_not_installed">Tidak terinstal</string>
|
||||
<string name="home_click_to_install">Klik untuk menginstal</string>
|
||||
<string name="home_not_installed">Tidak terpasang</string>
|
||||
<string name="home_click_to_install">Klik untuk memasang</string>
|
||||
<string name="lkm_mode_deprecated">Mode LKM sekarang sudah tidak digunakan lagi!</string>
|
||||
<string name="lkm_alternative_suggestion">Pasang kernel GKI atau integrasikan KernelSU Next ke perangkat anda.</string>
|
||||
<string name="home_working">Berfungsi</string>
|
||||
@@ -32,7 +32,7 @@
|
||||
<string name="home_android">Versi android</string>
|
||||
<string name="home_manager_version">Versi manajer</string>
|
||||
<string name="home_abi">ABI</string>
|
||||
<string name="home_selinux_status">SELinux status</string>
|
||||
<string name="home_selinux_status">Status SELinu</string>
|
||||
<string name="selinux_status_disabled">Nonaktif</string>
|
||||
<string name="selinux_status_enforcing">Enforcing</string>
|
||||
<string name="selinux_status_permissive">Permissive</string>
|
||||
@@ -42,7 +42,7 @@
|
||||
<string name="module_failed_to_disable">Gagal menonaktifkan modul: %s</string>
|
||||
<string name="module_empty">Tidak ada modul yang terpasang</string>
|
||||
<string name="module">Modul</string>
|
||||
<string name="module_install_prompt_with_name">Modul yang akan diinstal: %1$s</string>
|
||||
<string name="module_install_prompt_with_name">Modul berikut akan dipasang: %1$s</string>
|
||||
<string name="module_sort_a_to_z">Urutkan (A → Z)</string>
|
||||
<string name="module_sort_z_to_a">Urutkan (Z → A)</string>
|
||||
<string name="module_size_low_to_high">Urutkan (Kecil → Besar)</string>
|
||||
@@ -232,6 +232,4 @@
|
||||
<string name="module_sort_enabled_first">Urutkan (Diaktifkan lebih dulu)</string>
|
||||
<string name="module_sort_action_first">Urutkan (Aksi lebih dulu)</string>
|
||||
<string name="module_sort_webui_first">Urutkan (WebUI lebih dulu)</string>
|
||||
<string name="settings_global_namespace_mode">Mode Namespace Universal</string>
|
||||
<string name="settings_global_namespace_mode_summary">Semua sesi root menggunakan mount namespace universal</string>
|
||||
</resources>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<string name="issue_report_telegram_link">https://t.me/ksunext</string>
|
||||
<string name="confirm">Conferma</string>
|
||||
<string name="app_name">KernelSU Next</string>
|
||||
<string name="home">Home</string>
|
||||
<string name="home">Casa</string>
|
||||
<string name="home_not_installed">Non installato</string>
|
||||
<string name="home_click_to_install">Clicca per installare</string>
|
||||
<string name="lkm_mode_deprecated">La modalità LKM è ora obsoleta!</string>
|
||||
@@ -17,7 +17,7 @@
|
||||
<string name="home_working">In esecuzione</string>
|
||||
<string name="home_working_version">Versione: %d</string>
|
||||
<string name="home_module_update_count">Aggiornamenti: %d</string>
|
||||
<string name="home_failure">Firma v2 di KernelSU Next non trovata nel kernel! [ !KSU_NEXT || != size/hash ]</string>
|
||||
<string name="home_failure">KernelSU Next firma v2 non trovata nel kernel! [ !KSU_NEXT || != size/hash ]</string>
|
||||
<string name="home_failure_tip">Chiedi allo sviluppatore del kernel d\'integrare KernelSU Next!</string>
|
||||
<string name="home_kernel">Versione kernel</string>
|
||||
<string name="hook_mode">Modalità Hook</string>
|
||||
@@ -37,7 +37,7 @@
|
||||
<string name="selinux_status_enforcing">Enforcing</string>
|
||||
<string name="selinux_status_permissive">Permissive</string>
|
||||
<string name="selinux_status_unknown">Sconosciuto</string>
|
||||
<string name="superuser">Accesso root</string>
|
||||
<string name="superuser">Superutente</string>
|
||||
<string name="module_failed_to_enable">Impossibile abilitare il modulo: %s</string>
|
||||
<string name="module_failed_to_disable">Impossibile disabilitare il modulo: %s</string>
|
||||
<string name="module_empty">Nessun modulo installato</string>
|
||||
@@ -187,7 +187,7 @@
|
||||
<string name="select_file">Seleziona un file</string>
|
||||
<string name="install_inactive_slot">Installa nello slot inattivo (dopo un aggiornamento OTA)</string>
|
||||
<string name="install_inactive_slot_warning">Dopo il riavvio, il dispositivo sarà FORZATO ad avviarsi nello slot attualmente inattivo!\nUtilizza questa opzione solo dopo aver completato l\'aggiornamento OTA.\nVuoi continuare?</string>
|
||||
<string name="install_next">Next</string>
|
||||
<string name="install_next"></string>
|
||||
<string name="select_file_tip">Immagine partizione %1$s consigliata</string>
|
||||
<string name="select_kmi">Seleziona KMI</string>
|
||||
<string name="shrink_sparse_image">Minimizza l\'immagine sparsa</string>
|
||||
@@ -207,7 +207,7 @@
|
||||
<string name="log_saved">Log salvati</string>
|
||||
<string name="send_log">Condividi i log</string>
|
||||
<string name="settings_disable_su">Disattiva la compatibilità su</string>
|
||||
<string name="settings_disable_su_summary">Disattiva temporaneamente la capacità di ogni applicazione di ottenere i permessi root tramite il comando su (le sessioni di root esistenti non subiranno modifiche).</string>
|
||||
<string name="settings_disable_su_summary">Disattiva temporaneamente la capacità di ogni applicazione di ottenere i permessi di root tramite il comando su (le sessioni di root esistenti non subiranno modifiche).</string>
|
||||
<string name="settings_language">Lingua</string>
|
||||
<string name="system_default">Default di sistema</string>
|
||||
<string name="settings_legacyui">Usa lo stile d\'interfaccia precedente</string>
|
||||
@@ -223,14 +223,12 @@
|
||||
<string name="sucompat_disabled">SUCOMPAT DISABILITATO</string>
|
||||
<string name="zygisk_required">Zygisk richiesto</string>
|
||||
<string name="zygisk_status">Iniezione Zygisk</string>
|
||||
<string name="home_superuser_count_singular">Accesso root</string>
|
||||
<string name="home_superuser_count_plural">Accessi root</string>
|
||||
<string name="home_superuser_count_singular">Superutente</string>
|
||||
<string name="home_superuser_count_plural">Superutenti</string>
|
||||
<string name="home_module_count_singular">Modulo</string>
|
||||
<string name="home_module_count_plural">Moduli</string>
|
||||
<string name="module_backup_message">Esegue il backup dei moduli attualmente esistenti.</string>
|
||||
<string name="module_sort_enabled_first">Ordina (prima Abilitato)</string>
|
||||
<string name="module_sort_action_first">Ordina (prima Azione)</string>
|
||||
<string name="module_sort_webui_first">Ordina (prima WebUI)</string>
|
||||
<string name="settings_global_namespace_mode">Modalità Namespace globale</string>
|
||||
<string name="settings_global_namespace_mode_summary">Tutte le sessioni root usano lo spazio di montaggio globale</string>
|
||||
</resources>
|
||||
|
||||
@@ -231,6 +231,4 @@
|
||||
<string name="module_sort_enabled_first">並べ替え (有効を優先)</string>
|
||||
<string name="module_sort_action_first">並べ替え (実行可能を優先)</string>
|
||||
<string name="module_sort_webui_first">並べ替え (WebUIを優先)</string>
|
||||
<string name="settings_global_namespace_mode">グローバル名前空間モード</string>
|
||||
<string name="settings_global_namespace_mode_summary">すべての root セッションがグローバルマウント名前空間を使用します</string>
|
||||
</resources>
|
||||
|
||||
@@ -231,6 +231,4 @@
|
||||
<string name="module_sort_enabled_first">정렬 (활성화됨 우선)</string>
|
||||
<string name="module_sort_action_first">정렬 (동작 우선)</string>
|
||||
<string name="module_sort_webui_first">정렬 (WebUI 우선)</string>
|
||||
<string name="settings_global_namespace_mode">Global Namespace Mode</string>
|
||||
<string name="settings_global_namespace_mode_summary">All root sessions use the global mount namespace</string>
|
||||
</resources>
|
||||
|
||||
@@ -45,8 +45,8 @@
|
||||
<string name="module_install_prompt_with_name">Następujące moduły zostaną zainstalowane: %1$s</string>
|
||||
<string name="module_sort_a_to_z">Sortuj (A → Z)</string>
|
||||
<string name="module_sort_z_to_a">Sortuj (Z → A)</string>
|
||||
<string name="module_size_low_to_high">Sortuj (Małe → Duże)</string>
|
||||
<string name="module_size_high_to_low">Sortuj (Duże → Małe)</string>
|
||||
<string name="module_size_low_to_high">Sortuj (Najmniejszy → Największy)</string>
|
||||
<string name="module_size_high_to_low">Sortuj (Największy → Najmniejszy)</string>
|
||||
<string name="uninstall">Odinstaluj</string>
|
||||
<string name="restore">Przywróć</string>
|
||||
<string name="module_install">Zainstaluj</string>
|
||||
@@ -216,21 +216,19 @@
|
||||
<string name="settings_banner_summary">Wyświetlaj banery modułów w tle.</string>
|
||||
<string name="use_webuix">Używaj WebUI X</string>
|
||||
<string name="use_webuix_summary">Używaj WebUI X zamiast WebUI, który obsługuje więcej interfejsów API.</string>
|
||||
<string name="use_webuix_eruda">Wstrzykiwanie Eruda do WebUI X</string>
|
||||
<string name="use_webuix_eruda">Wstrzyknij Eruda do WebUI X</string>
|
||||
<string name="use_webuix_eruda_summary">Wstrzyknij konsolę debugowania do WebUI X, aby ułatwić debugowanie. Wymagane jest aktywne debugowanie WebView.</string>
|
||||
<string name="customization">Personalizacja</string>
|
||||
<string name="developer">Programista</string>
|
||||
<string name="sucompat_disabled">SUCOMPAT NIEAKTYWNY</string>
|
||||
<string name="zygisk_required">Wymagany Zygisk</string>
|
||||
<string name="zygisk_status">Wstrzykiwanie Zygisk</string>
|
||||
<string name="zygisk_status">Wstrzyknięcie Zygisk</string>
|
||||
<string name="home_superuser_count_singular">Superuser</string>
|
||||
<string name="home_superuser_count_plural">Superuserzy</string>
|
||||
<string name="home_module_count_singular">Moduł</string>
|
||||
<string name="home_module_count_plural">Moduły</string>
|
||||
<string name="module_backup_message">Utwórz kopię zapasową obecnie zainstalowanych modułów.</string>
|
||||
<string name="module_sort_enabled_first">Sortuj (najpierw włączone)</string>
|
||||
<string name="module_sort_action_first">Sortuj (najpierw z Akcją)</string>
|
||||
<string name="module_sort_webui_first">Sortuj (najpierw z WebUI)</string>
|
||||
<string name="settings_global_namespace_mode">Tryb globalnej przestrzeni nazw</string>
|
||||
<string name="settings_global_namespace_mode_summary">Wszystkie sesje roota używają globalnej przestrzeni nazw montowania</string>
|
||||
<string name="module_sort_enabled_first">Sort (Enabled first)</string>
|
||||
<string name="module_sort_action_first">Sort (Action first)</string>
|
||||
<string name="module_sort_webui_first">Sort (WebUI first)</string>
|
||||
</resources>
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
<string name="install">Instalar</string>
|
||||
<string name="reboot">Reiniciar</string>
|
||||
<string name="uninstalled">Desinstalado</string>
|
||||
<string name="settings">Ajustes</string>
|
||||
<string name="settings">Configurações</string>
|
||||
<string name="reboot_userspace">Reiniciar</string>
|
||||
<string name="reboot_recovery">Reiniciar em modo Recovery</string>
|
||||
<string name="reboot_bootloader">Reiniciar em modo Bootloader</string>
|
||||
@@ -228,9 +228,7 @@
|
||||
<string name="home_module_count_singular">Módulo</string>
|
||||
<string name="home_module_count_plural">Módulos</string>
|
||||
<string name="module_backup_message">Fazer backup dos módulos instalados.</string>
|
||||
<string name="module_sort_enabled_first">Ordenar (Habilitado primeiro)</string>
|
||||
<string name="module_sort_action_first">Ordenar (exceto primeiro)</string>
|
||||
<string name="module_sort_webui_first">Ordenar (WebUI primeiro)</string>
|
||||
<string name="settings_global_namespace_mode">Global Namespace Mode</string>
|
||||
<string name="settings_global_namespace_mode_summary">All root sessions use the global mount namespace</string>
|
||||
<string name="module_sort_enabled_first">Sort (Enabled first)</string>
|
||||
<string name="module_sort_action_first">Sort (Action first)</string>
|
||||
<string name="module_sort_webui_first">Sort (WebUI first)</string>
|
||||
</resources>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="issue_report_title">Возникли проблемы?</string>
|
||||
<string name="issue_report_body">Обнаружена ошибка или нужна обратная связь?</string>
|
||||
<string name="issue_report_body">Обнаружена ошибка или есть обратная связь?</string>
|
||||
<string name="issue_report_body_2">Сообщите об этом как можно скорее!</string>
|
||||
<string name="issue_report_github">Сообщить на GitHub</string>
|
||||
<string name="issue_report_telegram">Связаться через Telegram</string>
|
||||
@@ -100,7 +100,7 @@
|
||||
<string name="allowlist_backup_message">Резервное копирование текущего списка разрешений.</string>
|
||||
<string name="warning">Предупреждение</string>
|
||||
<string name="warning_message">Эта функция всё ещё находится в стадии бета-тестирования. Пожалуйста, убедитесь, что вы создали резервные копии модулей перед использованием. Используйте это только если понимаете возможные риски. Будьте осторожны.</string>
|
||||
<string name="proceed">Продолжить</string>
|
||||
<string name="proceed">В процессе</string>
|
||||
<string name="cancel">Отмена</string>
|
||||
<string name="later">Позже</string>
|
||||
<string name="lkm_warning_message">Патч LKM использует компоненты с закрытым исходным кодом. Хотите продолжить?</string>
|
||||
@@ -117,7 +117,7 @@
|
||||
<string name="profile">Профиль Приложения</string>
|
||||
<string name="profile_default">По умолчанию</string>
|
||||
<string name="profile_template">Шаблон</string>
|
||||
<string name="profile_custom">Пользовательский</string>
|
||||
<string name="profile_custom">Настроить</string>
|
||||
<string name="profile_name">Имя профиля</string>
|
||||
<string name="profile_namespace">Пространство монтирования</string>
|
||||
<string name="profile_namespace_inherited">Унаследованный</string>
|
||||
@@ -126,14 +126,14 @@
|
||||
<string name="profile_groups">Группы</string>
|
||||
<string name="profile_capabilities">Возможности</string>
|
||||
<string name="profile_selinux_context">Контекст SELinux</string>
|
||||
<string name="profile_umount_modules">Размонтировать модули</string>
|
||||
<string name="profile_umount_modules">Отключить модули</string>
|
||||
<string name="failed_to_update_app_profile">Не удалось обновить Профиль Приложения для %s</string>
|
||||
<string name="require_kernel_version">Текущая версия KernelSU Next %1$d слишком низкая для корректной работы менеджера. Пожалуйста, обновитесь до версии %2$d или выше!</string>
|
||||
<string name="settings_umount_modules_default">Размонтировать модули</string>
|
||||
<string name="settings_umount_modules_default_summary">По умолчанию включает статус \"Umount\" для приложений. Если эта настройка включена, то все модификации, внесённые модулями, будут удалены для приложений без включённого root-доступа.</string>
|
||||
<string name="settings_umount_modules_default">Отключить модули</string>
|
||||
<string name="settings_umount_modules_default_summary">Глобальное значение по умолчанию для \"Отключить модули\" в Профиле Приложения. Если включено, это удалит все модификации системы модулями для приложений без установленного профиля.</string>
|
||||
<string name="settings_susfs_toggle">Скрыть хук kprobes</string>
|
||||
<string name="settings_susfs_toggle_summary">Эта опция отключает хук kprobes, созданный ksu, и вместо него активирует встроенный хук без использования kprobes, реализующий ту же функциональность, которая применяется к ядрам без GKI, не поддерживающим kprobe.</string>
|
||||
<string name="profile_umount_modules_summary">Если эта настройка включена, то все модификации, внесённые модулями, будут удалены для данного приложения.</string>
|
||||
<string name="profile_umount_modules_summary">Включение этой опции позволит KernelSU Next восстанавливать любые изменённые модулями файлы для этого приложения.</string>
|
||||
<string name="profile_selinux_domain">Домен</string>
|
||||
<string name="profile_selinux_rules">Правила</string>
|
||||
<string name="module_update">Обновить</string>
|
||||
@@ -153,8 +153,8 @@
|
||||
<string name="failed_to_update_sepolicy">Не удалось обновить правила SELinux для %s</string>
|
||||
<string name="su_not_allowed">Предоставление прав суперпользователя запрещено для: %s</string>
|
||||
<string name="module_changelog">Журнал изменений</string>
|
||||
<string name="settings_profile_template">Шаблоны доступа</string>
|
||||
<string name="settings_profile_template_summary">Управление локальными и онлайн шаблонами root-доступа.</string>
|
||||
<string name="settings_profile_template">Шаблон Профиля Приложений</string>
|
||||
<string name="settings_profile_template_summary">Управление локальными и онлайн шаблонами профилей приложений.</string>
|
||||
<string name="app_profile_template_create">Создать шаблон</string>
|
||||
<string name="app_profile_template_edit">Изменить шаблон</string>
|
||||
<string name="app_profile_template_id">ID</string>
|
||||
@@ -231,6 +231,4 @@
|
||||
<string name="module_sort_enabled_first">По статусу (Сначала включённые)</string>
|
||||
<string name="module_sort_action_first">По статусу (Сначала со скриптом)</string>
|
||||
<string name="module_sort_webui_first">По статусу (Сначала с WebUI)</string>
|
||||
<string name="settings_global_namespace_mode">Общее пространство имён</string>
|
||||
<string name="settings_global_namespace_mode_summary">Все сессии пользователя root будут использовать общее пространство имён</string>
|
||||
</resources>
|
||||
|
||||
@@ -231,6 +231,4 @@
|
||||
<string name="module_sort_enabled_first">Sort (Enabled first)</string>
|
||||
<string name="module_sort_action_first">Sort (Action first)</string>
|
||||
<string name="module_sort_webui_first">Sort (WebUI first)</string>
|
||||
<string name="settings_global_namespace_mode">Global Namespace Mode</string>
|
||||
<string name="settings_global_namespace_mode_summary">All root sessions use the global mount namespace</string>
|
||||
</resources>
|
||||
|
||||
@@ -231,6 +231,4 @@
|
||||
<string name="module_sort_enabled_first">Sort (Enabled first)</string>
|
||||
<string name="module_sort_action_first">Sort (Action first)</string>
|
||||
<string name="module_sort_webui_first">Sort (WebUI first)</string>
|
||||
<string name="settings_global_namespace_mode">Global Namespace Mode</string>
|
||||
<string name="settings_global_namespace_mode_summary">All root sessions use the global mount namespace</string>
|
||||
</resources>
|
||||
|
||||
@@ -1,52 +1,52 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="issue_report_title">Sorun mu yaşıyorsunuz?</string>
|
||||
<string name="issue_report_body">Bir hatayla mı karşılaştınız veya geri bildiriminiz mi var?</string>
|
||||
<string name="issue_report_body_2">Mümkün olan en kısa sürede bildirin!</string>
|
||||
<string name="issue_report_github">GitHub’da bildirin</string>
|
||||
<string name="issue_report_telegram">Telegram üzerinden iletişim kurun</string>
|
||||
<string name="issue_report_body">Hata veya öneri mi bildirmek istiyorsunuz?</string>
|
||||
<string name="issue_report_body_2">Hemen bildirin!</string>
|
||||
<string name="issue_report_github">GitHub\'de bildirin</string>
|
||||
<string name="issue_report_telegram">Telegram ile iletişim kurun</string>
|
||||
<string name="issue_report_github_link">https://github.com/KernelSU-Next/KernelSU-Next/issues</string>
|
||||
<string name="issue_report_telegram_link">https://t.me/ksunext</string>
|
||||
<string name="confirm">Onayla</string>
|
||||
<string name="app_name">KernelSU Next</string>
|
||||
<string name="home">Ana Ekran</string>
|
||||
<string name="home_not_installed">Yüklü değil</string>
|
||||
<string name="home_click_to_install">Yüklemek için tıklayın</string>
|
||||
<string name="lkm_mode_deprecated">LKM modu artık kullanımdan kaldırıldı!</string>
|
||||
<string name="lkm_alternative_suggestion">GKI çekirdeğini yükleyin veya KernelSU Next\'i cihazınıza entegre edin.</string>
|
||||
<string name="home_not_installed">Yüklenmedi</string>
|
||||
<string name="home_click_to_install">Yüklemek için dokunun</string>
|
||||
<string name="lkm_mode_deprecated">LKM modu kullanımdan kaldırıldı!</string>
|
||||
<string name="lkm_alternative_suggestion">GKI kernel yükleyin veya KernelSU Next\'i cihazınıza entegre edin.</string>
|
||||
<string name="home_working">Çalışıyor</string>
|
||||
<string name="home_working_version">Sürüm: %d</string>
|
||||
<string name="home_module_update_count">Güncellemeler: %d</string>
|
||||
<string name="home_failure">KernelSU Next v2 imzası çekirdekte bulunamadı! [ !KSU_NEXT || != size/hash ]</string>
|
||||
<string name="home_failure">KernelSU Next v2 imzası kernelde bulunamadı! [ !KSU_NEXT || != size/hash ]</string>
|
||||
<string name="home_failure_tip">Kernel geliştiricinizden KernelSU Next\'i entegre etmelerini isteyin!</string>
|
||||
<string name="home_kernel">Çekirdek sürümü</string>
|
||||
<string name="hook_mode">Kanca modu</string>
|
||||
<string name="home_kernel">Kernel sürümü</string>
|
||||
<string name="hook_mode">Hook modu</string>
|
||||
<string name="enable">Etkinleştir</string>
|
||||
<string name="disable">Devre dışı bırak</string>
|
||||
<string name="enabled">Etkin</string>
|
||||
<string name="disabled">Devre dışı</string>
|
||||
<string name="enabled">Etkinleştir</string>
|
||||
<string name="disabled">Devre dışı bırak</string>
|
||||
<string name="susfs_supported">Destekleniyor</string>
|
||||
<string name="home_susfs">SuSFS: %s</string>
|
||||
<string name="home_susfs_version">SuSFS sürümü</string>
|
||||
<string name="home_susfs_sus_su">SuS SU</string>
|
||||
<string name="home_android">Android sürümü</string>
|
||||
<string name="home_manager_version">Yönetici sürümü</string>
|
||||
<string name="home_manager_version">Uygulama sürümü</string>
|
||||
<string name="home_abi">ABI</string>
|
||||
<string name="home_selinux_status">SELinux durumu</string>
|
||||
<string name="selinux_status_disabled">Devre dışı</string>
|
||||
<string name="selinux_status_enforcing">Zorlanıyor</string>
|
||||
<string name="selinux_status_permissive">Permissive (Serbest)</string>
|
||||
<string name="selinux_status_permissive">Etkin değil</string>
|
||||
<string name="selinux_status_unknown">Bilinmiyor</string>
|
||||
<string name="superuser">Süper Kullanıcı</string>
|
||||
<string name="superuser">Superuser</string>
|
||||
<string name="module_failed_to_enable">Modül etkinleştirilemedi: %s</string>
|
||||
<string name="module_failed_to_disable">Modül devre dışı bırakılamadı: %s</string>
|
||||
<string name="module_empty">Yüklü modül yok</string>
|
||||
<string name="module_empty">Yüklenmiş modül yok</string>
|
||||
<string name="module">Modül</string>
|
||||
<string name="module_install_prompt_with_name">Bu modüller yüklenecektir: %1$s</string>
|
||||
<string name="module_sort_a_to_z">Sırala (A → Z)</string>
|
||||
<string name="module_sort_z_to_a">Sırala (Z → A)</string>
|
||||
<string name="module_size_low_to_high">Sırala (Düşük → Yüksek)</string>
|
||||
<string name="module_size_high_to_low">Sırala (Yüksek → Düşük)</string>
|
||||
<string name="module_size_low_to_high">Sırala (Low → High)</string>
|
||||
<string name="module_size_high_to_low">Sırala (High → Low)</string>
|
||||
<string name="uninstall">Kaldır</string>
|
||||
<string name="restore">Geri yükle</string>
|
||||
<string name="module_install">Yükle</string>
|
||||
@@ -63,9 +63,9 @@
|
||||
<string name="module_uninstall_confirm">%s modülünü kaldırmak istediğinize emin misiniz?</string>
|
||||
<string name="module_uninstall_success">%s kaldırıldı</string>
|
||||
<string name="module_uninstall_failed">Kaldırma başarısız oldu: %s</string>
|
||||
<string name="module_restore_confirm">%s modülünü geri yüklemek istediğinize emin misiniz?</string>
|
||||
<string name="module_restore_success">%s geri yüklendi</string>
|
||||
<string name="module_restore_failed">Geri yükleme başarısız oldu: %s</string>
|
||||
<string name="module_restore_confirm">%s modülünü geri getirmek istediğinize emin misiniz?</string>
|
||||
<string name="module_restore_success">%s geri getirildi</string>
|
||||
<string name="module_restore_failed">Geri getirme başarısız oldu: %s</string>
|
||||
<string name="module_version">Sürüm</string>
|
||||
<string name="module_author">Geliştirici</string>
|
||||
<string name="module_id">Kimlik</string>
|
||||
@@ -74,7 +74,7 @@
|
||||
<string name="module_update_json_empty">Boş</string>
|
||||
<string name="enable_developer_options">Geliştirici seçeneklerini etkinleştir</string>
|
||||
<string name="enable_developer_options_summary">Yalnızca geliştiricilere yönelik gizli ayarları ve hata ayıklama bilgilerini göster.</string>
|
||||
<string name="module_overlay_fs_not_available">OverlayFS çekirdek tarafından devre dışı bırakıldığı için modüller kullanılamıyor!</string>
|
||||
<string name="module_overlay_fs_not_available">OverlayFS çekirdek tarafından devre dışı bırakıldığından modüller kullanılamaz!</string>
|
||||
<string name="refresh">Yenile</string>
|
||||
<string name="show_system_apps">Sistem uygulamalarını göster</string>
|
||||
<string name="hide_system_apps">Sistem uygulamalarını gizle</string>
|
||||
@@ -90,28 +90,28 @@
|
||||
<string name="use_overlay_fs_summary">KernelSU Next\'in bağlama sistemi için Magic Mount üzerinden OverlayFS kullanımı arasında geçiş yapın.</string>
|
||||
<string name="reboot_required">Yeniden başlatma gerekli</string>
|
||||
<string name="reboot_message">Değişiklikler sistem yeniden başlatıldıktan sonra geçerli olacaktır. Şimdi yeniden başlatmak istiyor musunuz?</string>
|
||||
<string name="module_restore">Modülü geri yükle</string>
|
||||
<string name="module_restore_message">Modülleri son yedeklemeden geri yükleyin.</string>
|
||||
<string name="module_restore">Modülü geri getir</string>
|
||||
<string name="module_restore_message">En yeni yedeklemeden modülleri geri getir.</string>
|
||||
<string name="backup_restore">Yedekle & Geri Getir</string>
|
||||
<string name="module_backup">Modülü yedekle</string>
|
||||
<string name="allowlist_restore">İzin listesini geri yükle</string>
|
||||
<string name="allowlist_restore_message">İzin listesini son yedeklemeden geri yükleyin.</string>
|
||||
<string name="allowlist_backup">İzin listesini yedekle</string>
|
||||
<string name="allowlist_restore">İzin verilen listesini geri yükle</string>
|
||||
<string name="allowlist_restore_message">En yeni yedeklemeden modülleri geri getir.</string>
|
||||
<string name="allowlist_backup">İzin verilen listesini yedekle</string>
|
||||
<string name="allowlist_backup_message">Şu anda yapılandırılmış izin listesini yedekleyin.</string>
|
||||
<string name="warning">Uyarı</string>
|
||||
<string name="warning">Uyarı!</string>
|
||||
<string name="warning_message">Bu özellik hala beta aşamasındadır ve geliştirilme aşamasındadır. Lütfen devam etmeden önce modüllerinizi yedeklediğinizden emin olun. Bu özelliği yalnızca potansiyel riskleri anlıyorsanız kullanın. Dikkatli bir şekilde ilerleyin.</string>
|
||||
<string name="proceed">Devam et</string>
|
||||
<string name="cancel">İptal et</string>
|
||||
<string name="later">Sonra</string>
|
||||
<string name="lkm_warning_message">LKM yaması kapalı kaynak bileşenlerine dayanır. Devam etmek istiyor musunuz?</string>
|
||||
<string name="home_next_kernelsu">🔥 Next Yapımı</string>
|
||||
<string name="lkm_warning_message">LKM yamaları kapalı kaynak kodludur. Devam etmek istiyor musunuz?</string>
|
||||
<string name="home_next_kernelsu">🔥 Sıradaki yapı</string>
|
||||
<string name="home_next_kernelsu_repo">https://github.com/KernelSU-Next/KernelSU-Next</string>
|
||||
<string name="home_next_kernelsu_body">Next deneysel dalı. GitHub\'da göz atın!</string>
|
||||
<string name="home_next_kernelsu_body">Next deneysel sürümü. GitHub\'da göz atın!</string>
|
||||
<string name="home_experimental_kernelsu">⚠️ Deneysel geliştirme uyarısı!</string>
|
||||
<string name="home_experimental_kernelsu_repo">127.0.0.1</string>
|
||||
<string name="home_experimental_kernelsu_body">KernelSU Next, sürekli geliştirme aşamasında olan resmi olmayan bir sürümdür. Kararlılık, performans veya güvenilirlik garantisi olmadan olduğu gibi sunulur.</string>
|
||||
<string name="home_experimental_kernelsu_body_point_1"> • Risk size aittir: çökmeler, beklenmedik davranışlar veya sistem sorunları meydana gelebilir.</string>
|
||||
<string name="home_experimental_kernelsu_body_point_2"> • Garanti yok: geliştiriciler herhangi bir veri kaybından, sistem hasarından veya kullanımından kaynaklanan diğer sonuçlardan sorumlu değildir.</string>
|
||||
<string name="home_experimental_kernelsu_body_point_2"> • Garantili değil: geliştiriciler; kullanımından kaynaklı veri kaybı, sistem hasarı gibi sonuçlardan sorumlu değildir.</string>
|
||||
<string name="home_experimental_kernelsu_body_point_3"> • Sadece test amaçlı: riskleri anlayan ve sorun giderme konusunda uzman olan kullanıcılar içindir.</string>
|
||||
<string name="about_source_code">Kaynak kodunu görüntüleyin: %1$s</string>
|
||||
<string name="profile">Uygulama Profili</string>
|
||||
@@ -121,42 +121,42 @@
|
||||
<string name="profile_name">Profil ismi</string>
|
||||
<string name="profile_namespace">Bağlama alanadı</string>
|
||||
<string name="profile_namespace_inherited">Inherited</string>
|
||||
<string name="profile_namespace_global">Genel</string>
|
||||
<string name="profile_namespace_individual">Özel</string>
|
||||
<string name="profile_namespace_global">Global</string>
|
||||
<string name="profile_namespace_individual">Bireysel</string>
|
||||
<string name="profile_groups">Gruplar</string>
|
||||
<string name="profile_capabilities">Kabiliyetler</string>
|
||||
<string name="profile_capabilities">Yetenekler</string>
|
||||
<string name="profile_selinux_context">SELinux bağlamı</string>
|
||||
<string name="profile_umount_modules">Modüllerin bağlantısını kes</string>
|
||||
<string name="failed_to_update_app_profile">%s için Uygulama Profili güncellenemedi</string>
|
||||
<string name="require_kernel_version">Geçerli KernelSU Next sürümü %1$d, yöneticinin düzgün çalışması için çok düşük. Lütfen %2$d veya daha yüksek bir sürüme yükseltin!</string>
|
||||
<string name="failed_to_update_app_profile">Uygulama profil güncellemesi %s için başarısız oldu</string>
|
||||
<string name="require_kernel_version">Mecvut KernelSU Next sürümü %1$d, uygulamanın doğru çalışması için çok düşük. Lütfen %2$d ya da daha yüksek bir sürüme yükseltin!</string>
|
||||
<string name="settings_umount_modules_default">Modüllerin bağlantısını kes</string>
|
||||
<string name="settings_umount_modules_default_summary">Uygulama profilinde \"Modüllerin bağlantısını kes\" ayarı için genel varsayılan değer. Etkinleştirilirse, profili ayarlanmamış tüm uygulamalar için sistemdeki tüm modül değişikliklerini kaldırır.</string>
|
||||
<string name="settings_susfs_toggle">kprobes kancasını gizle</string>
|
||||
<string name="settings_susfs_toggle_summary">Bu seçenek, ksu tarafından oluşturulan kprobes kancasını devre dışı bırakır ve bunun yerine, kprobe\'u desteklemeyen GKI olmayan bir çekirdeğe uygulanacak aynı işlevselliği uygulayan gömülü kprobes olmayan kancayı etkinleştirir.</string>
|
||||
<string name="profile_umount_modules_summary">Bu seçeneğin etkinleştirilmesi, KernelSU Next\'in bu uygulama için modüller tarafından değiştirilen tüm dosyaları geri yüklemesine izin verecektir.</string>
|
||||
<string name="settings_susfs_toggle_summary">Bu seçenek, ksu tarafından oluşturulan kprobes kancasını devre dışı bırakır ve bunun yerine gömülü kprobes olmayan kancayı etkinleştirir ve kprobe desteklemeyip GKI olmayan bir çekirdeğe uygulanacak aynı işlevi uygular.</string>
|
||||
<string name="profile_umount_modules_summary">Bu seçeneği etkinleştirmek, KernelSU Next\'in bu uygulama için modüller tarafından değiştirilen dosyaları geri yüklemesine izin verecektir.</string>
|
||||
<string name="profile_selinux_domain">Alan adı</string>
|
||||
<string name="profile_selinux_rules">Kurallar</string>
|
||||
<string name="module_update">Güncelle</string>
|
||||
<string name="module_update">Güncelleme</string>
|
||||
<string name="module_update_available">Güncelleme mevcut</string>
|
||||
<string name="module_updated">Güncellendi</string>
|
||||
<string name="module_downloading">Modül indiriliyor: %s</string>
|
||||
<string name="module_start_downloading">İndirme başlıyor: %s</string>
|
||||
<string name="new_version_available">Yeni sürüm %s mevcut, güncellemek için tıklayın.</string>
|
||||
<string name="launch_app">Başlat</string>
|
||||
<string name="new_version_available">Yeni sürüm %s mevcut, güncellemek için dokunun.</string>
|
||||
<string name="launch_app">Aç</string>
|
||||
<string name="close">Kapat</string>
|
||||
<string name="force_stop_app">Durmaya zorla</string>
|
||||
<string name="restart_app">Yeniden başlat</string>
|
||||
<string name="settings_amoled_mode">AMOLED modu</string>
|
||||
<string name="settings_amoled_mode_summary">Göz yorgunluğunu azaltmak ve pil tasarrufu sağlamak için AMOLED ekranlar için kullanışlı olan saf siyah temayı etkinleştirin.</string>
|
||||
<string name="settings_amoled_mode_summary">AMOLED ekranlar için göz yorgunluğunu azaltmak ve pil tasarrufu sağlamak için kullanışlı saf siyah temayı etkinleştirin.</string>
|
||||
<string name="restart_required">Yeniden başlatma gerekli</string>
|
||||
<string name="restart_app_message">Bu değişikliğin etkili olması için uygulamanın yeniden başlatılması gerekiyor.</string>
|
||||
<string name="restart_app_message">Uygulamanın bu değişikliği uygulaması için yeniden başlatılması gerekiyor.</string>
|
||||
<string name="failed_to_update_sepolicy">%s için SELinux kuralları güncellenemedi</string>
|
||||
<string name="su_not_allowed">%s\'ye süper kullanıcı izni verilemedi</string>
|
||||
<string name="su_not_allowed">%s\'ye Superuser izni verilemedi</string>
|
||||
<string name="module_changelog">Değişiklik Notları</string>
|
||||
<string name="settings_profile_template">Uygulama Profili şablonu</string>
|
||||
<string name="settings_profile_template_summary">Uygulama Profilinin yerel ve çevrimiçi şablonunu yönetme</string>
|
||||
<string name="settings_profile_template_summary">Uygulama Profil Şablonunu yerel ve çevrimiçi olarak yönetin</string>
|
||||
<string name="app_profile_template_create">Şablon oluştur</string>
|
||||
<string name="app_profile_template_edit">Şablonu düzenle</string>
|
||||
<string name="app_profile_template_edit">Şablonu Düzenle</string>
|
||||
<string name="app_profile_template_id">Kimlik</string>
|
||||
<string name="app_profile_template_id_invalid">Geçersiz şablon kimliği</string>
|
||||
<string name="app_profile_template_name">Ad</string>
|
||||
@@ -164,12 +164,12 @@
|
||||
<string name="app_profile_template_save">Kaydet</string>
|
||||
<string name="app_profile_template_delete">Sil</string>
|
||||
<string name="app_profile_template_view">Şablonu görüntüle</string>
|
||||
<string name="app_profile_template_readonly">Salt okunur</string>
|
||||
<string name="app_profile_template_readonly">Sadece okunabilir</string>
|
||||
<string name="app_profile_template_id_exist">Şablon kimliği zaten mevcut!</string>
|
||||
<string name="app_profile_import_export">İçe Aktar / Dışa Aktar</string>
|
||||
<string name="app_profile_import_from_clipboard">Panodan içe aktar</string>
|
||||
<string name="app_profile_export_to_clipboard">Panoya aktar</string>
|
||||
<string name="app_profile_template_export_empty">Dışa aktarılacak yerel şablon bulunamıyor!</string>
|
||||
<string name="app_profile_import_from_clipboard">Pano\'dan içe aktar</string>
|
||||
<string name="app_profile_export_to_clipboard">Panoya çıkar</string>
|
||||
<string name="app_profile_template_export_empty">Dışa aktarmak için yerel şablon bulunamadı!</string>
|
||||
<string name="app_profile_template_import_success">Başarıyla içe aktarıldı</string>
|
||||
<string name="app_profile_template_sync">Çevrimiçi şablonları senkronize et</string>
|
||||
<string name="app_profile_template_save_failed">Şablon kaydedilemedi</string>
|
||||
@@ -177,35 +177,35 @@
|
||||
<string name="module_changelog_failed">Değişiklik günlüğü alınamadı: %s</string>
|
||||
<string name="settings_check_update">Güncellemeleri kontrol et</string>
|
||||
<string name="settings_check_update_summary">Uygulamayı açarken güncellemeleri otomatik denetle</string>
|
||||
<string name="grant_root_failed">Kök izni verilemedi!</string>
|
||||
<string name="action">Eylem</string>
|
||||
<string name="grant_root_failed">Kök yetkisi verilemedi!</string>
|
||||
<string name="action">İşlem</string>
|
||||
<string name="webui">WebUI</string>
|
||||
<string name="open">Aç</string>
|
||||
<string name="enable_web_debugging">WebView hata ayıklamayı etkinleştir</string>
|
||||
<string name="enable_web_debugging_summary">WebUI\'de hata ayıklamak için kullanılabilir. Lütfen yalnızca gerektiğinde etkinleştirin.</string>
|
||||
<string name="enable_web_debugging">WebView hata ayıklama etkinleştir</string>
|
||||
<string name="enable_web_debugging_summary">WebUI\'yi hata ayıklamak için kullanılabilir. Sadece ihtiyaç duyulduğunda etkinleştirin.</string>
|
||||
<string name="direct_install">Doğrudan kurulum (Önerilen)</string>
|
||||
<string name="select_file">Bir dosya seçin</string>
|
||||
<string name="install_inactive_slot">Aktif olmayan yuvaya kur (OTA sonrası)</string>
|
||||
<string name="install_inactive_slot_warning">Cihazınız yeniden başlatıldıktan sonra mevcut etkin olmayan yuvaya önyükleme yapmak için **ZORUNLU** olacaktır.\nBu seçeneği yalnızca OTA tamamlandıktan sonra kullanın.\nDevam?</string>
|
||||
<string name="install_next">Sonraki</string>
|
||||
<string name="install_inactive_slot_warning">Cihazınız **ZORUNLU** olarak aktif olmayan yuvadan yeniden başlatılacaktır!\nBunu sadece OTA tamamlandıktan sonra kullanın\nDevam etmek istiyor musunuz?</string>
|
||||
<string name="install_next">Sıradaki</string>
|
||||
<string name="select_file_tip">%1$s bölüm imajı önerilir</string>
|
||||
<string name="select_kmi">KMI seçin</string>
|
||||
<string name="shrink_sparse_image">Sparse imajını küçültün</string>
|
||||
<string name="shrink_sparse_image_message">Modülün bulunduğu sparse imajını gerçek boyutuna yeniden boyutlandırın. Bunun modülün anormal çalışmasına neden olabileceğini unutmayın, bu nedenle lütfen yalnızca gerekli olduğunda kullanın (Yedekleme gibi).</string>
|
||||
<string name="shrink_sparse_image_message">Modülün bulunduğu sparse imajını gerçek boyutuna yeniden boyutlandırın. Bunun modülün anormal çalışmasına neden olabileceğini unutmayın, bu nedenle lütfen yalnızca gerekli olduğunda kullanın (yedekleme gibi).</string>
|
||||
<string name="settings_uninstall">Kaldır</string>
|
||||
<string name="settings_uninstall_temporary">Geçici olarak kaldır</string>
|
||||
<string name="settings_uninstall_permanent">Kalıcı olarak kaldır</string>
|
||||
<string name="settings_restore_stock_image">Stok imajı geri yükle</string>
|
||||
<string name="settings_uninstall_temporary_message">KernelSU\'yu geçici olarak kaldırın, bir sonraki yeniden başlatmadan sonra orijinal duruma geri dönün.</string>
|
||||
<string name="settings_uninstall_permanent_message">KernelSU Next\'i (Kök ve tüm modüller) tamamen ve kalıcı olarak kaldırın.</string>
|
||||
<string name="settings_uninstall_permanent_message">KernelSU Next\'i (Root ve tüm modüller) tamamen ve kalıcı olarak kaldırın.</string>
|
||||
<string name="settings_restore_stock_image_message">Stok fabrika imajını geri yükler (eğer yedek varsa), genellikle OTA\'dan önce kullanılır; KernelSU\'yu kaldırmanız gerekiyorsa, lütfen \"Kalıcı olarak kaldır\" seçeneğini kullanın.</string>
|
||||
<string name="flashing">Kuruluyor</string>
|
||||
<string name="flash_success">Kurulum başarılı</string>
|
||||
<string name="flash_failed">Kurulum başarısız</string>
|
||||
<string name="selected_lkm">Seçili LKM: %s</string>
|
||||
<string name="save_log">Günlükleri kaydet</string>
|
||||
<string name="log_saved">Günlükler kaydedildi</string>
|
||||
<string name="send_log">Günlükleri paylaş</string>
|
||||
<string name="save_log">Logları kaydet</string>
|
||||
<string name="log_saved">Loglar kaydedildi</string>
|
||||
<string name="send_log">Logları paylaş</string>
|
||||
<string name="settings_disable_su">Su uyumluluğunu devre dışı bırak</string>
|
||||
<string name="settings_disable_su_summary">Geçici olarak uygulamaların su komutu ile kök erişimi kazanmasını devre dışı bırakın (Zaten kök erişimi bulunan işlemler etkilenmez).</string>
|
||||
<string name="settings_language">Dil</string>
|
||||
@@ -223,14 +223,12 @@
|
||||
<string name="sucompat_disabled">SUCOMPAT DEVRE DIŞI</string>
|
||||
<string name="zygisk_required">Zygisk gerekli</string>
|
||||
<string name="zygisk_status">Zygisk enjeksiyonu</string>
|
||||
<string name="home_superuser_count_singular">Süper Kullanıcı</string>
|
||||
<string name="home_superuser_count_plural">Süper Kullanıcılar</string>
|
||||
<string name="home_superuser_count_singular">Superuser</string>
|
||||
<string name="home_superuser_count_plural">Superusers</string>
|
||||
<string name="home_module_count_singular">Modül</string>
|
||||
<string name="home_module_count_plural">Modüller</string>
|
||||
<string name="module_backup_message">Şu anda kurulu olan modülleri yedekleyin.</string>
|
||||
<string name="module_sort_enabled_first">Sırala (Önce etkin)</string>
|
||||
<string name="module_sort_action_first">Sırala (Önce eylem)</string>
|
||||
<string name="module_sort_enabled_first">Sırala (Önce Etkin)</string>
|
||||
<string name="module_sort_action_first">Sırala (Önce Eylem)</string>
|
||||
<string name="module_sort_webui_first">Sırala (Önce WebUI)</string>
|
||||
<string name="settings_global_namespace_mode">Küresel Ad Alanı Modu</string>
|
||||
<string name="settings_global_namespace_mode_summary">Tüm kök oturumları genel bağlama ad alanını kullanır</string>
|
||||
</resources>
|
||||
|
||||
@@ -231,6 +231,4 @@
|
||||
<string name="module_sort_enabled_first">За статусом (Спочатку включені)</string>
|
||||
<string name="module_sort_action_first">За статусом (Спочатку зі скриптом)</string>
|
||||
<string name="module_sort_webui_first">За статусом (Спочатку з WebUI)</string>
|
||||
<string name="settings_global_namespace_mode">Загальний простір імен</string>
|
||||
<string name="settings_global_namespace_mode_summary">Усі сесії користувача root будуть використовувати спільний простір імен</string>
|
||||
</resources>
|
||||
|
||||
@@ -231,6 +231,4 @@
|
||||
<string name="module_sort_enabled_first">Sắp xếp (Bật trước)</string>
|
||||
<string name="module_sort_action_first">Sắp xếp (Khởi chạy trước)</string>
|
||||
<string name="module_sort_webui_first">Sắp xếp (WebUI trước)</string>
|
||||
<string name="settings_global_namespace_mode">Chế độ Namespace chung</string>
|
||||
<string name="settings_global_namespace_mode_summary">Tất cả các phiên root đều sử dụng mount namespace chung</string>
|
||||
</resources>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<string name="lkm_mode_deprecated">LKM 模式已弃用!</string>
|
||||
<string name="lkm_alternative_suggestion">安装 GKI 内核或集成 KernelSU 到你的设备。</string>
|
||||
<string name="home_working">工作中</string>
|
||||
<string name="home_working_version">版本: %d</string>
|
||||
<string name="home_working_version">版本:%d</string>
|
||||
<string name="home_module_update_count">%d 个模块可更新!</string>
|
||||
<string name="home_failure">无法在内核中找到 KernelSU Next v2 签名![ !KSU_NEXT || != size/hash ]</string>
|
||||
<string name="home_failure_tip">请让你的内核开发人员集成 KernelSU Next!</string>
|
||||
@@ -26,27 +26,27 @@
|
||||
<string name="enabled">已启用</string>
|
||||
<string name="disabled">已禁用</string>
|
||||
<string name="susfs_supported">支持</string>
|
||||
<string name="home_susfs">SuSFS: %s</string>
|
||||
<string name="home_susfs">SuSFS:%s</string>
|
||||
<string name="home_susfs_version">SuSFS 版本</string>
|
||||
<string name="home_susfs_sus_su">SuS SU</string>
|
||||
<string name="home_android">Android 版本</string>
|
||||
<string name="home_manager_version">管理器版本</string>
|
||||
<string name="home_abi">ABI 类型</string>
|
||||
<string name="home_abi">接口</string>
|
||||
<string name="home_selinux_status">SELinux 状态</string>
|
||||
<string name="selinux_status_disabled">禁用</string>
|
||||
<string name="selinux_status_enforcing">严格模式</string>
|
||||
<string name="selinux_status_permissive">宽容模式</string>
|
||||
<string name="selinux_status_unknown">未知</string>
|
||||
<string name="superuser">超级用户</string>
|
||||
<string name="module_failed_to_enable">无法启用模块: %s</string>
|
||||
<string name="module_failed_to_disable">无法禁用模块: %s</string>
|
||||
<string name="module_failed_to_enable">启用模块失败:%s</string>
|
||||
<string name="module_failed_to_disable">禁用模块失败:%s</string>
|
||||
<string name="module_empty">未安装任何模块</string>
|
||||
<string name="module">模块</string>
|
||||
<string name="module_install_prompt_with_name">将安装以下模块: %1$s</string>
|
||||
<string name="module_sort_a_to_z">排序 (A -> Z)</string>
|
||||
<string name="module_sort_z_to_a">排序 (Z -> A)</string>
|
||||
<string name="module_size_low_to_high">排序 (按模块从小到大)</string>
|
||||
<string name="module_size_high_to_low">排序 (按模块从大到小)</string>
|
||||
<string name="module_install_prompt_with_name">将安装以下模块:%1$s</string>
|
||||
<string name="module_sort_a_to_z">按 A - Z 排序</string>
|
||||
<string name="module_sort_z_to_a">按 Z - A 排序</string>
|
||||
<string name="module_size_low_to_high">按模块大小正序排序</string>
|
||||
<string name="module_size_high_to_low">按模块大小倒序排序</string>
|
||||
<string name="uninstall">卸载</string>
|
||||
<string name="restore">还原</string>
|
||||
<string name="module_install">安装</string>
|
||||
@@ -62,10 +62,10 @@
|
||||
<string name="about">关于</string>
|
||||
<string name="module_uninstall_confirm">确定要卸载模块 %s 吗?</string>
|
||||
<string name="module_uninstall_success">已卸载 %s</string>
|
||||
<string name="module_uninstall_failed">卸载失败: %s</string>
|
||||
<string name="module_uninstall_failed">卸载失败:%s</string>
|
||||
<string name="module_restore_confirm">确定要还原模块 %s 吗?</string>
|
||||
<string name="module_restore_success">已还原 %s</string>
|
||||
<string name="module_restore_failed">恢复失败: %s</string>
|
||||
<string name="module_restore_failed">恢复失败:%s</string>
|
||||
<string name="module_version">版本</string>
|
||||
<string name="module_author">作者</string>
|
||||
<string name="module_id">模块标识</string>
|
||||
@@ -82,7 +82,7 @@
|
||||
<string name="safe_mode">安全模式</string>
|
||||
<string name="reboot_to_apply">重启生效</string>
|
||||
<string name="module_magisk_conflict">由于与 Magisk 冲突,模块系统不可用!</string>
|
||||
<string name="home_mount_system">挂载系统</string>
|
||||
<string name="home_mount_system">模块系统</string>
|
||||
<string name="home_magic_mount">Magic Mount</string>
|
||||
<string name="home_overlayfs_mount">OverlayFS</string>
|
||||
<string name="unavailable">不可用</string>
|
||||
@@ -103,10 +103,10 @@
|
||||
<string name="proceed">继续</string>
|
||||
<string name="cancel">取消</string>
|
||||
<string name="later">稍后</string>
|
||||
<string name="lkm_warning_message">LKM 补丁依赖于闭源组件。是否继续?</string>
|
||||
<string name="home_next_kernelsu">🔥 下一个版本</string>
|
||||
<string name="lkm_warning_message">此 LKM 补丁依赖于闭源组件,确认操作代表你知晓因继续使用该功能所导致的一切后果与开发团队无关。</string>
|
||||
<string name="home_next_kernelsu">🔥 Next 构建</string>
|
||||
<string name="home_next_kernelsu_repo">https://github.com/KernelSU-Next/KernelSU-Next</string>
|
||||
<string name="home_next_kernelsu_body">下一个实验性分支。请在 GitHub 上查看!</string>
|
||||
<string name="home_next_kernelsu_body">Next 实验性分支。在 GitHub 上查看!</string>
|
||||
<string name="home_experimental_kernelsu">⚠️ 实验性开发警告!</string>
|
||||
<string name="home_experimental_kernelsu_repo">127.0.0.1</string>
|
||||
<string name="home_experimental_kernelsu_body">KernelSU Next 是一个非官方版本,一直处于积极的实验开发阶段。它按原样提供,不保证稳定性、性能或可靠性。</string>
|
||||
@@ -139,9 +139,9 @@
|
||||
<string name="module_update">更新</string>
|
||||
<string name="module_update_available">更新可用</string>
|
||||
<string name="module_updated">重启以应用更新</string>
|
||||
<string name="module_downloading">正在下载模块: %s</string>
|
||||
<string name="module_start_downloading">开始下载: %s</string>
|
||||
<string name="new_version_available">发现新版本 %s,点击升级。</string>
|
||||
<string name="module_downloading">正在下载模块:%s</string>
|
||||
<string name="module_start_downloading">开始下载:%s</string>
|
||||
<string name="new_version_available">发现新版本:%s,点击升级。</string>
|
||||
<string name="launch_app">启动</string>
|
||||
<string name="close">关闭</string>
|
||||
<string name="force_stop_app">强行停止</string>
|
||||
@@ -174,7 +174,7 @@
|
||||
<string name="app_profile_template_sync">同步在线模板</string>
|
||||
<string name="app_profile_template_save_failed">模版保存失败</string>
|
||||
<string name="app_profile_template_import_empty">剪贴板为空!</string>
|
||||
<string name="module_changelog_failed">获取更新日志失败: %s</string>
|
||||
<string name="module_changelog_failed">获取更新日志失败:%s</string>
|
||||
<string name="settings_check_update">检查更新</string>
|
||||
<string name="settings_check_update_summary">在应用启动后自动检查是否有新版本。</string>
|
||||
<string name="grant_root_failed">获取 root 失败!</string>
|
||||
@@ -202,7 +202,7 @@
|
||||
<string name="flashing">刷写中</string>
|
||||
<string name="flash_success">刷写成功</string>
|
||||
<string name="flash_failed">刷写失败</string>
|
||||
<string name="selected_lkm">选择的 LKM: %s</string>
|
||||
<string name="selected_lkm">选择的 LKM:%s</string>
|
||||
<string name="save_log">保存日志</string>
|
||||
<string name="log_saved">日志已保存</string>
|
||||
<string name="send_log">分享日志</string>
|
||||
@@ -220,7 +220,7 @@
|
||||
<string name="use_webuix_eruda_summary">将调试控制台注入 WebUI X 以使调试更容易。需要启用 Web 调试。</string>
|
||||
<string name="customization">界面设置</string>
|
||||
<string name="developer">开发者选项</string>
|
||||
<string name="sucompat_disabled">SU 兼容已禁用</string>
|
||||
<string name="sucompat_disabled">SU 兼容被禁用</string>
|
||||
<string name="zygisk_required">需要 Zygisk</string>
|
||||
<string name="zygisk_status">Zygisk 注入</string>
|
||||
<string name="home_superuser_count_singular">超级用户</string>
|
||||
@@ -228,9 +228,7 @@
|
||||
<string name="home_module_count_singular">模块</string>
|
||||
<string name="home_module_count_plural">模块</string>
|
||||
<string name="module_backup_message">备份当前已安装的模块。</string>
|
||||
<string name="module_sort_enabled_first">排序 (已启用优先)</string>
|
||||
<string name="module_sort_action_first">排序 (可执行优先)</string>
|
||||
<string name="module_sort_webui_first">排序 (支持 WebUI 优先)</string>
|
||||
<string name="settings_global_namespace_mode">全局命名空间模式</string>
|
||||
<string name="settings_global_namespace_mode_summary">所有 Root 会话均使用全局挂载命名空间。</string>
|
||||
<string name="module_sort_enabled_first">按启用状态优先排序</string>
|
||||
<string name="module_sort_action_first">按支持执行脚本的模块优先排序</string>
|
||||
<string name="module_sort_webui_first">按拥有 WebUI 的模块优先排序</string>
|
||||
</resources>
|
||||
|
||||
@@ -229,8 +229,6 @@
|
||||
<string name="home_module_count_plural">模組</string>
|
||||
<string name="module_backup_message">備份當前已安裝的模組。</string>
|
||||
<string name="module_sort_enabled_first">依啟用狀態優先排序</string>
|
||||
<string name="module_sort_action_first">依支援執行優先排序</string>
|
||||
<string name="module_sort_webui_first">依具備 WebUI 優先排序</string>
|
||||
<string name="settings_global_namespace_mode">全域命名空間模式</string>
|
||||
<string name="settings_global_namespace_mode_summary">所有 Root 工作階段皆使用全域掛載命名空間</string>
|
||||
<string name="module_sort_action_first">依支援執行腳本的模組優先排序</string>
|
||||
<string name="module_sort_webui_first">依具備 WebUI 的模組優先排序</string>
|
||||
</resources>
|
||||
|
||||
@@ -231,6 +231,4 @@
|
||||
<string name="module_sort_enabled_first">Sort (Enabled first)</string>
|
||||
<string name="module_sort_action_first">Sort (Action first)</string>
|
||||
<string name="module_sort_webui_first">Sort (WebUI first)</string>
|
||||
<string name="settings_global_namespace_mode">Global Namespace Mode</string>
|
||||
<string name="settings_global_namespace_mode_summary">All root sessions use the global mount namespace</string>
|
||||
</resources>
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
|
||||
> gradle.properties
|
||||
|
||||
{
|
||||
echo 'android.experimental.enableNewResourceShrinker.preciseShrinking=true'
|
||||
echo 'android.enableAppCompileTimeRClass=true'
|
||||
echo 'android.useAndroidX=true'
|
||||
echo KEYSTORE_PASSWORD=$MY_KEYSTORE_PASSWORD
|
||||
echo KEY_ALIAS=$MY_KEY_ALIAS
|
||||
echo KEY_PASSWORD=$MY_KEY_PASSWORD
|
||||
echo KEYSTORE_FILE='key.jks'
|
||||
echo 'org.gradle.parallel=true'
|
||||
echo 'org.gradle.vfs.watch=true'
|
||||
echo 'org.gradle.jvmargs=-Xmx2048m'
|
||||
echo 'android.native.buildOutput=verbose'
|
||||
} >> gradle.properties
|
||||
|
||||
./gradlew clean assembleRelease
|
||||
|
||||
> gradle.properties
|
||||
|
||||
{
|
||||
echo 'android.experimental.enableNewResourceShrinker.preciseShrinking=true'
|
||||
echo 'android.enableAppCompileTimeRClass=true'
|
||||
echo 'android.useAndroidX=true'
|
||||
} >> gradle.properties
|
||||
@@ -31,9 +31,4 @@ if [ -f "./build.gradle.kts" ]; then
|
||||
sed -i 's/\(versionName = managerVersionName\)/versionName = managerVersionNameSpoofed/' ./build.gradle.kts
|
||||
fi
|
||||
|
||||
if [ -f "./app/build.gradle.kts" ]; then
|
||||
sed -i '/val managerVersionName:/a val managerVersionNameSpoofed = "${managerVersionName}-spoofed"' ./app/build.gradle.kts
|
||||
sed -i 's/outputFileName = "KernelSU_Next_${managerVersionName}_${managerVersionCode}-\$name.apk"/outputFileName = "KernelSU_Next_${managerVersionNameSpoofed}_${managerVersionCode}-\$name.apk"/' ./app/build.gradle.kts
|
||||
fi
|
||||
|
||||
echo "Done."
|
||||
|
||||
@@ -310,7 +310,7 @@ pub fn restore(
|
||||
|
||||
let skip_init = kmi.starts_with("android12-");
|
||||
|
||||
let (bootimage, bootdevice) = find_boot_image(&image, skip_init, false, false, workdir, &magiskboot)?;
|
||||
let (bootimage, bootdevice) = find_boot_image(&image, skip_init, false, false, workdir)?;
|
||||
|
||||
println!("- Unpacking boot image");
|
||||
let status = Command::new(&magiskboot)
|
||||
@@ -323,7 +323,6 @@ pub fn restore(
|
||||
ensure!(status.success(), "magiskboot unpack failed");
|
||||
|
||||
let no_ramdisk = !workdir.join("ramdisk.cpio").exists();
|
||||
// let no_ramdisk = !workdir.join("ramdisk.cpio").exists();
|
||||
let no_vendor_init_boot = !workdir
|
||||
.join("vendor_ramdisk")
|
||||
.join("init_boot.cpio")
|
||||
@@ -371,78 +370,41 @@ pub fn restore(
|
||||
}
|
||||
|
||||
if new_boot.is_none() {
|
||||
if !no_ramdisk {
|
||||
println!("- Restoring /ramdisk");
|
||||
println!("- Removing /ramdisk/kernelsu.ko");
|
||||
// remove kernelsu.ko
|
||||
do_cpio_cmd(&magiskboot, workdir, "rm kernelsu.ko")?;
|
||||
if no_ramdisk {
|
||||
if !no_vendor_init_boot {
|
||||
// vendor init_boot restore
|
||||
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "rm kernelsu.ko")?;
|
||||
|
||||
// if init.real exists, restore it
|
||||
println!("- Checking if init.real exists");
|
||||
let status = do_cpio_cmd(&magiskboot, workdir, "exists init.real").is_ok();
|
||||
if status {
|
||||
println!("- /ramdisk/init.real exists");
|
||||
println!("- Restoring /ramdisk/init.real to init");
|
||||
do_cpio_cmd(&magiskboot, workdir, "mv init.real init")?;
|
||||
} else {
|
||||
println!("- /ramdisk/init.real not found");
|
||||
println!("- Removing ramdisk.cpio");
|
||||
let ramdisk = workdir.join("ramdisk.cpio");
|
||||
std::fs::remove_file(ramdisk)?;
|
||||
}
|
||||
} else if !no_vendor_init_boot {
|
||||
println!("- Restoring /vendor_ramdisk/init_boot");
|
||||
println!("- Removing /vendor_ramdisk/init_boot/kernelsu.ko");
|
||||
// vendor init_boot restore
|
||||
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "rm kernelsu.ko")?;
|
||||
let status =
|
||||
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "exists init.real").is_ok();
|
||||
if status {
|
||||
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "mv init.real init")?;
|
||||
} else {
|
||||
let vendor_init_boot = workdir.join("vendor_ramdisk").join("init_boot.cpio");
|
||||
std::fs::remove_file(vendor_init_boot)?;
|
||||
}
|
||||
} else if !no_vendor_ramdisk {
|
||||
// vendor ramdisk restore
|
||||
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "rm kernelsu.ko")?;
|
||||
|
||||
println!("- Checking if init.real exists");
|
||||
let status =
|
||||
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "exists init.real").is_ok();
|
||||
if status {
|
||||
println!("- /vendor_ramdisk/init_boot/init.real exists");
|
||||
println!("- Restoring /vendor_ramdisk/init_boot/init.real to init");
|
||||
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "mv init.real init")?;
|
||||
} else {
|
||||
println!("- /vendor_ramdisk/init_boot/init.real not found");
|
||||
println!("- Removing vendor_ramdisk/init_boot.cpio");
|
||||
let vendor_init_boot = workdir.join("vendor_ramdisk").join("init_boot.cpio");
|
||||
std::fs::remove_file(vendor_init_boot)?;
|
||||
}
|
||||
} else if !no_vendor_ramdisk {
|
||||
println!("- Restoring /vendor_ramdisk/ramdisk");
|
||||
println!("- Removing /vendor_ramdisk/ramdisk/kernelsu.ko");
|
||||
// vendor ramdisk restore
|
||||
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "rm kernelsu.ko")?;
|
||||
|
||||
let status =
|
||||
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "exists init.real").is_ok();
|
||||
if status {
|
||||
println!("- /vendor_ramdisk/ramdisk/init.real exists");
|
||||
println!("- Restoring /vendor_ramdisk/ramdisk/init.real to init");
|
||||
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "mv init.real init")?;
|
||||
} else {
|
||||
println!("- /vendor_ramdisk/ramdisk/init.real not found");
|
||||
println!("- Removing vendor_ramdisk/ramdisk.cpio");
|
||||
let vendor_ramdisk = workdir.join("vendor_ramdisk").join("ramdisk.cpio");
|
||||
std::fs::remove_file(vendor_ramdisk)?;
|
||||
let status =
|
||||
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "exists init.real").is_ok();
|
||||
if status {
|
||||
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "mv init.real init")?;
|
||||
} else {
|
||||
let vendor_ramdisk = workdir.join("vendor_ramdisk").join("ramdisk.cpio");
|
||||
std::fs::remove_file(vendor_ramdisk)?;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
println!("- Restoring /ramdisk");
|
||||
println!("- Removing /ramdisk/kernelsu.ko");
|
||||
// remove kernelsu.ko
|
||||
do_cpio_cmd(&magiskboot, workdir, "rm kernelsu.ko")?;
|
||||
|
||||
// if init.real exists, restore it
|
||||
println!("- Checking if init.real exists");
|
||||
let status = do_cpio_cmd(&magiskboot, workdir, "exists init.real").is_ok();
|
||||
if status {
|
||||
println!("- /ramdisk/init.real exists");
|
||||
println!("- Restoring /ramdisk/init.real to init");
|
||||
do_cpio_cmd(&magiskboot, workdir, "mv init.real init")?;
|
||||
} else {
|
||||
println!("- /ramdisk/init.real not found");
|
||||
println!("- Removing ramdisk.cpio");
|
||||
let ramdisk = workdir.join("ramdisk.cpio");
|
||||
std::fs::remove_file(ramdisk)?;
|
||||
}
|
||||
@@ -574,7 +536,7 @@ fn do_patch(
|
||||
let skip_init = kmi.starts_with("android12-");
|
||||
|
||||
let (bootimage, bootdevice) =
|
||||
find_boot_image(&image, skip_init, ota, is_replace_kernel, workdir, &magiskboot)?;
|
||||
find_boot_image(&image, skip_init, ota, is_replace_kernel, workdir)?;
|
||||
|
||||
let bootimage = bootimage.display().to_string();
|
||||
|
||||
@@ -622,8 +584,7 @@ fn do_patch(
|
||||
.exists();
|
||||
let no_vendor_ramdisk = !workdir.join("vendor_ramdisk").join("ramdisk.cpio").exists();
|
||||
if no_ramdisk && no_vendor_init_boot && no_vendor_ramdisk {
|
||||
println!("- No compatible ramdisk found.");
|
||||
println!("- Will create our own ramdisk!");
|
||||
bail!("No compatible ramdisk found.");
|
||||
}
|
||||
let is_magisk_patched = is_magisk_patched(&magiskboot, workdir)?;
|
||||
let is_magisk_patched_vendor_init_boot =
|
||||
@@ -644,59 +605,43 @@ fn do_patch(
|
||||
is_kernelsu_patched_vendor_ramdisk(&magiskboot, workdir)?;
|
||||
|
||||
let mut need_backup = false;
|
||||
if (no_ramdisk && !is_kernelsu_patched_vendor_init_boot)
|
||||
if !is_kernelsu_patched
|
||||
|| (no_ramdisk && !is_kernelsu_patched_vendor_init_boot)
|
||||
|| (no_ramdisk && no_vendor_init_boot && !is_kernelsu_patched_vendor_ramdisk)
|
||||
|| !is_kernelsu_patched
|
||||
{
|
||||
if !no_ramdisk {
|
||||
println!("- Checking if /ramdisk/init exists");
|
||||
let status = do_cpio_cmd(&magiskboot, workdir, "exists init");
|
||||
if status.is_ok() {
|
||||
println!("- Backing up ramdisk/init");
|
||||
do_cpio_cmd(&magiskboot, workdir, "mv init init.real")?;
|
||||
if no_ramdisk {
|
||||
if !no_vendor_init_boot {
|
||||
// vendor init_boot patching
|
||||
let status = do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "exists init");
|
||||
if status.is_ok() {
|
||||
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "mv init init.real")?;
|
||||
}
|
||||
} else if !no_vendor_ramdisk {
|
||||
// vendor ramdisk patching
|
||||
let status = do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "exists init");
|
||||
if status.is_ok() {
|
||||
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "mv init init.real")?;
|
||||
}
|
||||
}
|
||||
need_backup = flash;
|
||||
} else if !no_vendor_init_boot {
|
||||
println!("- Checking if /vendor_ramdisk/init_boot/init exists");
|
||||
let status = do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "exists init");
|
||||
if status.is_ok() {
|
||||
println!("- Backing up vendor_ramdisk/init_boot/init");
|
||||
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "mv init init.real")?;
|
||||
}
|
||||
need_backup = flash;
|
||||
} else if !no_vendor_ramdisk {
|
||||
println!("- Checking if /vendor_ramdisk/ramdisk/init exists");
|
||||
let status = do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "exists init");
|
||||
if status.is_ok() {
|
||||
println!("- Backing up vendor_ramdisk/ramdisk/init");
|
||||
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "mv init init.real")?;
|
||||
}
|
||||
need_backup = flash;
|
||||
} else {
|
||||
println!("- Checking if /ramdisk/init exists");
|
||||
// kernelsu.ko is not exist, backup init if necessary
|
||||
let status = do_cpio_cmd(&magiskboot, workdir, "exists init");
|
||||
if status.is_ok() {
|
||||
println!("- Backing up ramdisk/init");
|
||||
do_cpio_cmd(&magiskboot, workdir, "mv init init.real")?;
|
||||
}
|
||||
need_backup = flash;
|
||||
}
|
||||
}
|
||||
|
||||
if !no_ramdisk {
|
||||
println!("- Patching /ramdisk");
|
||||
do_cpio_cmd(&magiskboot, workdir, "add 0755 init init")?;
|
||||
do_cpio_cmd(&magiskboot, workdir, "add 0755 kernelsu.ko kernelsu.ko")?;
|
||||
} else if !no_vendor_init_boot {
|
||||
println!("- Patching /vendor_ramdisk/init_boot");
|
||||
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "add 0755 init init")?;
|
||||
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "add 0755 kernelsu.ko kernelsu.ko")?;
|
||||
} else if !no_vendor_ramdisk {
|
||||
println!("- Patching /vendor_ramdisk/ramdisk");
|
||||
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "add 0750 init init")?;
|
||||
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "add 0750 kernelsu.ko kernelsu.ko")?;
|
||||
if no_ramdisk {
|
||||
if !no_vendor_init_boot {
|
||||
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "add 0755 init init")?;
|
||||
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "add 0755 kernelsu.ko kernelsu.ko")?;
|
||||
} else if !no_vendor_ramdisk {
|
||||
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "add 0750 init init")?;
|
||||
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "add 0750 kernelsu.ko kernelsu.ko")?;
|
||||
}
|
||||
} else {
|
||||
println!("- Creating and Patching /ramdisk");
|
||||
do_cpio_cmd(&magiskboot, workdir, "add 0755 init init")?;
|
||||
do_cpio_cmd(&magiskboot, workdir, "add 0755 kernelsu.ko kernelsu.ko")?;
|
||||
}
|
||||
@@ -855,17 +800,16 @@ fn find_boot_image(
|
||||
ota: bool,
|
||||
is_replace_kernel: bool,
|
||||
workdir: &Path,
|
||||
magiskboot: &Path,
|
||||
) -> Result<(PathBuf, Option<String>)> {
|
||||
let bootimage;
|
||||
let mut bootdevice = None;
|
||||
if let Some(ref image) = *image {
|
||||
ensure!(image.exists(), "- Boot image not found");
|
||||
ensure!(image.exists(), "boot image not found");
|
||||
bootimage = std::fs::canonicalize(image)?;
|
||||
} else {
|
||||
if cfg!(not(target_os = "android")) {
|
||||
println!("- Current OS is not android, refusing auto bootimage/bootdevice detection");
|
||||
bail!("- Please specify a boot image");
|
||||
bail!("Please specify a boot image");
|
||||
}
|
||||
let mut slot_suffix =
|
||||
utils::getprop("ro.boot.slot_suffix").unwrap_or_else(|| String::from(""));
|
||||
@@ -878,104 +822,27 @@ fn find_boot_image(
|
||||
}
|
||||
};
|
||||
|
||||
let init_boot_partition = format!("/dev/block/by-name/init_boot{slot_suffix}");
|
||||
let vendor_boot_partition = format!("/dev/block/by-name/vendor_boot{slot_suffix}");
|
||||
let boot_partition = format!("/dev/block/by-name/boot{slot_suffix}");
|
||||
let init_boot_exist =
|
||||
Path::new(&format!("/dev/block/by-name/init_boot{slot_suffix}")).exists();
|
||||
let vendor_boot_exist =
|
||||
Path::new(&format!("/dev/block/by-name/vendor_boot{slot_suffix}")).exists();
|
||||
let boot_partition = if !is_replace_kernel && init_boot_exist && !skip_init {
|
||||
format!("/dev/block/by-name/init_boot{slot_suffix}")
|
||||
} else if !is_replace_kernel && vendor_boot_exist && !skip_init {
|
||||
format!("/dev/block/by-name/vendor_boot{slot_suffix}")
|
||||
} else {
|
||||
format!("/dev/block/by-name/boot{slot_suffix}")
|
||||
};
|
||||
|
||||
let init_boot_exist = Path::new(&init_boot_partition).exists();
|
||||
let vendor_boot_exist = Path::new(&vendor_boot_partition).exists();
|
||||
|
||||
// helper: unpack a partition and check for a ramdisk and init
|
||||
fn unpack_and_check_init(
|
||||
magiskboot: &Path,
|
||||
workdir: &Path,
|
||||
partition: &str,
|
||||
ramdisk_cpio: &str,
|
||||
) -> Result<bool> {
|
||||
let tmp_img = workdir.join("probe.img");
|
||||
dd(partition, &tmp_img)?;
|
||||
let status = Command::new(magiskboot)
|
||||
.current_dir(workdir)
|
||||
.stdout(Stdio::null())
|
||||
.stderr(Stdio::null())
|
||||
.arg("unpack")
|
||||
.arg(&tmp_img)
|
||||
.status()?;
|
||||
if !status.success() {
|
||||
let _ = std::fs::remove_file(&tmp_img);
|
||||
return Ok(false);
|
||||
}
|
||||
let ramdisk_path = workdir.join(ramdisk_cpio);
|
||||
let has_init = if ramdisk_path.exists() {
|
||||
Command::new(magiskboot)
|
||||
.current_dir(workdir)
|
||||
.stdout(Stdio::null())
|
||||
.stderr(Stdio::null())
|
||||
.arg("cpio")
|
||||
.arg(ramdisk_cpio)
|
||||
.arg("exists init")
|
||||
.status()
|
||||
.map(|s| s.success())
|
||||
.unwrap_or(false)
|
||||
} else {
|
||||
false
|
||||
};
|
||||
// Clean up
|
||||
let _ = std::fs::remove_file(&tmp_img);
|
||||
let _ = std::fs::remove_file(workdir.join("ramdisk.cpio"));
|
||||
let _ = std::fs::remove_dir_all(workdir.join("vendor_ramdisk"));
|
||||
Ok(has_init)
|
||||
}
|
||||
|
||||
let mut selected_partition = &boot_partition;
|
||||
|
||||
if !is_replace_kernel && init_boot_exist && !skip_init {
|
||||
// try init_boot/ramdisk.cpio
|
||||
if unpack_and_check_init(magiskboot, workdir, &init_boot_partition, "ramdisk.cpio")? {
|
||||
println!("- Using init_boot partition (ramdisk.cpio).");
|
||||
selected_partition = &init_boot_partition;
|
||||
}
|
||||
}
|
||||
|
||||
// try vendor_boot/vendor_ramdisk/init_boot.cpio
|
||||
if selected_partition == &boot_partition && !is_replace_kernel && vendor_boot_exist && !skip_init {
|
||||
if unpack_and_check_init(
|
||||
magiskboot,
|
||||
workdir,
|
||||
&vendor_boot_partition,
|
||||
"vendor_ramdisk/init_boot.cpio",
|
||||
)? {
|
||||
println!("- Using vendor_boot partition (vendor_ramdisk/init_boot.cpio).");
|
||||
selected_partition = &vendor_boot_partition;
|
||||
}
|
||||
}
|
||||
|
||||
// try vendor_boot/vendor_ramdisk/ramdisk.cpio
|
||||
if selected_partition == &boot_partition && !is_replace_kernel && vendor_boot_exist && !skip_init {
|
||||
if unpack_and_check_init(
|
||||
magiskboot,
|
||||
workdir,
|
||||
&vendor_boot_partition,
|
||||
"vendor_ramdisk/ramdisk.cpio",
|
||||
)? {
|
||||
println!("- Using vendor_boot partition (vendor_ramdisk/ramdisk.cpio).");
|
||||
selected_partition = &vendor_boot_partition;
|
||||
}
|
||||
}
|
||||
|
||||
if selected_partition == &boot_partition {
|
||||
println!("- Using boot partition (ramdisk.cpio).");
|
||||
}
|
||||
|
||||
println!("- Bootdevice: {selected_partition}");
|
||||
println!("- Bootdevice: {boot_partition}");
|
||||
let tmp_boot_path = workdir.join("boot.img");
|
||||
|
||||
dd(selected_partition, &tmp_boot_path)?;
|
||||
dd(&boot_partition, &tmp_boot_path)?;
|
||||
|
||||
ensure!(tmp_boot_path.exists(), "- Tmp boot image not found");
|
||||
ensure!(tmp_boot_path.exists(), "boot image not found");
|
||||
|
||||
bootimage = tmp_boot_path;
|
||||
bootdevice = Some(selected_partition.to_string());
|
||||
bootdevice = Some(boot_partition);
|
||||
};
|
||||
Ok((bootimage, bootdevice))
|
||||
}
|
||||
|
||||
@@ -44,5 +44,3 @@ pub const NO_TMPFS_PATH: &str = concatcp!(WORKING_DIR, ".notmpfs");
|
||||
pub const NO_MOUNT_PATH: &str = concatcp!(WORKING_DIR, ".nomount");
|
||||
|
||||
pub const MOUNT_SYSTEM: &str = "Magic_Mount";
|
||||
|
||||
pub const GLOBAL_NAMESPACE_FILE: &str = concatcp!(WORKING_DIR, ".global_mnt");
|
||||
|
||||
@@ -261,9 +261,7 @@ pub fn root_shell() -> Result<()> {
|
||||
|
||||
// switch to global mount namespace
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
let global_namespace_enable =
|
||||
std::fs::read_to_string(defs::GLOBAL_NAMESPACE_FILE).unwrap_or("0".to_string());
|
||||
if global_namespace_enable.trim() == "1" || mount_master {
|
||||
if mount_master {
|
||||
let _ = utils::switch_mnt_ns(1);
|
||||
}
|
||||
|
||||
|
||||
@@ -310,7 +310,7 @@ pub fn restore(
|
||||
|
||||
let skip_init = kmi.starts_with("android12-");
|
||||
|
||||
let (bootimage, bootdevice) = find_boot_image(&image, skip_init, false, false, workdir, &magiskboot)?;
|
||||
let (bootimage, bootdevice) = find_boot_image(&image, skip_init, false, false, workdir)?;
|
||||
|
||||
println!("- Unpacking boot image");
|
||||
let status = Command::new(&magiskboot)
|
||||
@@ -323,7 +323,6 @@ pub fn restore(
|
||||
ensure!(status.success(), "magiskboot unpack failed");
|
||||
|
||||
let no_ramdisk = !workdir.join("ramdisk.cpio").exists();
|
||||
// let no_ramdisk = !workdir.join("ramdisk.cpio").exists();
|
||||
let no_vendor_init_boot = !workdir
|
||||
.join("vendor_ramdisk")
|
||||
.join("init_boot.cpio")
|
||||
@@ -371,78 +370,41 @@ pub fn restore(
|
||||
}
|
||||
|
||||
if new_boot.is_none() {
|
||||
if !no_ramdisk {
|
||||
println!("- Restoring /ramdisk");
|
||||
println!("- Removing /ramdisk/kernelsu.ko");
|
||||
// remove kernelsu.ko
|
||||
do_cpio_cmd(&magiskboot, workdir, "rm kernelsu.ko")?;
|
||||
if no_ramdisk {
|
||||
if !no_vendor_init_boot {
|
||||
// vendor init_boot restore
|
||||
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "rm kernelsu.ko")?;
|
||||
|
||||
// if init.real exists, restore it
|
||||
println!("- Checking if init.real exists");
|
||||
let status = do_cpio_cmd(&magiskboot, workdir, "exists init.real").is_ok();
|
||||
if status {
|
||||
println!("- /ramdisk/init.real exists");
|
||||
println!("- Restoring /ramdisk/init.real to init");
|
||||
do_cpio_cmd(&magiskboot, workdir, "mv init.real init")?;
|
||||
} else {
|
||||
println!("- /ramdisk/init.real not found");
|
||||
println!("- Removing ramdisk.cpio");
|
||||
let ramdisk = workdir.join("ramdisk.cpio");
|
||||
std::fs::remove_file(ramdisk)?;
|
||||
}
|
||||
} else if !no_vendor_init_boot {
|
||||
println!("- Restoring /vendor_ramdisk/init_boot");
|
||||
println!("- Removing /vendor_ramdisk/init_boot/kernelsu.ko");
|
||||
// vendor init_boot restore
|
||||
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "rm kernelsu.ko")?;
|
||||
let status =
|
||||
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "exists init.real").is_ok();
|
||||
if status {
|
||||
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "mv init.real init")?;
|
||||
} else {
|
||||
let vendor_init_boot = workdir.join("vendor_ramdisk").join("init_boot.cpio");
|
||||
std::fs::remove_file(vendor_init_boot)?;
|
||||
}
|
||||
} else if !no_vendor_ramdisk {
|
||||
// vendor ramdisk restore
|
||||
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "rm kernelsu.ko")?;
|
||||
|
||||
println!("- Checking if init.real exists");
|
||||
let status =
|
||||
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "exists init.real").is_ok();
|
||||
if status {
|
||||
println!("- /vendor_ramdisk/init_boot/init.real exists");
|
||||
println!("- Restoring /vendor_ramdisk/init_boot/init.real to init");
|
||||
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "mv init.real init")?;
|
||||
} else {
|
||||
println!("- /vendor_ramdisk/init_boot/init.real not found");
|
||||
println!("- Removing vendor_ramdisk/init_boot.cpio");
|
||||
let vendor_init_boot = workdir.join("vendor_ramdisk").join("init_boot.cpio");
|
||||
std::fs::remove_file(vendor_init_boot)?;
|
||||
}
|
||||
} else if !no_vendor_ramdisk {
|
||||
println!("- Restoring /vendor_ramdisk/ramdisk");
|
||||
println!("- Removing /vendor_ramdisk/ramdisk/kernelsu.ko");
|
||||
// vendor ramdisk restore
|
||||
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "rm kernelsu.ko")?;
|
||||
|
||||
let status =
|
||||
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "exists init.real").is_ok();
|
||||
if status {
|
||||
println!("- /vendor_ramdisk/ramdisk/init.real exists");
|
||||
println!("- Restoring /vendor_ramdisk/ramdisk/init.real to init");
|
||||
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "mv init.real init")?;
|
||||
} else {
|
||||
println!("- /vendor_ramdisk/ramdisk/init.real not found");
|
||||
println!("- Removing vendor_ramdisk/ramdisk.cpio");
|
||||
let vendor_ramdisk = workdir.join("vendor_ramdisk").join("ramdisk.cpio");
|
||||
std::fs::remove_file(vendor_ramdisk)?;
|
||||
let status =
|
||||
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "exists init.real").is_ok();
|
||||
if status {
|
||||
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "mv init.real init")?;
|
||||
} else {
|
||||
let vendor_ramdisk = workdir.join("vendor_ramdisk").join("ramdisk.cpio");
|
||||
std::fs::remove_file(vendor_ramdisk)?;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
println!("- Restoring /ramdisk");
|
||||
println!("- Removing /ramdisk/kernelsu.ko");
|
||||
// remove kernelsu.ko
|
||||
do_cpio_cmd(&magiskboot, workdir, "rm kernelsu.ko")?;
|
||||
|
||||
// if init.real exists, restore it
|
||||
println!("- Checking if init.real exists");
|
||||
let status = do_cpio_cmd(&magiskboot, workdir, "exists init.real").is_ok();
|
||||
if status {
|
||||
println!("- /ramdisk/init.real exists");
|
||||
println!("- Restoring /ramdisk/init.real to init");
|
||||
do_cpio_cmd(&magiskboot, workdir, "mv init.real init")?;
|
||||
} else {
|
||||
println!("- /ramdisk/init.real not found");
|
||||
println!("- Removing ramdisk.cpio");
|
||||
let ramdisk = workdir.join("ramdisk.cpio");
|
||||
std::fs::remove_file(ramdisk)?;
|
||||
}
|
||||
@@ -574,7 +536,7 @@ fn do_patch(
|
||||
let skip_init = kmi.starts_with("android12-");
|
||||
|
||||
let (bootimage, bootdevice) =
|
||||
find_boot_image(&image, skip_init, ota, is_replace_kernel, workdir, &magiskboot)?;
|
||||
find_boot_image(&image, skip_init, ota, is_replace_kernel, workdir)?;
|
||||
|
||||
let bootimage = bootimage.display().to_string();
|
||||
|
||||
@@ -622,8 +584,7 @@ fn do_patch(
|
||||
.exists();
|
||||
let no_vendor_ramdisk = !workdir.join("vendor_ramdisk").join("ramdisk.cpio").exists();
|
||||
if no_ramdisk && no_vendor_init_boot && no_vendor_ramdisk {
|
||||
println!("- No compatible ramdisk found.");
|
||||
println!("- Will create our own ramdisk!");
|
||||
bail!("No compatible ramdisk found.");
|
||||
}
|
||||
let is_magisk_patched = is_magisk_patched(&magiskboot, workdir)?;
|
||||
let is_magisk_patched_vendor_init_boot =
|
||||
@@ -644,59 +605,43 @@ fn do_patch(
|
||||
is_kernelsu_patched_vendor_ramdisk(&magiskboot, workdir)?;
|
||||
|
||||
let mut need_backup = false;
|
||||
if (no_ramdisk && !is_kernelsu_patched_vendor_init_boot)
|
||||
if !is_kernelsu_patched
|
||||
|| (no_ramdisk && !is_kernelsu_patched_vendor_init_boot)
|
||||
|| (no_ramdisk && no_vendor_init_boot && !is_kernelsu_patched_vendor_ramdisk)
|
||||
|| !is_kernelsu_patched
|
||||
{
|
||||
if !no_ramdisk {
|
||||
println!("- Checking if /ramdisk/init exists");
|
||||
let status = do_cpio_cmd(&magiskboot, workdir, "exists init");
|
||||
if status.is_ok() {
|
||||
println!("- Backing up ramdisk/init");
|
||||
do_cpio_cmd(&magiskboot, workdir, "mv init init.real")?;
|
||||
if no_ramdisk {
|
||||
if !no_vendor_init_boot {
|
||||
// vendor init_boot patching
|
||||
let status = do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "exists init");
|
||||
if status.is_ok() {
|
||||
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "mv init init.real")?;
|
||||
}
|
||||
} else if !no_vendor_ramdisk {
|
||||
// vendor ramdisk patching
|
||||
let status = do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "exists init");
|
||||
if status.is_ok() {
|
||||
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "mv init init.real")?;
|
||||
}
|
||||
}
|
||||
need_backup = flash;
|
||||
} else if !no_vendor_init_boot {
|
||||
println!("- Checking if /vendor_ramdisk/init_boot/init exists");
|
||||
let status = do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "exists init");
|
||||
if status.is_ok() {
|
||||
println!("- Backing up vendor_ramdisk/init_boot/init");
|
||||
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "mv init init.real")?;
|
||||
}
|
||||
need_backup = flash;
|
||||
} else if !no_vendor_ramdisk {
|
||||
println!("- Checking if /vendor_ramdisk/ramdisk/init exists");
|
||||
let status = do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "exists init");
|
||||
if status.is_ok() {
|
||||
println!("- Backing up vendor_ramdisk/ramdisk/init");
|
||||
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "mv init init.real")?;
|
||||
}
|
||||
need_backup = flash;
|
||||
} else {
|
||||
println!("- Checking if /ramdisk/init exists");
|
||||
// kernelsu.ko is not exist, backup init if necessary
|
||||
let status = do_cpio_cmd(&magiskboot, workdir, "exists init");
|
||||
if status.is_ok() {
|
||||
println!("- Backing up ramdisk/init");
|
||||
do_cpio_cmd(&magiskboot, workdir, "mv init init.real")?;
|
||||
}
|
||||
need_backup = flash;
|
||||
}
|
||||
}
|
||||
|
||||
if !no_ramdisk {
|
||||
println!("- Patching /ramdisk");
|
||||
do_cpio_cmd(&magiskboot, workdir, "add 0755 init init")?;
|
||||
do_cpio_cmd(&magiskboot, workdir, "add 0755 kernelsu.ko kernelsu.ko")?;
|
||||
} else if !no_vendor_init_boot {
|
||||
println!("- Patching /vendor_ramdisk/init_boot");
|
||||
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "add 0755 init init")?;
|
||||
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "add 0755 kernelsu.ko kernelsu.ko")?;
|
||||
} else if !no_vendor_ramdisk {
|
||||
println!("- Patching /vendor_ramdisk/ramdisk");
|
||||
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "add 0750 init init")?;
|
||||
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "add 0750 kernelsu.ko kernelsu.ko")?;
|
||||
if no_ramdisk {
|
||||
if !no_vendor_init_boot {
|
||||
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "add 0755 init init")?;
|
||||
do_vendor_init_boot_cpio_cmd(&magiskboot, workdir, "add 0755 kernelsu.ko kernelsu.ko")?;
|
||||
} else if !no_vendor_ramdisk {
|
||||
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "add 0750 init init")?;
|
||||
do_vendor_ramdisk_cpio_cmd(&magiskboot, workdir, "add 0750 kernelsu.ko kernelsu.ko")?;
|
||||
}
|
||||
} else {
|
||||
println!("- Creating and Patching /ramdisk");
|
||||
do_cpio_cmd(&magiskboot, workdir, "add 0755 init init")?;
|
||||
do_cpio_cmd(&magiskboot, workdir, "add 0755 kernelsu.ko kernelsu.ko")?;
|
||||
}
|
||||
@@ -855,17 +800,16 @@ fn find_boot_image(
|
||||
ota: bool,
|
||||
is_replace_kernel: bool,
|
||||
workdir: &Path,
|
||||
magiskboot: &Path,
|
||||
) -> Result<(PathBuf, Option<String>)> {
|
||||
let bootimage;
|
||||
let mut bootdevice = None;
|
||||
if let Some(ref image) = *image {
|
||||
ensure!(image.exists(), "- Boot image not found");
|
||||
ensure!(image.exists(), "boot image not found");
|
||||
bootimage = std::fs::canonicalize(image)?;
|
||||
} else {
|
||||
if cfg!(not(target_os = "android")) {
|
||||
println!("- Current OS is not android, refusing auto bootimage/bootdevice detection");
|
||||
bail!("- Please specify a boot image");
|
||||
bail!("Please specify a boot image");
|
||||
}
|
||||
let mut slot_suffix =
|
||||
utils::getprop("ro.boot.slot_suffix").unwrap_or_else(|| String::from(""));
|
||||
@@ -878,104 +822,27 @@ fn find_boot_image(
|
||||
}
|
||||
};
|
||||
|
||||
let init_boot_partition = format!("/dev/block/by-name/init_boot{slot_suffix}");
|
||||
let vendor_boot_partition = format!("/dev/block/by-name/vendor_boot{slot_suffix}");
|
||||
let boot_partition = format!("/dev/block/by-name/boot{slot_suffix}");
|
||||
let init_boot_exist =
|
||||
Path::new(&format!("/dev/block/by-name/init_boot{slot_suffix}")).exists();
|
||||
let vendor_boot_exist =
|
||||
Path::new(&format!("/dev/block/by-name/vendor_boot{slot_suffix}")).exists();
|
||||
let boot_partition = if !is_replace_kernel && init_boot_exist && !skip_init {
|
||||
format!("/dev/block/by-name/init_boot{slot_suffix}")
|
||||
} else if !is_replace_kernel && vendor_boot_exist && !skip_init {
|
||||
format!("/dev/block/by-name/vendor_boot{slot_suffix}")
|
||||
} else {
|
||||
format!("/dev/block/by-name/boot{slot_suffix}")
|
||||
};
|
||||
|
||||
let init_boot_exist = Path::new(&init_boot_partition).exists();
|
||||
let vendor_boot_exist = Path::new(&vendor_boot_partition).exists();
|
||||
|
||||
// helper: unpack a partition and check for a ramdisk and init
|
||||
fn unpack_and_check_init(
|
||||
magiskboot: &Path,
|
||||
workdir: &Path,
|
||||
partition: &str,
|
||||
ramdisk_cpio: &str,
|
||||
) -> Result<bool> {
|
||||
let tmp_img = workdir.join("probe.img");
|
||||
dd(partition, &tmp_img)?;
|
||||
let status = Command::new(magiskboot)
|
||||
.current_dir(workdir)
|
||||
.stdout(Stdio::null())
|
||||
.stderr(Stdio::null())
|
||||
.arg("unpack")
|
||||
.arg(&tmp_img)
|
||||
.status()?;
|
||||
if !status.success() {
|
||||
let _ = std::fs::remove_file(&tmp_img);
|
||||
return Ok(false);
|
||||
}
|
||||
let ramdisk_path = workdir.join(ramdisk_cpio);
|
||||
let has_init = if ramdisk_path.exists() {
|
||||
Command::new(magiskboot)
|
||||
.current_dir(workdir)
|
||||
.stdout(Stdio::null())
|
||||
.stderr(Stdio::null())
|
||||
.arg("cpio")
|
||||
.arg(ramdisk_cpio)
|
||||
.arg("exists init")
|
||||
.status()
|
||||
.map(|s| s.success())
|
||||
.unwrap_or(false)
|
||||
} else {
|
||||
false
|
||||
};
|
||||
// Clean up
|
||||
let _ = std::fs::remove_file(&tmp_img);
|
||||
let _ = std::fs::remove_file(workdir.join("ramdisk.cpio"));
|
||||
let _ = std::fs::remove_dir_all(workdir.join("vendor_ramdisk"));
|
||||
Ok(has_init)
|
||||
}
|
||||
|
||||
let mut selected_partition = &boot_partition;
|
||||
|
||||
if !is_replace_kernel && init_boot_exist && !skip_init {
|
||||
// try init_boot/ramdisk.cpio
|
||||
if unpack_and_check_init(magiskboot, workdir, &init_boot_partition, "ramdisk.cpio")? {
|
||||
println!("- Using init_boot partition (ramdisk.cpio).");
|
||||
selected_partition = &init_boot_partition;
|
||||
}
|
||||
}
|
||||
|
||||
// try vendor_boot/vendor_ramdisk/init_boot.cpio
|
||||
if selected_partition == &boot_partition && !is_replace_kernel && vendor_boot_exist && !skip_init {
|
||||
if unpack_and_check_init(
|
||||
magiskboot,
|
||||
workdir,
|
||||
&vendor_boot_partition,
|
||||
"vendor_ramdisk/init_boot.cpio",
|
||||
)? {
|
||||
println!("- Using vendor_boot partition (vendor_ramdisk/init_boot.cpio).");
|
||||
selected_partition = &vendor_boot_partition;
|
||||
}
|
||||
}
|
||||
|
||||
// try vendor_boot/vendor_ramdisk/ramdisk.cpio
|
||||
if selected_partition == &boot_partition && !is_replace_kernel && vendor_boot_exist && !skip_init {
|
||||
if unpack_and_check_init(
|
||||
magiskboot,
|
||||
workdir,
|
||||
&vendor_boot_partition,
|
||||
"vendor_ramdisk/ramdisk.cpio",
|
||||
)? {
|
||||
println!("- Using vendor_boot partition (vendor_ramdisk/ramdisk.cpio).");
|
||||
selected_partition = &vendor_boot_partition;
|
||||
}
|
||||
}
|
||||
|
||||
if selected_partition == &boot_partition {
|
||||
println!("- Using boot partition (ramdisk.cpio).");
|
||||
}
|
||||
|
||||
println!("- Bootdevice: {selected_partition}");
|
||||
println!("- Bootdevice: {boot_partition}");
|
||||
let tmp_boot_path = workdir.join("boot.img");
|
||||
|
||||
dd(selected_partition, &tmp_boot_path)?;
|
||||
dd(&boot_partition, &tmp_boot_path)?;
|
||||
|
||||
ensure!(tmp_boot_path.exists(), "- Tmp boot image not found");
|
||||
ensure!(tmp_boot_path.exists(), "boot image not found");
|
||||
|
||||
bootimage = tmp_boot_path;
|
||||
bootdevice = Some(selected_partition.to_string());
|
||||
bootdevice = Some(boot_partition);
|
||||
};
|
||||
Ok((bootimage, bootdevice))
|
||||
}
|
||||
|
||||
@@ -47,5 +47,3 @@ pub const KSU_BACKUP_FILE_PREFIX: &str = "ksu_backup_";
|
||||
pub const BACKUP_FILENAME: &str = "stock_image.sha1";
|
||||
|
||||
pub const MOUNT_SYSTEM: &str = "OverlayFS";
|
||||
|
||||
pub const GLOBAL_NAMESPACE_FILE: &str = concatcp!(WORKING_DIR, ".global_mnt");
|
||||
|
||||
@@ -261,9 +261,7 @@ pub fn root_shell() -> Result<()> {
|
||||
|
||||
// switch to global mount namespace
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
let global_namespace_enable =
|
||||
std::fs::read_to_string(defs::GLOBAL_NAMESPACE_FILE).unwrap_or("0".to_string());
|
||||
if global_namespace_enable.trim() == "1" || mount_master {
|
||||
if mount_master {
|
||||
let _ = utils::switch_mnt_ns(1);
|
||||
}
|
||||
|
||||
|
||||
227
KernelSU-Next/userspace/ksuinit/Cargo.lock
generated
227
KernelSU-Next/userspace/ksuinit/Cargo.lock
generated
@@ -1,227 +0,0 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.80"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf"
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "goblin"
|
||||
version = "0.8.0"
|
||||
source = "git+https://github.com/tiann/goblin#138d40d4c36471cfbb611eb493f0378ee9fc63f5"
|
||||
dependencies = [
|
||||
"log",
|
||||
"plain",
|
||||
"scroll",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kernlog"
|
||||
version = "0.3.1"
|
||||
source = "git+https://github.com/tiann/kernlog.rs#ff0b1bd6d5261eae0fa297cec6951fe8d982151a"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ksuinit"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"goblin",
|
||||
"kernlog",
|
||||
"log",
|
||||
"obfstr",
|
||||
"rustix",
|
||||
"scroll",
|
||||
"syscalls",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.153"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.4.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
|
||||
|
||||
[[package]]
|
||||
name = "obfstr"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3ba2979b86cc910a6d13837ef97fef0c6b68fa807c5e014d622449db18351dc"
|
||||
|
||||
[[package]]
|
||||
name = "plain"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.34"
|
||||
source = "git+https://github.com/Kernel-SU/rustix.git?rev=4a53fbc#4a53fbc7cb7a07cabe87125cc21dbc27db316259"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scroll"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ab8598aa408498679922eff7fa985c25d58a90771bd6be794434c5277eab1a6"
|
||||
dependencies = [
|
||||
"scroll_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scroll_derive"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f81c2fde025af7e69b1d1420531c8a8811ca898919db177141a85313b1cb932"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.52"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syscalls"
|
||||
version = "0.6.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56b389b38331a454883a34fd19f25cbd1510b3510ff7aa28cb8d6de85d888439"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8"
|
||||
@@ -1,34 +0,0 @@
|
||||
[package]
|
||||
name = "ksuinit"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
|
||||
# for elf parsing
|
||||
goblin = { git = "https://github.com/tiann/goblin" }
|
||||
scroll = "0.12"
|
||||
|
||||
anyhow = "1"
|
||||
# If you want to use the following dependencies, please use aarch64-unknown-linux-musl & x86_64-unknown-linux-musl to compile statically
|
||||
# rustix = { git = "https://github.com/bytecodealliance/rustix", rev = "7b44528", features = ["mount", "fs", "runtime", "system", "process"] }
|
||||
rustix = { git = "https://github.com/Kernel-SU/rustix.git", rev = "4a53fbc", features = ["mount", "fs", "runtime", "system", "process"] }
|
||||
|
||||
syscalls = { version = "0.6", default-features = false, features = [
|
||||
"aarch64",
|
||||
"x86_64",
|
||||
] }
|
||||
|
||||
# for kmsg logging
|
||||
log = "0.4"
|
||||
kernlog = { git = "https://github.com/tiann/kernlog.rs" }
|
||||
|
||||
obfstr = "0.4"
|
||||
|
||||
[profile.release]
|
||||
strip = true
|
||||
lto = true
|
||||
opt-level = "z"
|
||||
panic = "abort"
|
||||
@@ -1,185 +0,0 @@
|
||||
use std::io::{ErrorKind, Write};
|
||||
|
||||
use crate::loader::load_module;
|
||||
use anyhow::Result;
|
||||
use rustix::fs::{chmodat, symlink, unlink, AtFlags, Mode};
|
||||
use rustix::{
|
||||
fd::AsFd,
|
||||
fs::{access, makedev, mkdir, mknodat, Access, FileType, CWD},
|
||||
mount::{
|
||||
fsconfig_create, fsmount, fsopen, move_mount, unmount, FsMountFlags, FsOpenFlags,
|
||||
MountAttrFlags, MoveMountFlags, UnmountFlags,
|
||||
},
|
||||
};
|
||||
|
||||
use obfstr::obfstr as s;
|
||||
|
||||
struct AutoUmount {
|
||||
mountpoints: Vec<String>,
|
||||
}
|
||||
|
||||
impl Drop for AutoUmount {
|
||||
fn drop(&mut self) {
|
||||
for mountpoint in self.mountpoints.iter().rev() {
|
||||
if let Err(e) = unmount(mountpoint.as_str(), UnmountFlags::DETACH) {
|
||||
log::error!("{} {}: {}", s!("Cannot umount"), mountpoint, e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn prepare_mount() -> AutoUmount {
|
||||
let mut mountpoints = vec![];
|
||||
|
||||
// mount procfs
|
||||
let result = mkdir("/proc", Mode::from_raw_mode(0o755))
|
||||
.or_else(|err| match err.kind() {
|
||||
ErrorKind::AlreadyExists => Ok(()),
|
||||
_ => Err(err),
|
||||
})
|
||||
.and_then(|_| fsopen("proc", FsOpenFlags::FSOPEN_CLOEXEC))
|
||||
.and_then(|fd| fsconfig_create(fd.as_fd()).map(|_| fd))
|
||||
.and_then(|fd| {
|
||||
fsmount(
|
||||
fd.as_fd(),
|
||||
FsMountFlags::FSMOUNT_CLOEXEC,
|
||||
MountAttrFlags::empty(),
|
||||
)
|
||||
})
|
||||
.and_then(|fd| {
|
||||
move_mount(
|
||||
fd.as_fd(),
|
||||
"",
|
||||
CWD,
|
||||
"/proc",
|
||||
MoveMountFlags::MOVE_MOUNT_F_EMPTY_PATH,
|
||||
)
|
||||
});
|
||||
match result {
|
||||
Ok(_) => mountpoints.push("/proc".to_string()),
|
||||
Err(e) => log::error!("{} {:?}", s!("Cannot mount procfs: "), e),
|
||||
}
|
||||
|
||||
// mount sysfs
|
||||
let result = mkdir("/sys", Mode::from_raw_mode(0o755))
|
||||
.or_else(|err| match err.kind() {
|
||||
ErrorKind::AlreadyExists => Ok(()),
|
||||
_ => Err(err),
|
||||
})
|
||||
.and_then(|_| fsopen("sysfs", FsOpenFlags::FSOPEN_CLOEXEC))
|
||||
.and_then(|fd| fsconfig_create(fd.as_fd()).map(|_| fd))
|
||||
.and_then(|fd| {
|
||||
fsmount(
|
||||
fd.as_fd(),
|
||||
FsMountFlags::FSMOUNT_CLOEXEC,
|
||||
MountAttrFlags::empty(),
|
||||
)
|
||||
})
|
||||
.and_then(|fd| {
|
||||
move_mount(
|
||||
fd.as_fd(),
|
||||
"",
|
||||
CWD,
|
||||
"/sys",
|
||||
MoveMountFlags::MOVE_MOUNT_F_EMPTY_PATH,
|
||||
)
|
||||
});
|
||||
|
||||
match result {
|
||||
Ok(_) => mountpoints.push("/sys".to_string()),
|
||||
Err(e) => log::error!("{} {:?}", s!("Cannot mount sysfs:"), e),
|
||||
}
|
||||
|
||||
AutoUmount { mountpoints }
|
||||
}
|
||||
|
||||
fn setup_kmsg() {
|
||||
const KMSG: &str = "/dev/kmsg";
|
||||
let device = match access(KMSG, Access::EXISTS) {
|
||||
Ok(_) => KMSG,
|
||||
Err(_) => {
|
||||
// try to create it
|
||||
mknodat(
|
||||
CWD,
|
||||
"/kmsg",
|
||||
FileType::CharacterDevice,
|
||||
0o666.into(),
|
||||
makedev(1, 11),
|
||||
)
|
||||
.ok();
|
||||
"/kmsg"
|
||||
}
|
||||
};
|
||||
|
||||
let _ = kernlog::init_with_device(device);
|
||||
}
|
||||
|
||||
fn unlimit_kmsg() {
|
||||
// Disable kmsg rate limiting
|
||||
if let Ok(mut rate) = std::fs::File::options()
|
||||
.write(true)
|
||||
.open(s!("/proc/sys/kernel/printk_devkmsg"))
|
||||
{
|
||||
writeln!(rate, "on").ok();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init() -> Result<()> {
|
||||
// Setup kernel log first
|
||||
setup_kmsg();
|
||||
|
||||
log::info!("{}", s!("Hello, KernelSU!"));
|
||||
|
||||
// mount /proc and /sys to access kernel interface
|
||||
let _dontdrop = prepare_mount();
|
||||
|
||||
// This relies on the fact that we have /proc mounted
|
||||
unlimit_kmsg();
|
||||
|
||||
if has_kernelsu() {
|
||||
log::info!("{}", s!("KernelSU may be already loaded in kernel, skip!"));
|
||||
} else {
|
||||
log::info!("{}", s!("Loading kernelsu.ko.."));
|
||||
if let Err(e) = load_module(s!("/kernelsu.ko")) {
|
||||
log::error!("{}: {}", s!("Cannot load kernelsu.ko"), e);
|
||||
}
|
||||
}
|
||||
|
||||
// And now we should prepare the real init to transfer control to it
|
||||
unlink("/init")?;
|
||||
|
||||
let real_init = match access("/init.real", Access::EXISTS) {
|
||||
Ok(_) => "init.real",
|
||||
Err(_) => "/system/bin/init",
|
||||
};
|
||||
|
||||
log::info!("{} {}", s!("init is"), real_init);
|
||||
symlink(real_init, "/init")?;
|
||||
|
||||
chmodat(
|
||||
CWD,
|
||||
"/init",
|
||||
Mode::from_raw_mode(0o755),
|
||||
AtFlags::SYMLINK_NOFOLLOW,
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn has_kernelsu() -> bool {
|
||||
use syscalls::{syscall, Sysno};
|
||||
let mut version = 0;
|
||||
const CMD_GET_VERSION: i32 = 2;
|
||||
unsafe {
|
||||
let _ = syscall!(
|
||||
Sysno::prctl,
|
||||
0xDEADBEEF,
|
||||
CMD_GET_VERSION,
|
||||
std::ptr::addr_of_mut!(version)
|
||||
);
|
||||
}
|
||||
|
||||
log::info!("{}: {}", s!("KernelSU version"), version);
|
||||
|
||||
version != 0
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
use anyhow::{Context, Result};
|
||||
use goblin::elf::{section_header, sym::Sym, Elf};
|
||||
use rustix::{cstr, system::init_module};
|
||||
use scroll::{ctx::SizeWith, Pwrite};
|
||||
use std::collections::HashMap;
|
||||
use std::fs;
|
||||
|
||||
use obfstr::obfstr as s;
|
||||
|
||||
struct Kptr {
|
||||
value: String,
|
||||
}
|
||||
|
||||
impl Kptr {
|
||||
pub fn new() -> Result<Self> {
|
||||
let value = fs::read_to_string(s!("/proc/sys/kernel/kptr_restrict"))?;
|
||||
fs::write(s!("/proc/sys/kernel/kptr_restrict"), "1")?;
|
||||
Ok(Kptr { value })
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Kptr {
|
||||
fn drop(&mut self) {
|
||||
let _ = fs::write(s!("/proc/sys/kernel/kptr_restrict"), self.value.as_bytes());
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_kallsyms() -> Result<HashMap<String, u64>> {
|
||||
let _dontdrop = Kptr::new()?;
|
||||
|
||||
let allsyms = fs::read_to_string(s!("/proc/kallsyms"))?
|
||||
.lines()
|
||||
.map(|line| line.split_whitespace())
|
||||
.filter_map(|mut splits| {
|
||||
splits
|
||||
.next()
|
||||
.and_then(|addr| u64::from_str_radix(addr, 16).ok())
|
||||
.and_then(|addr| splits.nth(1).map(|symbol| (symbol, addr)))
|
||||
})
|
||||
.map(|(symbol, addr)| {
|
||||
(
|
||||
symbol
|
||||
.find("$").or_else(|| symbol.find(".llvm."))
|
||||
.map_or(symbol, |pos| &symbol[0..pos])
|
||||
.to_owned(),
|
||||
addr,
|
||||
)
|
||||
})
|
||||
.collect::<HashMap<_, _>>();
|
||||
|
||||
Ok(allsyms)
|
||||
}
|
||||
|
||||
pub fn load_module(path: &str) -> Result<()> {
|
||||
// check if self is init process(pid == 1)
|
||||
if !rustix::process::getpid().is_init() {
|
||||
anyhow::bail!("{}", s!("Invalid process"));
|
||||
}
|
||||
|
||||
let mut buffer =
|
||||
fs::read(path).with_context(|| format!("{} {}", s!("Cannot read file"), path))?;
|
||||
let elf = Elf::parse(&buffer)?;
|
||||
|
||||
let kernel_symbols =
|
||||
parse_kallsyms().with_context(|| s!("Cannot parse kallsyms").to_string())?;
|
||||
|
||||
let mut modifications = Vec::new();
|
||||
for (index, mut sym) in elf.syms.iter().enumerate() {
|
||||
if index == 0 {
|
||||
continue;
|
||||
}
|
||||
|
||||
if sym.st_shndx != section_header::SHN_UNDEF as usize {
|
||||
continue;
|
||||
}
|
||||
|
||||
let Some(name) = elf.strtab.get_at(sym.st_name) else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let offset = elf.syms.offset() + index * Sym::size_with(elf.syms.ctx());
|
||||
let Some(real_addr) = kernel_symbols.get(name) else {
|
||||
log::warn!("{}: {}", s!("Cannot found symbol"), &name);
|
||||
continue;
|
||||
};
|
||||
sym.st_shndx = section_header::SHN_ABS as usize;
|
||||
sym.st_value = *real_addr;
|
||||
modifications.push((sym, offset));
|
||||
}
|
||||
|
||||
let ctx = *elf.syms.ctx();
|
||||
for ele in modifications {
|
||||
buffer.pwrite_with(ele.0, ele.1, ctx)?;
|
||||
}
|
||||
init_module(&buffer, cstr!("")).with_context(|| s!("init_module failed.").to_string())?;
|
||||
Ok(())
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
#![no_main]
|
||||
|
||||
mod init;
|
||||
mod loader;
|
||||
|
||||
use rustix::{cstr, runtime::execve};
|
||||
/// # Safety
|
||||
/// This is the entry point of the program
|
||||
/// We cannot use the main because rust will abort if we don't have std{in/out/err}
|
||||
/// https://github.com/rust-lang/rust/blob/3071aefdb2821439e2e6f592f41a4d28e40c1e79/library/std/src/sys/unix/mod.rs#L80
|
||||
/// So we use the C main function and call rust code from there
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn main(_argc: i32, argv: *const *const u8, envp: *const *const u8) -> i32 {
|
||||
let _ = init::init();
|
||||
unsafe {
|
||||
execve(cstr!("/init"), argv, envp);
|
||||
}
|
||||
0
|
||||
}
|
||||
@@ -1,54 +1,11 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/xattr.h>
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <termios.h>
|
||||
#include <sys/prctl.h>
|
||||
|
||||
#define KERNEL_SU_OPTION 0xDEADBEEF
|
||||
#define CMD_GRANT_ROOT 0
|
||||
#define CMD_ENABLE_SU 15
|
||||
|
||||
int main(int argc, char **argv, char **envp) {
|
||||
unsigned long result = 0;
|
||||
|
||||
if (argc >= 2 && strcmp(argv[1], "--disable-sucompat") == 0) {
|
||||
prctl(KERNEL_SU_OPTION, CMD_ENABLE_SU, 0L, 0L, (unsigned long)&result);
|
||||
return 0;
|
||||
}
|
||||
|
||||
prctl(KERNEL_SU_OPTION, CMD_GRANT_ROOT, 0L, 0L, (unsigned long)&result);
|
||||
if (result != KERNEL_SU_OPTION) {
|
||||
const char *error = "Access Denied: sucompat not permitted\n";
|
||||
write(STDERR_FILENO, error, strlen(error));
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct termios term;
|
||||
if (ioctl(STDIN_FILENO, TCGETS, &term) == 0) {
|
||||
char tty_path[PATH_MAX];
|
||||
ssize_t len = readlink("/proc/self/fd/0", tty_path, sizeof(tty_path) - 1);
|
||||
if (len > 0) {
|
||||
tty_path[len] = '\0';
|
||||
const char *selinux_ctx = "u:object_r:devpts:s0";
|
||||
setxattr(tty_path, "security.selinux", selinux_ctx, strlen(selinux_ctx) + 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
const char *default_args[] = { "/system/bin/su", NULL };
|
||||
if (argc < 1 || !argv) {
|
||||
argv = (char **)default_args;
|
||||
} else {
|
||||
argv[0] = "/system/bin/su";
|
||||
}
|
||||
|
||||
execve("/data/adb/ksud", argv, envp);
|
||||
|
||||
const char *error = "Error: Failed to execve /data/adb/ksud\n";
|
||||
write(STDERR_FILENO, error, strlen(error));
|
||||
return 1;
|
||||
// This is a simple example. If you want a full-featured "su", please use "/data/adb/ksud debug su".
|
||||
int main(){
|
||||
int32_t result = 0;
|
||||
prctl(0xdeadbeef, 0, 0, 0, &result);
|
||||
system("/system/bin/sh");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -104,77 +104,52 @@ int main(int argc, char *argv[]) {
|
||||
prctl(KERNEL_SU_OPTION, CMD_SUSFS_SHOW_ENABLED_FEATURES, enabled_features, bufsize, &error);
|
||||
printf("%s\n", error || !strlen(enabled_features) ? "Unsupported" : "Supported");
|
||||
free(enabled_features);
|
||||
} else if (argc >= 2 && !strcmp(argv[1], "sus_su")) {
|
||||
if (argc == 3 && strcmp(argv[2], "support") == 0) {
|
||||
char *enabled_features;
|
||||
size_t bufsize = getpagesize() * 2;
|
||||
enabled_features = (char *)malloc(bufsize);
|
||||
if (!enabled_features) {
|
||||
perror("malloc");
|
||||
return -ENOMEM;
|
||||
}
|
||||
prctl(KERNEL_SU_OPTION, CMD_SUSFS_SHOW_ENABLED_FEATURES, enabled_features, bufsize, &error);
|
||||
if (!error && strstr(enabled_features, "CONFIG_KSU_SUSFS_SUS_SU")) {
|
||||
printf("Supported\n");
|
||||
} else {
|
||||
printf("Unsupported\n");
|
||||
}
|
||||
free(enabled_features);
|
||||
return 0;
|
||||
} else if (argc == 3) {
|
||||
int last_working_mode = 0;
|
||||
int target_working_mode;
|
||||
char *endptr;
|
||||
} else if (argc == 3 && !strcmp(argv[1], "sus_su")) {
|
||||
int last_working_mode = 0;
|
||||
int target_working_mode;
|
||||
char* endptr;
|
||||
|
||||
prctl(KERNEL_SU_OPTION, CMD_SUSFS_SHOW_SUS_SU_WORKING_MODE, &last_working_mode, NULL, &error);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
if (!strcmp(argv[2], "mode")) {
|
||||
printf("%d\n", last_working_mode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
target_working_mode = strtol(argv[2], &endptr, 10);
|
||||
if (*endptr != '\0') {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (target_working_mode == SUS_SU_WITH_HOOKS) {
|
||||
bool is_sus_su_ready;
|
||||
prctl(KERNEL_SU_OPTION, CMD_SUSFS_IS_SUS_SU_READY, &is_sus_su_ready, NULL, &error);
|
||||
if (error)
|
||||
return error;
|
||||
if (!is_sus_su_ready) {
|
||||
printf("[-] sus_su mode %d has to be run during or after service stage\n", SUS_SU_WITH_HOOKS);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (last_working_mode == SUS_SU_DISABLED) {
|
||||
error = enable_sus_su(last_working_mode, SUS_SU_WITH_HOOKS);
|
||||
} else if (last_working_mode == SUS_SU_WITH_HOOKS) {
|
||||
printf("[-] sus_su is already in mode %d\n", last_working_mode);
|
||||
return 1;
|
||||
} else {
|
||||
error = enable_sus_su(last_working_mode, SUS_SU_DISABLED);
|
||||
if (!error)
|
||||
error = enable_sus_su(last_working_mode, SUS_SU_WITH_HOOKS);
|
||||
}
|
||||
} else if (target_working_mode == SUS_SU_DISABLED) {
|
||||
if (last_working_mode == SUS_SU_DISABLED) {
|
||||
printf("[-] sus_su is already in mode %d\n", last_working_mode);
|
||||
return 1;
|
||||
}
|
||||
error = enable_sus_su(last_working_mode, SUS_SU_DISABLED);
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Usage: %s sus_su <0|2|mode|support>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
prctl(KERNEL_SU_OPTION, CMD_SUSFS_SHOW_SUS_SU_WORKING_MODE, &last_working_mode, NULL, &error);
|
||||
if (error)
|
||||
return error;
|
||||
if (!strcmp(argv[2], "mode")) {
|
||||
printf("%d\n", last_working_mode);
|
||||
return 0;
|
||||
}
|
||||
target_working_mode = strtol(argv[2], &endptr, 10);
|
||||
if (*endptr != '\0') {
|
||||
return 1;
|
||||
}
|
||||
if (target_working_mode == SUS_SU_WITH_HOOKS) {
|
||||
bool is_sus_su_ready;
|
||||
prctl(KERNEL_SU_OPTION, CMD_SUSFS_IS_SUS_SU_READY, &is_sus_su_ready, NULL, &error);
|
||||
if (error)
|
||||
return error;
|
||||
if (!is_sus_su_ready) {
|
||||
printf("[-] sus_su mode %d has to be run during or after service stage\n", SUS_SU_WITH_HOOKS);
|
||||
return 1;
|
||||
}
|
||||
if (last_working_mode == SUS_SU_DISABLED) {
|
||||
error = enable_sus_su(last_working_mode, SUS_SU_WITH_HOOKS);
|
||||
} else if (last_working_mode == SUS_SU_WITH_HOOKS) {
|
||||
printf("[-] sus_su is already in mode %d\n", last_working_mode);
|
||||
return 1;
|
||||
} else {
|
||||
error = enable_sus_su(last_working_mode, SUS_SU_DISABLED);
|
||||
if (!error)
|
||||
error = enable_sus_su(last_working_mode, SUS_SU_WITH_HOOKS);
|
||||
}
|
||||
} else if (target_working_mode == SUS_SU_DISABLED) {
|
||||
if (last_working_mode == SUS_SU_DISABLED) {
|
||||
printf("[-] sus_su is already in mode %d\n", last_working_mode);
|
||||
return 1;
|
||||
}
|
||||
error = enable_sus_su(last_working_mode, SUS_SU_DISABLED);
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Invalid argument: %s\n", argv[1]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
CONFIG_LOCALVERSION="-✨Caelum-b4s4"
|
||||
# Compression
|
||||
CONFIG_KERNEL_LZ4=y
|
||||
# CONFIG_FHANDLE is not set
|
||||
CONFIG_AUDIT=y
|
||||
|
||||
115
fs/compat.c
115
fs/compat.c
@@ -54,6 +54,15 @@
|
||||
#include <asm/ioctls.h>
|
||||
#include "internal.h"
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
#include <linux/susfs_def.h>
|
||||
extern bool susfs_is_inode_sus_path(struct inode *inode);
|
||||
extern bool susfs_is_sus_android_data_d_name_found(const char *d_name);
|
||||
extern bool susfs_is_sus_sdcard_d_name_found(const char *d_name);
|
||||
extern bool susfs_is_base_dentry_android_data_dir(struct dentry* base);
|
||||
extern bool susfs_is_base_dentry_sdcard_dir(struct dentry* base);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Not all architectures have sys_utime, so implement this in terms
|
||||
* of sys_utimes.
|
||||
@@ -829,6 +838,11 @@ struct compat_old_linux_dirent {
|
||||
struct compat_readdir_callback {
|
||||
struct dir_context ctx;
|
||||
struct compat_old_linux_dirent __user *dirent;
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
struct super_block *sb;
|
||||
bool is_base_dentry_android_data_root_dir;
|
||||
bool is_base_dentry_sdcard_root_dir;
|
||||
#endif
|
||||
int result;
|
||||
};
|
||||
|
||||
@@ -840,6 +854,9 @@ static int compat_fillonedir(struct dir_context *ctx, const char *name,
|
||||
container_of(ctx, struct compat_readdir_callback, ctx);
|
||||
struct compat_old_linux_dirent __user *dirent;
|
||||
compat_ulong_t d_ino;
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
struct inode *inode;
|
||||
#endif
|
||||
|
||||
if (buf->result)
|
||||
return -EINVAL;
|
||||
@@ -848,6 +865,28 @@ static int compat_fillonedir(struct dir_context *ctx, const char *name,
|
||||
buf->result = -EOVERFLOW;
|
||||
return -EOVERFLOW;
|
||||
}
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
if (buf->is_base_dentry_android_data_root_dir) {
|
||||
if (susfs_is_sus_android_data_d_name_found(name)) {
|
||||
return 0;
|
||||
}
|
||||
} else if (buf->is_base_dentry_sdcard_root_dir) {
|
||||
if (susfs_is_sus_sdcard_d_name_found(name)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
inode = ilookup(buf->sb, ino);
|
||||
if (!inode) {
|
||||
goto orig_flow;
|
||||
}
|
||||
if (susfs_is_inode_sus_path(inode)) {
|
||||
iput(inode);
|
||||
return 0;
|
||||
}
|
||||
iput(inode);
|
||||
orig_flow:
|
||||
#endif
|
||||
buf->result++;
|
||||
dirent = buf->dirent;
|
||||
if (!access_ok(VERIFY_WRITE, dirent,
|
||||
@@ -875,9 +914,33 @@ COMPAT_SYSCALL_DEFINE3(old_readdir, unsigned int, fd,
|
||||
.ctx.actor = compat_fillonedir,
|
||||
.dirent = dirent
|
||||
};
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
struct inode *inode;
|
||||
#endif
|
||||
|
||||
if (!f.file)
|
||||
return -EBADF;
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
buf.sb = f.file->f_inode->i_sb;
|
||||
inode = f.file->f_path.dentry->d_inode;
|
||||
if (f.file->f_path.dentry && inode) {
|
||||
if (susfs_is_base_dentry_android_data_dir(f.file->f_path.dentry))
|
||||
{
|
||||
buf.is_base_dentry_android_data_root_dir = true;
|
||||
buf.is_base_dentry_sdcard_root_dir = false;
|
||||
goto orig_flow;
|
||||
}
|
||||
if (susfs_is_base_dentry_sdcard_dir(f.file->f_path.dentry))
|
||||
{
|
||||
buf.is_base_dentry_sdcard_root_dir = true;
|
||||
buf.is_base_dentry_android_data_root_dir = false;
|
||||
goto orig_flow;
|
||||
}
|
||||
}
|
||||
buf.is_base_dentry_android_data_root_dir = false;
|
||||
buf.is_base_dentry_sdcard_root_dir = false;
|
||||
orig_flow:
|
||||
#endif
|
||||
|
||||
error = iterate_dir(f.file, &buf.ctx);
|
||||
if (buf.result)
|
||||
@@ -898,6 +961,11 @@ struct compat_getdents_callback {
|
||||
struct dir_context ctx;
|
||||
struct compat_linux_dirent __user *current_dir;
|
||||
struct compat_linux_dirent __user *previous;
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
struct super_block *sb;
|
||||
bool is_base_dentry_android_data_root_dir;
|
||||
bool is_base_dentry_sdcard_root_dir;
|
||||
#endif
|
||||
int count;
|
||||
int error;
|
||||
};
|
||||
@@ -911,6 +979,9 @@ static int compat_filldir(struct dir_context *ctx, const char *name, int namlen,
|
||||
compat_ulong_t d_ino;
|
||||
int reclen = ALIGN(offsetof(struct compat_linux_dirent, d_name) +
|
||||
namlen + 2, sizeof(compat_long_t));
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
struct inode *inode;
|
||||
#endif
|
||||
|
||||
buf->error = -EINVAL; /* only used if we fail.. */
|
||||
if (reclen > buf->count)
|
||||
@@ -920,6 +991,26 @@ static int compat_filldir(struct dir_context *ctx, const char *name, int namlen,
|
||||
buf->error = -EOVERFLOW;
|
||||
return -EOVERFLOW;
|
||||
}
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
if (buf->is_base_dentry_android_data_root_dir) {
|
||||
if (susfs_is_sus_android_data_d_name_found(name)) {
|
||||
return 0;
|
||||
}
|
||||
} else if (buf->is_base_dentry_sdcard_root_dir) {
|
||||
if (susfs_is_sus_sdcard_d_name_found(name)) {
|
||||
return 0;
|
||||
} }
|
||||
|
||||
inode = ilookup(buf->sb, ino);
|
||||
if (!inode) { goto orig_flow;
|
||||
}
|
||||
if (susfs_is_inode_sus_path(inode)) {
|
||||
iput(inode);
|
||||
return 0;
|
||||
}
|
||||
iput(inode);
|
||||
orig_flow:
|
||||
#endif
|
||||
dirent = buf->previous;
|
||||
if (dirent) {
|
||||
if (signal_pending(current))
|
||||
@@ -959,6 +1050,9 @@ COMPAT_SYSCALL_DEFINE3(getdents, unsigned int, fd,
|
||||
.count = count
|
||||
};
|
||||
int error;
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
struct inode *inode;
|
||||
#endif
|
||||
|
||||
if (!access_ok(VERIFY_WRITE, dirent, count))
|
||||
return -EFAULT;
|
||||
@@ -966,6 +1060,27 @@ COMPAT_SYSCALL_DEFINE3(getdents, unsigned int, fd,
|
||||
f = fdget_pos(fd);
|
||||
if (!f.file)
|
||||
return -EBADF;
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
buf.sb = f.file->f_inode->i_sb;
|
||||
inode = f.file->f_path.dentry->d_inode;
|
||||
if (f.file->f_path.dentry && inode) {
|
||||
if (susfs_is_base_dentry_android_data_dir(f.file->f_path.dentry))
|
||||
{
|
||||
buf.is_base_dentry_android_data_root_dir = true;
|
||||
buf.is_base_dentry_sdcard_root_dir = false;
|
||||
goto orig_flow;
|
||||
}
|
||||
if (susfs_is_base_dentry_sdcard_dir(f.file->f_path.dentry))
|
||||
{
|
||||
buf.is_base_dentry_sdcard_root_dir = true;
|
||||
buf.is_base_dentry_android_data_root_dir = false;
|
||||
goto orig_flow;
|
||||
}
|
||||
}
|
||||
buf.is_base_dentry_android_data_root_dir = false;
|
||||
buf.is_base_dentry_sdcard_root_dir = false;
|
||||
orig_flow:
|
||||
#endif
|
||||
|
||||
error = iterate_dir(f.file, &buf.ctx);
|
||||
if (error >= 0)
|
||||
|
||||
132
fs/namei.c
132
fs/namei.c
@@ -40,8 +40,10 @@
|
||||
#include <asm/uaccess.h>
|
||||
#if defined(CONFIG_KSU_SUSFS_SUS_PATH) || defined(CONFIG_KSU_SUSFS_OPEN_REDIRECT)
|
||||
#include <linux/susfs_def.h>
|
||||
|
||||
#endif
|
||||
#include "internal.h"
|
||||
#include "mount.h"
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
extern bool susfs_is_sus_android_data_d_name_found(const char *d_name);
|
||||
extern bool susfs_is_sus_sdcard_d_name_found(const char *d_name);
|
||||
@@ -51,9 +53,6 @@ extern bool susfs_is_base_dentry_sdcard_dir(struct dentry* base);
|
||||
extern const struct qstr susfs_fake_qstr_name;
|
||||
#endif
|
||||
|
||||
#include "internal.h"
|
||||
#include "mount.h"
|
||||
|
||||
/* [Feb-1997 T. Schoebel-Theuer]
|
||||
* Fundamental changes in the pathname lookup mechanisms (namei)
|
||||
* were necessary because of omirr. The reason is that omirr needs
|
||||
@@ -538,7 +537,7 @@ struct nameidata {
|
||||
struct inode *inode; /* path.dentry.d_inode */
|
||||
unsigned int flags;
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
unsigned int state;
|
||||
unsigned int state;
|
||||
#endif
|
||||
unsigned seq, m_seq;
|
||||
int last_type;
|
||||
@@ -949,12 +948,6 @@ static inline int may_follow_link(struct nameidata *nd)
|
||||
const struct inode *parent;
|
||||
kuid_t puid;
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
if (nd->inode && unlikely(nd->inode->i_state & INODE_STATE_SUS_PATH) && likely(current->susfs_task_state & TASK_STRUCT_NON_ROOT_USER_APP_PROC)) {
|
||||
return -ENOENT;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!sysctl_protected_symlinks)
|
||||
return 0;
|
||||
|
||||
@@ -1031,12 +1024,6 @@ static int may_linkat(struct path *link)
|
||||
{
|
||||
struct inode *inode;
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
if (link->dentry->d_inode && unlikely(link->dentry->d_inode->i_state & INODE_STATE_SUS_PATH) && likely(current->susfs_task_state & TASK_STRUCT_NON_ROOT_USER_APP_PROC)) {
|
||||
return -ENOENT;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!sysctl_protected_hardlinks)
|
||||
return 0;
|
||||
|
||||
@@ -1076,12 +1063,6 @@ static int may_linkat(struct path *link)
|
||||
static int may_create_in_sticky(umode_t dir_mode, kuid_t dir_uid,
|
||||
struct inode * const inode)
|
||||
{
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
if (unlikely(inode->i_state & INODE_STATE_SUS_PATH) && likely(current->susfs_task_state & TASK_STRUCT_NON_ROOT_USER_APP_PROC)) {
|
||||
return -ENOENT;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((!sysctl_protected_fifos && S_ISFIFO(inode->i_mode)) ||
|
||||
(!sysctl_protected_regular && S_ISREG(inode->i_mode)) ||
|
||||
likely(!(dir_mode & S_ISVTX)) ||
|
||||
@@ -1611,11 +1592,7 @@ static struct dentry *__lookup_hash(const struct qstr *name,
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
struct dentry *dentry;
|
||||
bool found_sus_path = false;
|
||||
#else
|
||||
struct dentry *dentry = lookup_dcache(name, base, flags);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
if (base && base->d_inode && !found_sus_path) {
|
||||
if (susfs_is_base_dentry_android_data_dir(base) &&
|
||||
susfs_is_sus_android_data_d_name_found(name->name))
|
||||
@@ -1636,18 +1613,23 @@ static struct dentry *__lookup_hash(const struct qstr *name,
|
||||
}
|
||||
dentry = lookup_dcache(name, base, flags);
|
||||
retry:
|
||||
#else
|
||||
struct dentry *dentry = lookup_dcache(name, base, flags);
|
||||
#endif
|
||||
|
||||
if (dentry) {
|
||||
if (dentry)
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
{
|
||||
if (!found_sus_path && !IS_ERR(dentry) && dentry->d_inode && susfs_is_inode_sus_path(dentry->d_inode)) {
|
||||
dentry = lookup_dcache(&susfs_fake_qstr_name, base, flags);
|
||||
found_sus_path = true;
|
||||
goto retry;
|
||||
}
|
||||
#endif
|
||||
return dentry;
|
||||
}
|
||||
#else
|
||||
return dentry;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
if (found_sus_path) {
|
||||
@@ -1665,6 +1647,7 @@ skip_orig_flow:
|
||||
return lookup_real(base->d_inode, dentry, flags);
|
||||
}
|
||||
|
||||
|
||||
static int lookup_fast(struct nameidata *nd,
|
||||
struct path *path, struct inode **inode,
|
||||
unsigned *seqp)
|
||||
@@ -1672,11 +1655,10 @@ static int lookup_fast(struct nameidata *nd,
|
||||
struct vfsmount *mnt = nd->path.mnt;
|
||||
struct dentry *dentry, *parent = nd->path.dentry;
|
||||
int status = 1;
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
bool is_nd_state_lookup_last_and_open_last =
|
||||
(nd->state & ND_STATE_LOOKUP_LAST || nd->state & ND_STATE_OPEN_LAST);
|
||||
#endif
|
||||
int err;
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
bool is_nd_state_lookup_last_and_open_last = (nd->state & ND_STATE_LOOKUP_LAST || nd->state & ND_STATE_OPEN_LAST);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Rename seqlock is not required here because in the off chance
|
||||
@@ -1705,7 +1687,7 @@ static int lookup_fast(struct nameidata *nd,
|
||||
#endif
|
||||
dentry = __d_lookup_rcu(parent, &nd->last, &seq);
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
if (is_nd_state_lookup_last_and_open_last && dentry && !IS_ERR(dentry) && dentry->d_inode) {
|
||||
if (is_nd_state_lookup_last_and_open_last && dentry && !IS_ERR(dentry) && dentry->d_inode && parent->d_inode) {
|
||||
if (susfs_is_inode_sus_path(dentry->d_inode)) {
|
||||
dentry = __d_lookup_rcu(parent, &susfs_fake_qstr_name, &backup_next_seq);
|
||||
}
|
||||
@@ -1777,7 +1759,7 @@ skip_orig_flow1:
|
||||
#endif
|
||||
dentry = __d_lookup(parent, &nd->last);
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
if (is_nd_state_lookup_last_and_open_last && dentry && !IS_ERR(dentry) && dentry->d_inode) {
|
||||
if (is_nd_state_lookup_last_and_open_last && dentry && !IS_ERR(dentry) && dentry->d_inode && parent->d_inode) {
|
||||
if (susfs_is_inode_sus_path(dentry->d_inode)) {
|
||||
dentry = __d_lookup(parent, &susfs_fake_qstr_name);
|
||||
}
|
||||
@@ -1840,7 +1822,7 @@ again:
|
||||
found_sus_path = true;
|
||||
goto retry;
|
||||
} else if (susfs_is_base_dentry_sdcard_dir(dir) &&
|
||||
susfs_is_sus_sdcard_d_name_found(name->name))
|
||||
susfs_is_sus_sdcard_d_name_found(name->name))
|
||||
{
|
||||
dentry = d_alloc_parallel(dir, &susfs_fake_qstr_name, &sus_wq);
|
||||
found_sus_path = true;
|
||||
@@ -2270,9 +2252,6 @@ static inline u64 hash_name(const void *salt, const char *name)
|
||||
static int link_path_walk(const char *name, struct nameidata *nd)
|
||||
{
|
||||
int err;
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
struct dentry *dentry;
|
||||
#endif
|
||||
|
||||
while (*name=='/')
|
||||
name++;
|
||||
@@ -2283,11 +2262,13 @@ static int link_path_walk(const char *name, struct nameidata *nd)
|
||||
for(;;) {
|
||||
u64 hash_len;
|
||||
int type;
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
struct dentry *dentry;
|
||||
#endif
|
||||
|
||||
err = may_lookup(nd);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
dentry = nd->path.dentry;
|
||||
if (dentry->d_inode && susfs_is_inode_sus_path(dentry->d_inode)) {
|
||||
@@ -2512,7 +2493,6 @@ static inline int lookup_last(struct nameidata *nd)
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
nd->state |= ND_STATE_LOOKUP_LAST;
|
||||
#endif
|
||||
|
||||
nd->flags &= ~LOOKUP_PARENT;
|
||||
return walk_component(nd,
|
||||
nd->flags & LOOKUP_FOLLOW
|
||||
@@ -2574,12 +2554,6 @@ static int filename_lookup(int dfd, struct filename *name, unsigned flags,
|
||||
if (likely(!retval))
|
||||
audit_inode(name, path->dentry, flags & LOOKUP_PARENT);
|
||||
restore_nameidata();
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
if (!retval && path->dentry->d_inode && unlikely(path->dentry->d_inode->i_state & INODE_STATE_SUS_PATH) && likely(current->susfs_task_state & TASK_STRUCT_NON_ROOT_USER_APP_PROC)) {
|
||||
putname(name);
|
||||
return -ENOENT;
|
||||
}
|
||||
#endif
|
||||
putname(name);
|
||||
return retval;
|
||||
}
|
||||
@@ -3062,12 +3036,6 @@ static int may_delete(struct vfsmount *mnt, struct inode *dir, struct dentry *vi
|
||||
if (IS_APPEND(dir))
|
||||
return -EPERM;
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
if (unlikely(inode->i_state & INODE_STATE_SUS_PATH) && likely(current->susfs_task_state & TASK_STRUCT_NON_ROOT_USER_APP_PROC)) {
|
||||
return -ENOENT;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (check_sticky(dir, inode) || IS_APPEND(inode) ||
|
||||
IS_IMMUTABLE(inode) || IS_SWAPFILE(inode) || HAS_UNMAPPED_ID(inode))
|
||||
return -EPERM;
|
||||
@@ -3096,20 +3064,8 @@ static int may_delete(struct vfsmount *mnt, struct inode *dir, struct dentry *vi
|
||||
*/
|
||||
static inline int may_create(struct vfsmount *mnt, struct inode *dir, struct dentry *child)
|
||||
{
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
int error;
|
||||
#endif
|
||||
struct user_namespace *s_user_ns;
|
||||
audit_inode_child(dir, child, AUDIT_TYPE_CHILD_CREATE);
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
if (child->d_inode && unlikely(child->d_inode->i_state & INODE_STATE_SUS_PATH) && likely(current->susfs_task_state & TASK_STRUCT_NON_ROOT_USER_APP_PROC)) {
|
||||
error = inode_permission2(mnt, dir, MAY_WRITE | MAY_EXEC);
|
||||
if (error) {
|
||||
return error;
|
||||
}
|
||||
return -ENOENT;
|
||||
}
|
||||
#endif
|
||||
if (child->d_inode)
|
||||
return -EEXIST;
|
||||
if (IS_DEADDIR(dir))
|
||||
@@ -3214,12 +3170,6 @@ static int may_open(struct path *path, int acc_mode, int flag)
|
||||
if (!inode)
|
||||
return -ENOENT;
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
if (unlikely(inode->i_state & INODE_STATE_SUS_PATH) && likely(current->susfs_task_state & TASK_STRUCT_NON_ROOT_USER_APP_PROC)) {
|
||||
return -ENOENT;
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (inode->i_mode & S_IFMT) {
|
||||
case S_IFLNK:
|
||||
return -ELOOP;
|
||||
@@ -3291,20 +3241,7 @@ static inline int open_to_namei_flags(int flag)
|
||||
static int may_o_create(const struct path *dir, struct dentry *dentry, umode_t mode)
|
||||
{
|
||||
struct user_namespace *s_user_ns;
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
int error;
|
||||
|
||||
if (dentry->d_inode && unlikely(dentry->d_inode->i_state & INODE_STATE_SUS_PATH) && likely(current->susfs_task_state & TASK_STRUCT_NON_ROOT_USER_APP_PROC)) {
|
||||
error = inode_permission2(dir->mnt, dir->dentry->d_inode, MAY_WRITE | MAY_EXEC);
|
||||
if (error) {
|
||||
return error;
|
||||
}
|
||||
return -ENOENT;
|
||||
}
|
||||
error = security_path_mknod(dir, dentry, mode, 0);
|
||||
#else
|
||||
int error = security_path_mknod(dir, dentry, mode, 0);
|
||||
#endif
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
@@ -3438,9 +3375,9 @@ static int lookup_open(struct nameidata *nd, struct path *path,
|
||||
{
|
||||
dentry = d_lookup(dir, &susfs_fake_qstr_name);
|
||||
found_sus_path = true;
|
||||
goto skip_orig_flow1;
|
||||
goto skip_orig_flow1;
|
||||
} else if (susfs_is_base_dentry_sdcard_dir(dir) &&
|
||||
susfs_is_sus_sdcard_d_name_found(nd->last.name))
|
||||
susfs_is_sus_sdcard_d_name_found(nd->last.name))
|
||||
{
|
||||
dentry = d_lookup(dir, &susfs_fake_qstr_name);
|
||||
found_sus_path = true;
|
||||
@@ -3490,12 +3427,6 @@ skip_orig_flow2:
|
||||
}
|
||||
if (dentry->d_inode) {
|
||||
/* Cached positive dentry: will open in f_op->open */
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
if (unlikely(dentry->d_inode->i_state & INODE_STATE_SUS_PATH) && likely(current->susfs_task_state & TASK_STRUCT_NON_ROOT_USER_APP_PROC)) {
|
||||
dput(dentry);
|
||||
return -ENOENT;
|
||||
}
|
||||
#endif
|
||||
goto out_no_open;
|
||||
}
|
||||
|
||||
@@ -3539,16 +3470,6 @@ skip_orig_flow2:
|
||||
mode, opened);
|
||||
if (unlikely(error == -ENOENT) && create_error)
|
||||
error = create_error;
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
if (!IS_ERR(dentry) && dentry->d_inode && unlikely(dentry->d_inode->i_state & INODE_STATE_SUS_PATH) && likely(current->susfs_task_state & TASK_STRUCT_NON_ROOT_USER_APP_PROC)) {
|
||||
if (create_error) {
|
||||
dput(dentry);
|
||||
return create_error;
|
||||
}
|
||||
dput(dentry);
|
||||
return -ENOENT;
|
||||
}
|
||||
#endif
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -3564,12 +3485,6 @@ no_open:
|
||||
}
|
||||
dput(dentry);
|
||||
dentry = res;
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
if (dentry->d_inode && unlikely(dentry->d_inode->i_state & INODE_STATE_SUS_PATH) && likely(current->susfs_task_state & TASK_STRUCT_NON_ROOT_USER_APP_PROC)) {
|
||||
dput(dentry);
|
||||
return -ENOENT;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3623,7 +3538,6 @@ static int do_last(struct nameidata *nd,
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
nd->state |= ND_STATE_OPEN_LAST;
|
||||
#endif
|
||||
|
||||
nd->flags &= ~LOOKUP_PARENT;
|
||||
nd->flags |= op->intent;
|
||||
|
||||
|
||||
@@ -25,11 +25,12 @@
|
||||
#include <linux/magic.h>
|
||||
#include <linux/bootmem.h>
|
||||
#include <linux/task_work.h>
|
||||
#include "pnode.h"
|
||||
#include "internal.h"
|
||||
|
||||
#if defined(CONFIG_KSU_SUSFS_SUS_MOUNT) || defined(CONFIG_KSU_SUSFS_TRY_UMOUNT)
|
||||
#include <linux/susfs_def.h>
|
||||
#endif
|
||||
#include "pnode.h"
|
||||
#include "internal.h"
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT
|
||||
extern bool susfs_is_current_ksu_domain(void);
|
||||
@@ -126,6 +127,11 @@ static inline struct hlist_head *mp_hash(struct dentry *dentry)
|
||||
return &mountpoint_hashtable[tmp & mp_hash_mask];
|
||||
}
|
||||
|
||||
/*
|
||||
* allocation is serialized by namespace_sem, but we need the spinlock to
|
||||
* serialize with freeing.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT
|
||||
// Our own mnt_alloc_id() that assigns mnt_id starting from DEFAULT_SUS_MNT_ID
|
||||
static int susfs_mnt_alloc_id(struct mount *mnt)
|
||||
@@ -145,10 +151,6 @@ retry:
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* allocation is serialized by namespace_sem, but we need the spinlock to
|
||||
* serialize with freeing.
|
||||
*/
|
||||
static int mnt_alloc_id(struct mount *mnt)
|
||||
{
|
||||
int res;
|
||||
@@ -2076,6 +2078,7 @@ struct mount *copy_tree(struct mount *mnt, struct dentry *dentry,
|
||||
p = mnt;
|
||||
list_for_each_entry(r, &mnt->mnt_mounts, mnt_child) {
|
||||
struct mount *s;
|
||||
|
||||
if (!is_subdir(r->mnt_mountpoint, dentry))
|
||||
continue;
|
||||
|
||||
@@ -2107,7 +2110,7 @@ struct mount *copy_tree(struct mount *mnt, struct dentry *dentry,
|
||||
goto out;
|
||||
lock_mount_hash();
|
||||
list_add_tail(&q->mnt_list, &res->mnt_list);
|
||||
attach_mnt(q, parent, p->mnt_mp);
|
||||
attach_mnt(q, parent, p->mnt_mp);
|
||||
unlock_mount_hash();
|
||||
}
|
||||
}
|
||||
@@ -3178,7 +3181,7 @@ long do_mount(const char *dev_name, const char __user *dir_name,
|
||||
retval = do_move_mount(&path, dev_name);
|
||||
else
|
||||
retval = do_new_mount(&path, type_page, flags, mnt_flags,
|
||||
dev_name, data_page);
|
||||
dev_name, data_page);
|
||||
#ifdef CONFIG_KSU_SUSFS_AUTO_ADD_SUS_KSU_DEFAULT_MOUNT
|
||||
// For both Legacy and Magic Mount KernelSU
|
||||
if (!retval && susfs_is_auto_add_sus_ksu_default_mount_enabled &&
|
||||
@@ -3928,4 +3931,4 @@ bool susfs_is_mnt_devname_ksu(struct path *path) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -102,7 +102,6 @@ static void inotify_fdinfo(struct seq_file *m, struct fsnotify_mark *mark)
|
||||
inode = igrab(mark->inode);
|
||||
if (inode) {
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT
|
||||
u32 mask = mark->mask & IN_ALL_EVENTS;
|
||||
if (likely(current->susfs_task_state & TASK_STRUCT_NON_ROOT_USER_APP_PROC) &&
|
||||
unlikely(inode->i_state & INODE_STATE_SUS_KSTAT)) {
|
||||
struct path path;
|
||||
@@ -118,9 +117,9 @@ static void inotify_fdinfo(struct seq_file *m, struct fsnotify_mark *mark)
|
||||
if (kern_path(dpath, 0, &path)) {
|
||||
goto out_free_pathname;
|
||||
}
|
||||
seq_printf(m, "inotify wd:%x ino:%lx sdev:%x mask:%x ignored_mask:%x ",
|
||||
seq_printf(m, "inotify wd:%x ino:%lx sdev:%x mask:%x ignored_mask:0 ",
|
||||
inode_mark->wd, path.dentry->d_inode->i_ino, path.dentry->d_inode->i_sb->s_dev,
|
||||
mask, mark->ignored_mask);
|
||||
inotify_mark_user_mask(mark));
|
||||
show_mark_fhandle(m, path.dentry->d_inode);
|
||||
seq_putc(m, '\n');
|
||||
iput(inode);
|
||||
|
||||
@@ -112,16 +112,6 @@ static int ovl_getattr(struct vfsmount *mnt, struct dentry *dentry,
|
||||
const struct cred *old_cred;
|
||||
int err;
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_OVERLAYFS
|
||||
ovl_path_lowerdata(dentry, &realpath);
|
||||
if (likely(realpath.mnt && realpath.dentry)) {
|
||||
old_cred = ovl_override_creds(dentry->d_sb);
|
||||
err = vfs_getattr(&realpath, stat);
|
||||
ovl_revert_creds(old_cred);
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
ovl_path_real(dentry, &realpath);
|
||||
old_cred = ovl_override_creds(dentry->d_sb);
|
||||
err = vfs_getattr(&realpath, stat);
|
||||
|
||||
@@ -149,9 +149,6 @@ u64 ovl_dentry_version_get(struct dentry *dentry);
|
||||
void ovl_dentry_version_inc(struct dentry *dentry);
|
||||
void ovl_path_upper(struct dentry *dentry, struct path *path);
|
||||
void ovl_path_lower(struct dentry *dentry, struct path *path);
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_OVERLAYFS
|
||||
void ovl_path_lowerdata(struct dentry *dentry, struct path *path);
|
||||
#endif
|
||||
enum ovl_path_type ovl_path_real(struct dentry *dentry, struct path *path);
|
||||
int ovl_path_next(int idx, struct dentry *dentry, struct path *path);
|
||||
struct dentry *ovl_dentry_upper(struct dentry *dentry);
|
||||
|
||||
@@ -500,7 +500,6 @@ static int ovl_dir_open(struct inode *inode, struct file *file)
|
||||
return -ENOMEM;
|
||||
|
||||
type = ovl_path_real(file->f_path.dentry, &realpath);
|
||||
|
||||
realfile = ovl_path_open(&realpath, file->f_flags);
|
||||
if (IS_ERR(realfile)) {
|
||||
kfree(od);
|
||||
|
||||
@@ -186,20 +186,6 @@ void ovl_path_lower(struct dentry *dentry, struct path *path)
|
||||
*path = oe->numlower ? oe->lowerstack[0] : (struct path) { NULL, NULL };
|
||||
}
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_OVERLAYFS
|
||||
void ovl_path_lowerdata(struct dentry *dentry, struct path *path)
|
||||
{
|
||||
struct ovl_entry *oe = dentry->d_fsdata;
|
||||
|
||||
if (oe->numlower) {
|
||||
path->mnt = oe->lowerstack[oe->numlower - 1].mnt;
|
||||
path->dentry = oe->lowerstack[oe->numlower - 1].dentry;
|
||||
} else {
|
||||
*path = (struct path) { };
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int ovl_want_write(struct dentry *dentry)
|
||||
{
|
||||
struct ovl_fs *ofs = dentry->d_sb->s_fs_info;
|
||||
|
||||
@@ -15,7 +15,6 @@ static int cmdline_proc_show(struct seq_file *m, void *v)
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
seq_printf(m, "%s\n", saved_command_line);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -71,8 +71,8 @@ static int seq_show(struct seq_file *m, void *v)
|
||||
seq_printf(m, "pos:\t%lli\nflags:\t0%o\nmnt_id:\t%i\n",
|
||||
(long long)file->f_pos, f_flags,
|
||||
real_mount(file->f_path.mnt)->mnt_id);
|
||||
|
||||
#endif
|
||||
|
||||
show_fd_locks(m, file, files);
|
||||
if (seq_has_overflowed(m))
|
||||
goto out;
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#include <linux/user_namespace.h>
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
static const struct proc_ns_operations *ns_entries[] = {
|
||||
#ifdef CONFIG_NET_NS
|
||||
&netns_operations,
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#include <linux/page_idle.h>
|
||||
#include <linux/shmem_fs.h>
|
||||
#include <linux/mm_inline.h>
|
||||
|
||||
#include <linux/ctype.h>
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_KSTAT
|
||||
#include <linux/susfs_def.h>
|
||||
#endif
|
||||
|
||||
@@ -10,11 +10,12 @@
|
||||
#include <linux/nsproxy.h>
|
||||
#include <linux/security.h>
|
||||
#include <linux/fs_struct.h>
|
||||
#include "proc/internal.h" /* only for get_proc_task() in ->open() */
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT
|
||||
#include <linux/susfs_def.h>
|
||||
#endif
|
||||
|
||||
#include "proc/internal.h" /* only for get_proc_task() in ->open() */
|
||||
|
||||
#include "pnode.h"
|
||||
#include "internal.h"
|
||||
|
||||
@@ -108,8 +109,7 @@ static int show_vfsmnt(struct seq_file *m, struct vfsmount *mnt)
|
||||
int err;
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT
|
||||
if (unlikely(r->mnt_id >= DEFAULT_SUS_MNT_ID) &&
|
||||
(susfs_hide_sus_mnts_for_all_procs || !susfs_is_current_ksu_domain()))
|
||||
if (unlikely(r->mnt_id >= DEFAULT_SUS_MNT_ID)&&(susfs_hide_sus_mnts_for_all_procs || !susfs_is_current_ksu_domain()))
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
@@ -150,8 +150,7 @@ static int show_mountinfo(struct seq_file *m, struct vfsmount *mnt)
|
||||
int err;
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT
|
||||
if (unlikely(r->mnt_id >= DEFAULT_SUS_MNT_ID) &&
|
||||
(susfs_hide_sus_mnts_for_all_procs || !susfs_is_current_ksu_domain()))
|
||||
if (unlikely(r->mnt_id >= DEFAULT_SUS_MNT_ID)&&(susfs_hide_sus_mnts_for_all_procs || !susfs_is_current_ksu_domain()))
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
@@ -220,8 +219,7 @@ static int show_vfsstat(struct seq_file *m, struct vfsmount *mnt)
|
||||
int err;
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_MOUNT
|
||||
if (unlikely(r->mnt_id >= DEFAULT_SUS_MNT_ID) &&
|
||||
(susfs_hide_sus_mnts_for_all_procs || !susfs_is_current_ksu_domain()))
|
||||
if (unlikely(r->mnt_id >= DEFAULT_SUS_MNT_ID)&&(susfs_hide_sus_mnts_for_all_procs || !susfs_is_current_ksu_domain()))
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
|
||||
23
fs/readdir.c
23
fs/readdir.c
@@ -18,6 +18,9 @@
|
||||
#include <linux/security.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/unistd.h>
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
#include <linux/susfs_def.h>
|
||||
extern bool susfs_is_inode_sus_path(struct inode *inode);
|
||||
@@ -26,9 +29,6 @@ extern bool susfs_is_sus_sdcard_d_name_found(const char *d_name);
|
||||
extern bool susfs_is_base_dentry_android_data_dir(struct dentry* base);
|
||||
extern bool susfs_is_base_dentry_sdcard_dir(struct dentry* base);
|
||||
#endif
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
int iterate_dir(struct file *file, struct dir_context *ctx)
|
||||
{
|
||||
struct inode *inode = file_inode(file);
|
||||
@@ -207,7 +207,6 @@ SYSCALL_DEFINE3(old_readdir, unsigned int, fd,
|
||||
|
||||
if (!f.file)
|
||||
return -EBADF;
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
buf.sb = f.file->f_inode->i_sb;
|
||||
inode = f.file->f_path.dentry->d_inode;
|
||||
@@ -229,6 +228,7 @@ SYSCALL_DEFINE3(old_readdir, unsigned int, fd,
|
||||
buf.is_base_dentry_sdcard_root_dir = false;
|
||||
orig_flow:
|
||||
#endif
|
||||
|
||||
error = iterate_dir(f.file, &buf.ctx);
|
||||
if (buf.result)
|
||||
error = buf.result;
|
||||
@@ -253,12 +253,12 @@ struct linux_dirent {
|
||||
struct getdents_callback {
|
||||
struct dir_context ctx;
|
||||
struct linux_dirent __user * current_dir;
|
||||
struct linux_dirent __user * previous;
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
struct super_block *sb;
|
||||
bool is_base_dentry_android_data_root_dir;
|
||||
bool is_base_dentry_sdcard_root_dir;
|
||||
#endif
|
||||
struct linux_dirent __user * previous;
|
||||
int count;
|
||||
int error;
|
||||
};
|
||||
@@ -272,10 +272,10 @@ static int filldir(struct dir_context *ctx, const char *name, int namlen,
|
||||
unsigned long d_ino;
|
||||
int reclen = ALIGN(offsetof(struct linux_dirent, d_name) + namlen + 2,
|
||||
sizeof(long));
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
struct inode *inode;
|
||||
#endif
|
||||
|
||||
buf->error = verify_dirent_name(name, namlen);
|
||||
if (unlikely(buf->error))
|
||||
return buf->error;
|
||||
@@ -358,7 +358,6 @@ SYSCALL_DEFINE3(getdents, unsigned int, fd,
|
||||
f = fdget_pos(fd);
|
||||
if (!f.file)
|
||||
return -EBADF;
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
buf.sb = f.file->f_inode->i_sb;
|
||||
inode = f.file->f_path.dentry->d_inode;
|
||||
@@ -380,6 +379,7 @@ SYSCALL_DEFINE3(getdents, unsigned int, fd,
|
||||
buf.is_base_dentry_sdcard_root_dir = false;
|
||||
orig_flow:
|
||||
#endif
|
||||
|
||||
error = iterate_dir(f.file, &buf.ctx);
|
||||
if (error >= 0)
|
||||
error = buf.error;
|
||||
@@ -397,12 +397,12 @@ orig_flow:
|
||||
struct getdents_callback64 {
|
||||
struct dir_context ctx;
|
||||
struct linux_dirent64 __user * current_dir;
|
||||
struct linux_dirent64 __user * previous;
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
struct super_block *sb;
|
||||
bool is_base_dentry_android_data_root_dir;
|
||||
bool is_base_dentry_sdcard_root_dir;
|
||||
#endif
|
||||
struct linux_dirent64 __user * previous;
|
||||
int count;
|
||||
int error;
|
||||
};
|
||||
@@ -429,6 +429,9 @@ static int filldir64(struct dir_context *ctx, const char *name, int namlen,
|
||||
if (dirent) {
|
||||
if (signal_pending(current))
|
||||
return -EINTR;
|
||||
if (__put_user(offset, &dirent->d_off))
|
||||
goto efault;
|
||||
}
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
if (buf->is_base_dentry_android_data_root_dir) {
|
||||
if (susfs_is_sus_android_data_d_name_found(name)) {
|
||||
@@ -451,9 +454,6 @@ static int filldir64(struct dir_context *ctx, const char *name, int namlen,
|
||||
iput(inode);
|
||||
orig_flow:
|
||||
#endif
|
||||
if (__put_user(offset, &dirent->d_off))
|
||||
goto efault;
|
||||
}
|
||||
dirent = buf->current_dir;
|
||||
if (__put_user(ino, &dirent->d_ino))
|
||||
goto efault;
|
||||
@@ -498,7 +498,6 @@ SYSCALL_DEFINE3(getdents64, unsigned int, fd,
|
||||
f = fdget_pos(fd);
|
||||
if (!f.file)
|
||||
return -EBADF;
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||
buf.sb = f.file->f_inode->i_sb;
|
||||
inode = f.file->f_path.dentry->d_inode;
|
||||
|
||||
@@ -21,6 +21,15 @@
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/unistd.h>
|
||||
|
||||
/**
|
||||
* generic_fillattr - Fill in the basic attributes from the inode struct
|
||||
* @inode: Inode to use as the source
|
||||
* @stat: Where to fill in the attributes
|
||||
*
|
||||
* Fill in the basic attributes in the kstat structure from data that's to be
|
||||
* found on the VFS inode structure. This is the default if no getattr inode
|
||||
* operation is supplied.
|
||||
*/
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_KSTAT
|
||||
extern void susfs_sus_ino_for_generic_fillattr(unsigned long ino, struct kstat *stat);
|
||||
#endif
|
||||
|
||||
55
fs/susfs.c
55
fs/susfs.c
@@ -1034,6 +1034,61 @@ struct filename* susfs_get_redirected_path(unsigned long ino) {
|
||||
}
|
||||
#endif // #ifdef CONFIG_KSU_SUSFS_OPEN_REDIRECT
|
||||
|
||||
/* sus_su */
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_SU
|
||||
extern int susfs_sus_su_working_mode;
|
||||
extern void ksu_susfs_enable_sus_su(void);
|
||||
extern void ksu_susfs_disable_sus_su(void);
|
||||
|
||||
int susfs_get_sus_su_working_mode(void) {
|
||||
return susfs_sus_su_working_mode;
|
||||
}
|
||||
|
||||
int susfs_sus_su(struct st_sus_su* __user user_info) {
|
||||
struct st_sus_su info;
|
||||
int last_working_mode = susfs_sus_su_working_mode;
|
||||
|
||||
if (copy_from_user(&info, user_info, sizeof(struct st_sus_su))) {
|
||||
SUSFS_LOGE("failed copying from userspace\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (info.mode == SUS_SU_WITH_HOOKS) {
|
||||
if (last_working_mode == SUS_SU_WITH_HOOKS) {
|
||||
SUSFS_LOGE("current sus_su mode is already %d\n", SUS_SU_WITH_HOOKS);
|
||||
return 1;
|
||||
}
|
||||
if (last_working_mode != SUS_SU_DISABLED) {
|
||||
SUSFS_LOGE("please make sure the current sus_su mode is %d first\n", SUS_SU_DISABLED);
|
||||
return 2;
|
||||
}
|
||||
ksu_susfs_enable_sus_su();
|
||||
SUSFS_LOGI("core kprobe hooks for ksu are disabled!\n");
|
||||
SUSFS_LOGI("non-kprobe hook sus_su is enabled!\n");
|
||||
SUSFS_LOGI("sus_su mode: %d\n", SUS_SU_WITH_HOOKS);
|
||||
return 0;
|
||||
} else if (info.mode == SUS_SU_DISABLED) {
|
||||
if (last_working_mode == SUS_SU_DISABLED) {
|
||||
SUSFS_LOGE("current sus_su mode is already %d\n", SUS_SU_DISABLED);
|
||||
return 1;
|
||||
}
|
||||
ksu_susfs_disable_sus_su();
|
||||
if (last_working_mode == SUS_SU_WITH_HOOKS) {
|
||||
SUSFS_LOGI("core kprobe hooks for ksu are enabled!\n");
|
||||
goto out;
|
||||
}
|
||||
out:
|
||||
if (copy_to_user(user_info, &info, sizeof(info)))
|
||||
SUSFS_LOGE("copy_to_user() failed\n");
|
||||
return 0;
|
||||
} else if (info.mode == SUS_SU_WITH_OVERLAY) {
|
||||
SUSFS_LOGE("sus_su mode %d is deprecated\n", SUS_SU_WITH_OVERLAY);
|
||||
return 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#endif // #ifdef CONFIG_KSU_SUSFS_SUS_SU
|
||||
|
||||
static int copy_config_to_buf(const char *config_string, char *buf_ptr, size_t *copied_size, size_t bufsize) {
|
||||
size_t tmp_size = strlen(config_string);
|
||||
|
||||
|
||||
@@ -2208,10 +2208,6 @@ struct task_struct {
|
||||
atomic_t stack_refcount;
|
||||
#endif
|
||||
/* CPU-specific state of this task */
|
||||
#ifdef CONFIG_KSU_SUSFS
|
||||
u64 susfs_task_state;
|
||||
u64 susfs_last_fake_mnt_id;
|
||||
#endif
|
||||
struct thread_struct thread;
|
||||
/*
|
||||
* WARNING: on x86, 'thread_struct' contains a variable-sized
|
||||
@@ -2219,6 +2215,11 @@ struct task_struct {
|
||||
*
|
||||
* Do not put anything below here!
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_KSU_SUSFS
|
||||
u64 susfs_task_state;
|
||||
u64 susfs_last_fake_mnt_id;
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef CONFIG_ARCH_WANTS_DYNAMIC_TASK_STRUCT
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
struct st_susfs_sus_path {
|
||||
unsigned long target_ino;
|
||||
char target_pathname[SUSFS_MAX_LEN_PATHNAME];
|
||||
unsigned int i_uid;
|
||||
unsigned int i_uid;
|
||||
};
|
||||
|
||||
struct st_susfs_sus_path_list {
|
||||
@@ -127,6 +127,13 @@ struct st_susfs_open_redirect_hlist {
|
||||
};
|
||||
#endif
|
||||
|
||||
/* sus_su */
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_SU
|
||||
struct st_sus_su {
|
||||
int mode;
|
||||
};
|
||||
#endif
|
||||
|
||||
/***********************/
|
||||
/* FORWARD DECLARATION */
|
||||
/***********************/
|
||||
@@ -180,6 +187,11 @@ int susfs_spoof_cmdline_or_bootconfig(struct seq_file *m);
|
||||
int susfs_add_open_redirect(struct st_susfs_open_redirect* __user user_info);
|
||||
struct filename* susfs_get_redirected_path(unsigned long ino);
|
||||
#endif
|
||||
/* sus_su */
|
||||
#ifdef CONFIG_KSU_SUSFS_SUS_SU
|
||||
int susfs_get_sus_su_working_mode(void);
|
||||
int susfs_sus_su(struct st_sus_su* __user user_info);
|
||||
#endif
|
||||
|
||||
int susfs_get_enabled_features(char __user* buf, size_t bufsize);
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#define CMD_SUSFS_SET_SDCARD_ROOT_PATH 0x55552
|
||||
#define CMD_SUSFS_ADD_SUS_MOUNT 0x55560
|
||||
#define CMD_SUSFS_HIDE_SUS_MNTS_FOR_ALL_PROCS 0x55561
|
||||
#define CMD_SUSFS_UMOUNT_FOR_ZYGOTE_ISO_SERVICE 0x55562
|
||||
#define CMD_SUSFS_ADD_SUS_KSTAT 0x55570
|
||||
#define CMD_SUSFS_UPDATE_SUS_KSTAT 0x55571
|
||||
#define CMD_SUSFS_ADD_SUS_KSTAT_STATICALLY 0x55572
|
||||
@@ -24,6 +25,9 @@
|
||||
#define CMD_SUSFS_SHOW_VERSION 0x555e1
|
||||
#define CMD_SUSFS_SHOW_ENABLED_FEATURES 0x555e2
|
||||
#define CMD_SUSFS_SHOW_VARIANT 0x555e3
|
||||
#define CMD_SUSFS_SHOW_SUS_SU_WORKING_MODE 0x555e4
|
||||
#define CMD_SUSFS_IS_SUS_SU_READY 0x555f0
|
||||
#define CMD_SUSFS_SUS_SU 0x60000
|
||||
|
||||
#define SUSFS_MAX_LEN_PATHNAME 256 // 256 should address many paths already unless you are doing some strange experimental stuff, then set your own desired length
|
||||
#define SUSFS_FAKE_CMDLINE_OR_BOOTCONFIG_SIZE 4096
|
||||
@@ -31,6 +35,10 @@
|
||||
#define TRY_UMOUNT_DEFAULT 0 /* used by susfs_try_umount() */
|
||||
#define TRY_UMOUNT_DETACH 1 /* used by susfs_try_umount() */
|
||||
|
||||
#define SUS_SU_DISABLED 0
|
||||
#define SUS_SU_WITH_OVERLAY 1 /* deprecated */
|
||||
#define SUS_SU_WITH_HOOKS 2
|
||||
|
||||
#define DEFAULT_SUS_MNT_ID 100000 /* used by mount->mnt_id */
|
||||
#define DEFAULT_SUS_MNT_ID_FOR_KSU_PROC_UNSHARE 1000000 /* used by vfsmount->susfs_mnt_id_backup */
|
||||
#define DEFAULT_SUS_MNT_GROUP_ID 1000 /* used by mount->mnt_group_id */
|
||||
@@ -40,7 +48,6 @@
|
||||
* mount->mnt.susfs_mnt_id_backup => storing original mnt_id of normal mounts or custom sus mnt_id of sus mounts
|
||||
* task_struct->susfs_task_state => storing flag 'TASK_STRUCT_'
|
||||
*/
|
||||
|
||||
#define INODE_STATE_SUS_PATH BIT(24)
|
||||
#define INODE_STATE_SUS_MOUNT BIT(25)
|
||||
#define INODE_STATE_SUS_KSTAT BIT(26)
|
||||
@@ -60,6 +67,7 @@
|
||||
|
||||
#define MAGIC_MOUNT_WORKDIR "/debug_ramdisk/workdir"
|
||||
#define DATA_ADB_UMOUNT_FOR_ZYGOTE_SYSTEM_PROCESS "/data/adb/susfs_umount_for_zygote_system_process"
|
||||
#define DATA_ADB_UMOUNT_FOR_ZYGOTE_ISO_SERVICE "/data/adb/susfs_umount_for_zygote_iso_service"
|
||||
#define DATA_ADB_NO_AUTO_ADD_SUS_BIND_MOUNT "/data/adb/susfs_no_auto_add_sus_bind_mount"
|
||||
#define DATA_ADB_NO_AUTO_ADD_SUS_KSU_DEFAULT_MOUNT "/data/adb/susfs_no_auto_add_sus_ksu_default_mount"
|
||||
#define DATA_ADB_NO_AUTO_ADD_TRY_UMOUNT_FOR_BIND_MOUNT "/data/adb/susfs_no_auto_add_try_umount_for_bind_mount"
|
||||
|
||||
Reference in New Issue
Block a user