Compare commits

..

11 Commits

Author SHA1 Message Date
Wang Han
121f9a8e90 Update su.rs 2025-05-17 16:28:11 +08:00
Wang Han
36446948ba Update Cargo.toml 2025-05-17 16:26:06 +08:00
Wang Han
8cf7b7ad20 Update Cargo.toml 2025-05-17 16:21:26 +08:00
Wang Han
05f032d13d Update Cargo.lock 2025-05-17 16:10:44 +08:00
Wang Han
8c12707e1e Update Cargo.toml 2025-05-17 14:36:44 +08:00
Wang Han
af8e984898 Update Cargo.toml 2025-05-17 14:35:49 +08:00
Wang Han
29565b7af1 Update Cargo.lock 2025-05-17 14:33:12 +08:00
Wang Han
50770b287d Update Cargo.lock 2025-05-17 14:21:06 +08:00
Wang Han
5efc1ee549 Update build.rs 2025-05-17 14:14:03 +08:00
Wang Han
de164dd18e Update build.rs 2025-05-17 14:12:13 +08:00
Wang Han
dd9bc4d995 Update Cargo.lock 2025-05-17 14:09:53 +08:00
37 changed files with 226 additions and 388 deletions

1
.github/FUNDING.yml vendored
View File

@@ -2,3 +2,4 @@
github: tiann
patreon: weishu
custom: https://vxposed.com/donate.html

View File

@@ -27,10 +27,6 @@ jobs:
os_patch_level: 2024-08
- sub_level: 226
os_patch_level: 2024-11
- sub_level: 233
os_patch_level: 2025-02
- sub_level: 236
os_patch_level: 2025-05
uses: ./.github/workflows/gki-kernel.yml
secrets: inherit
with:

View File

@@ -36,12 +36,6 @@ jobs:
- version: "5.10"
sub_level: 223
os_patch_level: 2024-11
- version: "5.10"
sub_level: 228
os_patch_level: 2025-01
- version: "5.10"
sub_level: 234
os_patch_level: 2025-03
- version: "5.15"
sub_level: 148
os_patch_level: 2024-05
@@ -57,15 +51,6 @@ jobs:
- version: "5.15"
sub_level: 167
os_patch_level: 2024-11
- version: "5.15"
sub_level: 178
os_patch_level: 2024-11
- version: "5.15"
sub_level: 170
os_patch_level: 2025-01
- version: "5.15"
sub_level: 178
os_patch_level: 2025-03
uses: ./.github/workflows/gki-kernel.yml
secrets: inherit
with:

View File

@@ -39,12 +39,6 @@ jobs:
- version: "5.15"
sub_level: 167
os_patch_level: 2024-11
- version: "5.15"
sub_level: 170
os_patch_level: 2025-01
- version: "5.15"
sub_level: 178
os_patch_level: 2025-03
- version: "6.1"
sub_level: 75
os_patch_level: 2024-05
@@ -69,15 +63,6 @@ jobs:
- version: "6.1"
sub_level: 115
os_patch_level: 2024-12
- version: "6.1"
sub_level: 118
os_patch_level: 2025-01
- version: "6.1"
sub_level: 128
os_patch_level: 2025-03
- version: "6.1"
sub_level: 134
os_patch_level: 2025-05
uses: ./.github/workflows/gki-kernel.yml
secrets: inherit
with:

View File

@@ -36,21 +36,6 @@ jobs:
- version: "6.6"
sub_level: 57
os_patch_level: 2024-12
- version: "6.6"
sub_level: 58
os_patch_level: 2025-01
- version: "6.6"
sub_level: 66
os_patch_level: 2025-02
- version: "6.6"
sub_level: 77
os_patch_level: 2025-03
- version: "6.6"
sub_level: 82
os_patch_level: 2025-04
- version: "6.6"
sub_level: 87
os_patch_level: 2025-05
uses: ./.github/workflows/gki-kernel.yml
secrets: inherit
with:

View File

@@ -15,8 +15,8 @@ jobs:
matrix:
include:
- version: "android12-5.10"
sub_level: 236
os_patch_level: 2025-05
sub_level: 233
os_patch_level: 2025-02
- version: "android13-5.10"
sub_level: 234
os_patch_level: 2025-03
@@ -27,11 +27,11 @@ jobs:
sub_level: 178
os_patch_level: 2025-03
- version: "android14-6.1"
sub_level: 134
os_patch_level: 2025-05
sub_level: 128
os_patch_level: 2025-03
- version: "android15-6.6"
sub_level: 87
os_patch_level: 2025-05
sub_level: 77
os_patch_level: 2025-03
uses: ./.github/workflows/gki-kernel.yml
with:
version: ${{ matrix.version }}

View File

@@ -108,7 +108,6 @@ static void setup_groups(struct root_profile *profile, struct cred *cred)
groups_sort(group_info);
set_groups(cred, group_info);
put_group_info(group_info);
}
static void disable_seccomp()
@@ -133,18 +132,18 @@ void escape_to_root(void)
{
struct cred *cred;
cred = prepare_creds();
if (!cred) {
pr_warn("prepare_creds failed!\n");
return;
}
rcu_read_lock();
do {
cred = (struct cred *)__task_cred((current));
BUG_ON(!cred);
} while (!get_cred_rcu(cred));
if (cred->euid.val == 0) {
pr_warn("Already root, don't escape!\n");
abort_creds(cred);
rcu_read_unlock();
return;
}
struct root_profile *profile = ksu_get_root_profile(cred->uid.val);
cred->uid.val = profile->uid;
@@ -175,7 +174,7 @@ void escape_to_root(void)
setup_groups(profile, cred);
commit_creds(cred);
rcu_read_unlock();
// Refer to kernel/seccomp.c: seccomp_set_mode_strict
// When disabling Seccomp, ensure that current->sighand->siglock is held during the operation.
@@ -242,7 +241,7 @@ static void nuke_ext4_sysfs() {
}
ext4_unregister_sysfs(sb);
path_put(&path);
path_put(&path);
}
int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
@@ -413,17 +412,6 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
return 0;
}
if (arg2 == CMD_GET_MANAGER_UID) {
uid_t manager_uid = ksu_get_manager_uid();
if (copy_to_user(arg3, &manager_uid, sizeof(manager_uid))) {
pr_err("get manager uid failed\n");
}
if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) {
pr_err("prctl reply error, cmd: %lu\n", arg2);
}
return 0;
}
// all other cmds are for 'root manager'
if (!from_manager) {
return 0;
@@ -552,13 +540,11 @@ static void try_umount(const char *mnt, bool check_mnt, int flags)
if (path.dentry != path.mnt->mnt_root) {
// it is not root mountpoint, maybe umounted by others already.
path_put(&path);
return;
}
// we are only interest in some specific mounts
if (check_mnt && !should_umount(&path)) {
path_put(&path);
return;
}

View File

@@ -23,7 +23,6 @@
#define CMD_UID_SHOULD_UMOUNT 13
#define CMD_IS_SU_ENABLED 14
#define CMD_ENABLE_SU 15
#define CMD_GET_MANAGER_UID 16
#define EVENT_POST_FS_DATA 1
#define EVENT_BOOT_COMPLETED 2

View File

@@ -19,24 +19,19 @@
static struct policydb *get_policydb(void)
{
struct policydb *db;
struct selinux_policy *policy = selinux_state.policy;
struct selinux_policy *policy = rcu_dereference(selinux_state.policy);
db = &policy->policydb;
return db;
}
static DEFINE_MUTEX(ksu_rules);
void apply_kernelsu_rules()
{
struct policydb *db;
if (!getenforce()) {
pr_info("SELinux permissive or disabled, apply rules!\n");
}
mutex_lock(&ksu_rules);
db = get_policydb();
rcu_read_lock();
struct policydb *db = get_policydb();
ksu_permissive(db, KERNEL_SU_DOMAIN);
ksu_typeattribute(db, KERNEL_SU_DOMAIN, "mlstrustedsubject");
@@ -123,11 +118,11 @@ void apply_kernelsu_rules()
// Allow all binder transactions
ksu_allow(db, ALL, KERNEL_SU_DOMAIN, "binder", ALL);
// Allow system server kill su process
ksu_allow(db, "system_server", KERNEL_SU_DOMAIN, "process", "getpgid");
ksu_allow(db, "system_server", KERNEL_SU_DOMAIN, "process", "sigkill");
// Allow system server kill su process
ksu_allow(db, "system_server", KERNEL_SU_DOMAIN, "process", "getpgid");
ksu_allow(db, "system_server", KERNEL_SU_DOMAIN, "process", "sigkill");
mutex_unlock(&ksu_rules);
rcu_read_unlock();
}
#define MAX_SEPOL_LEN 128
@@ -189,8 +184,6 @@ static void reset_avc_cache()
int handle_sepolicy(unsigned long arg3, void __user *arg4)
{
struct policydb *db;
if (!arg4) {
return -1;
}
@@ -208,9 +201,9 @@ int handle_sepolicy(unsigned long arg3, void __user *arg4)
u32 cmd = data.cmd;
u32 subcmd = data.subcmd;
mutex_lock(&ksu_rules);
rcu_read_lock();
db = get_policydb();
struct policydb *db = get_policydb();
int ret = -1;
if (cmd == CMD_NORMAL_PERM) {
@@ -460,7 +453,7 @@ int handle_sepolicy(unsigned long arg3, void __user *arg4)
}
exit:
mutex_unlock(&ksu_rules);
rcu_read_unlock();
// only allow and xallow needs to reset avc cache, but we cannot do that because
// we are in atomic context. so we just reset it every time.

View File

@@ -213,8 +213,7 @@ void search_manager(const char *path, int depth, struct list_head *uid_data)
int i, stop = 0;
struct list_head data_path_list;
INIT_LIST_HEAD(&data_path_list);
unsigned long data_app_magic = 0;
// Initialize APK cache list
struct apk_path_hash *pos, *n;
list_for_each_entry(pos, &apk_path_hash_list, list) {
@@ -245,24 +244,6 @@ void search_manager(const char *path, int depth, struct list_head *uid_data)
pr_err("Failed to open directory: %s, err: %ld\n", pos->dirpath, PTR_ERR(file));
goto skip_iterate;
}
// grab magic on first folder, which is /data/app
if (!data_app_magic) {
if (file->f_inode->i_sb->s_magic) {
data_app_magic = file->f_inode->i_sb->s_magic;
pr_info("%s: dir: %s got magic! 0x%lx\n", __func__, pos->dirpath, data_app_magic);
} else {
filp_close(file, NULL);
goto skip_iterate;
}
}
if (file->f_inode->i_sb->s_magic != data_app_magic) {
pr_info("%s: skip: %s magic: 0x%lx expected: 0x%lx\n", __func__, pos->dirpath,
file->f_inode->i_sb->s_magic, data_app_magic);
filp_close(file, NULL);
goto skip_iterate;
}
iterate_dir(file, &ctx.ctx);
filp_close(file, NULL);

View File

@@ -92,10 +92,6 @@ android {
}
}
ksp {
arg("compose-destinations.defaultTransitions", "none")
}
dependencies {
implementation(libs.androidx.activity.compose)
implementation(libs.androidx.navigation.compose)

View File

@@ -50,13 +50,12 @@ bool become_manager(const char* pkg) {
}
// cache the result to avoid unnecessary syscall
static bool is_lkm = false;
int get_version(void) {
static bool is_lkm;
int get_version() {
int32_t version = -1;
int32_t flags = 0;
ksuctl(CMD_GET_VERSION, &version, &flags);
if (!is_lkm && (flags & 0x1)) {
int32_t lkm = 0;
ksuctl(CMD_GET_VERSION, &version, &lkm);
if (!is_lkm && lkm != 0) {
is_lkm = true;
}
return version;
@@ -97,4 +96,4 @@ bool is_su_enabled() {
// if ksuctl failed, we assume su is enabled, and it cannot be disabled.
ksuctl(CMD_IS_SU_ENABLED, &enabled, nullptr);
return enabled;
}
}

View File

@@ -11,9 +11,6 @@ import androidx.compose.animation.ExitTransition
import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.scaleOut
import androidx.compose.animation.slideInHorizontally
import androidx.compose.animation.slideOutHorizontally
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.WindowInsetsSides
import androidx.compose.foundation.layout.displayCutout
@@ -62,16 +59,13 @@ class MainActivity : ComponentActivity() {
super.onCreate(savedInstanceState)
val isManager = Natives.becomeManager(ksuApp.packageName)
if (isManager) install()
val isManager = Natives.becomeManager(ksuApp.packageName)
if (isManager) install()
setContent {
KernelSUTheme {
val navController = rememberNavController()
val snackBarHostState = remember { SnackbarHostState() }
val bottomBarRoutes = remember {
BottomBarDestination.entries.map { it.direction.route }.toSet()
}
Scaffold(
bottomBar = { BottomBar(navController) },
contentWindowInsets = WindowInsets(0, 0, 0, 0)
@@ -84,45 +78,10 @@ class MainActivity : ComponentActivity() {
navGraph = NavGraphs.root,
navController = navController,
defaultTransitions = object : NavHostAnimatedDestinationStyle() {
override val enterTransition: AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition = {
// If the target is a detail page (not a bottom navigation page), slide in from the right
if (targetState.destination.route !in bottomBarRoutes) {
slideInHorizontally(initialOffsetX = { it })
} else {
// Otherwise (switching between bottom navigation pages), use fade in
fadeIn(animationSpec = tween(340))
}
}
override val exitTransition: AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition = {
// If navigating from the home page (bottom navigation page) to a detail page, slide out to the left
if (initialState.destination.route in bottomBarRoutes && targetState.destination.route !in bottomBarRoutes) {
slideOutHorizontally(targetOffsetX = { -it / 4 }) + fadeOut()
} else {
// Otherwise (switching between bottom navigation pages), use fade out
fadeOut(animationSpec = tween(340))
}
}
override val popEnterTransition: AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition = {
// If returning to the home page (bottom navigation page), slide in from the left
if (targetState.destination.route in bottomBarRoutes) {
slideInHorizontally(initialOffsetX = { -it / 4 }) + fadeIn()
} else {
// Otherwise (e.g., returning between multiple detail pages), use default fade in
fadeIn(animationSpec = tween(340))
}
}
override val popExitTransition: AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition = {
// If returning from a detail page (not a bottom navigation page), scale down and fade out
if (initialState.destination.route !in bottomBarRoutes) {
scaleOut(targetScale = 0.9f) + fadeOut()
} else {
// Otherwise, use default fade out
fadeOut(animationSpec = tween(340))
}
}
override val enterTransition: AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition
get() = { fadeIn(animationSpec = tween(340)) }
override val exitTransition: AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition
get() = { fadeOut(animationSpec = tween(340)) }
}
)
}

View File

@@ -81,9 +81,9 @@ fun createRootShell(globalMnt: Boolean = false): Shell {
Log.w(TAG, "ksu failed: ", e)
try {
if (globalMnt) {
builder.build("su", "-mm")
} else {
builder.build("su")
} else {
builder.build("su", "-mm")
}
} catch (e: Throwable) {
Log.e(TAG, "su failed: ", e)

View File

@@ -129,10 +129,6 @@ class ModuleViewModel : ViewModel() {
}
}
private fun sanitizeVersionString(version: String): String {
return version.replace(Regex("[^a-zA-Z0-9.\\-_]"), "_")
}
fun checkUpdate(m: ModuleInfo): Triple<String, String, String> {
val empty = Triple("", "", "")
if (m.updateJson.isEmpty() || m.remove || m.update || !m.enabled) {
@@ -162,8 +158,7 @@ class ModuleViewModel : ViewModel() {
JSONObject(result)
}.getOrNull() ?: return empty
var version = updateJson.optString("version", "")
version = sanitizeVersionString(version)
val version = updateJson.optString("version", "")
val versionCode = updateJson.optInt("versionCode", 0)
val zipUrl = updateJson.optString("zipUrl", "")
val changelog = updateJson.optString("changelog", "")
@@ -173,4 +168,4 @@ class ModuleViewModel : ViewModel() {
return Triple(zipUrl, version, changelog)
}
}
}

View File

@@ -133,6 +133,4 @@
<string name="shrink_sparse_image">Spärliches Bild minimieren</string>
<string name="action">Aktion</string>
<string name="log_saved">Protokolle gespeichert</string>
<string name="module_install_prompt_with_name">Folgende Module werden installiert: %1$s</string>
<string name="confirm">Bestätigen</string>
</resources>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="home">ទំព័រដើម</string>
<string name="home_not_installed">មិនទាន់បានដំឡើង</string>
<string name="home_click_to_install">ចុចដើម្បីដំឡើង</string>
</resources>

View File

@@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources></resources>

View File

@@ -8,20 +8,20 @@
<string name="profile_groups">Nhóm</string>
<string name="failed_to_update_app_profile">Không thể cập nhật Hồ sơ ứng dụng cho %s</string>
<string name="settings_umount_modules_default">Ngắt mô-đun theo mặc định</string>
<string name="settings_umount_modules_default_summary">Giá trị mặc định chung cho \"Ngắt mô-đun\" trong Hồ sơ ứng dụng. Khi bật, mọi thay đổi từ mô-đun sẽ bị loại bỏ khỏi hệ thống đối với các ứng dụng chưa được gán hồ sơ riêng.</string>
<string name="profile_umount_modules_summary">Bật tùy chọn này sẽ cho phép KernelSU khôi phục bất kỳ tệp đã sửa đổi bởi các mô-đun cho ứng dụng này.</string>
<string name="settings_umount_modules_default_summary">Giá trị mặc định của \"Ngắt mô-đun\" trong Cấu hình ứng dụng. Nếu bật, KernelSU sẽ khôi phục mọi tệp hệ thống đã sửa đổi bởi mô-đun cho các ứng dụng chưa thiết lập Cấu hình.</string>
<string name="profile_umount_modules_summary">Bật tùy chọn này sẽ khôi phục mọi tệp đã sửa đổi bởi các mô-đun cho ứng dụng này.</string>
<string name="module_update">Cập nhật</string>
<string name="module_downloading">Đang tải xuống mô-đun: %s</string>
<string name="module_start_downloading">Bắt đầu tải xuống: %s</string>
<string name="new_version_available">Có phiên bản mới %s, nhấn vào đây để cập nhật.</string>
<string name="home_learn_kernelsu">Tìm hiểu thêm về KernelSU</string>
<string name="new_version_available">Phiên bản mới: %s đã có, bấm để nâng cấp</string>
<string name="home_learn_kernelsu">Tìm hiểu KernelSU</string>
<string name="home_click_to_learn_kernelsu">Tìm hiểu cách cài đặt KernelSU và sử dụng các mô-đun</string>
<string name="home_support_title">Hỗ trợ chúng tôi</string>
<string name="home_support_content">KernelSU sẽ luôn miễn phí, mã nguồn mở. Nếu bạn thấy hữu ích, hãy ủng hộ chúng tôi bằng một khoản quyên góp nhỏ.</string>
<string name="about_source_code"><![CDATA[View source code at %1$s<br/>Tham gia kênh %2$s của chúng tôi]]></string>
<string name="module_magisk_conflict">Module không hoạt động do xung đột với Magisk!</string>
<string name="home_support_content">KernelSU sẽ luôn luôn miễn phí mã nguồn mở. Tuy nhiên bạn có thể ủng hộ chúng tôi bằng một khoản đóng góp nhỏ.</string>
<string name="about_source_code"><![CDATA[Xem mã nguồn tại %1$s<br/>Tham gia kênh %2$s của chúng tôi]]></string>
<string name="module_magisk_conflict">Các mô-đun bị vô hiệu hóa vì chúng xung đột với Magisk!</string>
<string name="module_uninstall_confirm">Bạn có muốn gỡ cài đặt mô-đun %s không\?</string>
<string name="send_log">Gửi nhật ký</string>
<string name="send_log">Nhật ký báo cáo</string>
<string name="home">Trang chủ</string>
<string name="home_not_installed">Chưa cài đặt</string>
<string name="home_click_to_install">Nhấn để cài đặt</string>
@@ -30,14 +30,14 @@
<string name="home_unsupported">Không được hỗ trợ</string>
<string name="home_unsupported_reason">KernelSU hiện tại chỉ hỗ trợ kernel GKI</string>
<string name="home_kernel">Kernel</string>
<string name="home_manager_version">Phiên bản trình quản lý</string>
<string name="home_manager_version">Phiên bản Manager</string>
<string name="home_fingerprint">Fingerprint</string>
<string name="home_selinux_status">Trạng thái SELinux</string>
<string name="selinux_status_disabled">Vô hiệu hóa</string>
<string name="selinux_status_enforcing">Thực thi</string>
<string name="selinux_status_permissive">Cho phép</string>
<string name="selinux_status_unknown">Không rõ</string>
<string name="superuser">Siêu người dùng</string>
<string name="superuser">SuperUser</string>
<string name="module_failed_to_enable">Không thể kích hoạt mô-đun: %s</string>
<string name="module_failed_to_disable">Không thể vô hiệu hóa mô-đun: %s</string>
<string name="module_empty">Chưa cài đặt mô-đun nào</string>
@@ -46,97 +46,90 @@
<string name="module_install">Cài đặt</string>
<string name="install">Cài đặt</string>
<string name="reboot">Khởi động lại</string>
<string name="settings">Cài đặt</string>
<string name="settings">Thiết đặt</string>
<string name="reboot_userspace">Khởi động mềm</string>
<string name="reboot_recovery">Khởi động vào Recovery</string>
<string name="reboot_bootloader">Khởi động vào Bootloader</string>
<string name="reboot_download">Khởi động vào Download</string>
<string name="reboot_edl">Khởi động vào EDL</string>
<string name="reboot_recovery">Khởi động lại vào Recovery</string>
<string name="reboot_bootloader">Khởi động lại vào Bootloader</string>
<string name="reboot_download">Khởi động lại vào Download Mode</string>
<string name="reboot_edl">Khởi động lại vào EDL</string>
<string name="about">Giới thiệu</string>
<string name="module_uninstall_success">Đã gỡ cài đặt %s</string>
<string name="module_uninstall_failed">Không thể gỡ cài đặt: %s</string>
<string name="module_uninstall_success">%s được gỡ cài đặt</string>
<string name="module_uninstall_failed">Lỗi khi gỡ cài đặt: %s</string>
<string name="module_version">Phiên bản</string>
<string name="module_author">Tác giả</string>
<string name="module_overlay_fs_not_available">Module không hoạt động vì OverlayFS đã bị kernel vô hiệu hóa!</string>
<string name="module_overlay_fs_not_available">overlayfs hiện không khả dụng, mô-đun không thể hoạt động!</string>
<string name="refresh">Làm mới</string>
<string name="show_system_apps">Hiển thị ứng dụng hệ thống</string>
<string name="hide_system_apps">Ẩn ứng dụng hệ thống</string>
<string name="safe_mode">Chế độ an toàn</string>
<string name="reboot_to_apply">Khởi động lại để áp dụng thay đổi</string>
<string name="home_learn_kernelsu_url">https://kernelsu.org/guide/what-is-kernelsu.html</string>
<string name="reboot_to_apply">Khởi động lại để có hiệu lực</string>
<string name="home_learn_kernelsu_url">https://kernelsu.org/vi_VN/guide/what-is-kernelsu.html</string>
<string name="home_superuser_count">Số superuser: %d</string>
<string name="home_module_count">Số mô-đun: %d</string>
<string name="profile_selinux_domain">Phạm vi</string>
<string name="profile_selinux_rules">Quy tắc</string>
<string name="profile_selinux_rules">Quy định</string>
<string name="launch_app">Khởi chạy</string>
<string name="restart_app">Khởi động lại</string>
<string name="profile_namespace">Gắn namespace</string>
<string name="profile_capabilities">Quyền</string>
<string name="failed_to_update_sepolicy">Không thể cập nhật quy tắc SELinux cho %s</string>
<string name="failed_to_update_sepolicy">Không thể cập nhật quy định SELinux cho: %s</string>
<string name="force_stop_app">Buộc dừng</string>
<string name="profile_namespace_inherited">Inherited</string>
<string name="profile_namespace_global">Global</string>
<string name="profile_namespace_individual">Individual</string>
<string name="profile_namespace_inherited">Thừa hưởng</string>
<string name="profile_namespace_global">Chung</string>
<string name="profile_namespace_individual">Riêng</string>
<string name="profile_selinux_context">Bối cảnh SELinux</string>
<string name="profile_umount_modules">Ngắt mô-đun</string>
<string name="require_kernel_version">Phiên bản KernelSU bạn đang dùng (%d) quá để trình quản lý hoạt động ổn định. Hãy cập nhật từ phiên bản %d trở lên!</string>
<string name="require_kernel_version">KernelSU phiên bản %d quá thấp để trình quản lý hoạt động, hãy cập nhật lên %d hoặc mới hơn!</string>
<string name="app_profile_template_import_success">Đã nhập thành công</string>
<string name="app_profile_export_to_clipboard">Xuất vào bảng nhớ tạm</string>
<string name="app_profile_template_export_empty">Không có mẫu nào để xuất!</string>
<string name="app_profile_template_id_exist">ID mẫu đã tồn tại!</string>
<string name="app_profile_export_to_clipboard">Xuất từ khay nhớ tạm</string>
<string name="app_profile_template_export_empty">Không thể tìm thấy mẫu cục bộ để xuất!</string>
<string name="app_profile_template_id_exist">id bản mẫu đã tồn tại!</string>
<string name="module_changelog">Nhật ký thay đổi</string>
<string name="app_profile_import_from_clipboard">Nhập từ bảng nhớ tạm</string>
<string name="app_profile_import_from_clipboard">Nhập từ khay nhớ tạm</string>
<string name="module_changelog_failed">Không nạp được nhật ký thay đổi: %s</string>
<string name="app_profile_template_name">Tên</string>
<string name="app_profile_template_id_invalid">ID mẫu không hợp lệ</string>
<string name="app_profile_template_sync">Đồng bộ mẫu trực tuyến</string>
<string name="app_profile_template_create">Tạo mẫu</string>
<string name="app_profile_template_id_invalid">Id mẫu không hợp lệ</string>
<string name="app_profile_template_sync">Đồng bộ hóa các mẫu trực tuyến</string>
<string name="app_profile_template_create">Tạo Bản Mẫu</string>
<string name="app_profile_import_export">Nhập/Xuất</string>
<string name="app_profile_template_save_failed">Không lưu được mẫu</string>
<string name="app_profile_template_edit">Sửa mẫu</string>
<string name="app_profile_template_edit">Sửa Bản Mẫu</string>
<string name="settings_profile_template">Mẫu Hồ Sơ Ứng Dụng</string>
<string name="app_profile_template_description">Mô tả</string>
<string name="app_profile_template_save">Lưu</string>
<string name="settings_profile_template_summary">Quản lý mẫu Hồ sơ Ứng dụng và trực tuyến</string>
<string name="settings_profile_template_summary">Quản lý mẫu Hồ sơ Ứng dụng cục bộ và trực tuyến</string>
<string name="app_profile_template_delete">Xóa</string>
<string name="app_profile_template_import_empty">Bảng nhớ tạm đang trống!</string>
<string name="app_profile_template_view">Xem mẫu</string>
<string name="app_profile_template_readonly">Chỉ đọc</string>
<string name="app_profile_template_id">ID</string>
<string name="app_profile_template_import_empty">Clipboard trống!</string>
<string name="app_profile_template_view">Xem Bản Mẫu</string>
<string name="app_profile_template_readonly">chỉ đọc</string>
<string name="app_profile_template_id">id</string>
<string name="enable_web_debugging">Bật gỡ lỗi WebView</string>
<string name="enable_web_debugging_summary">Có thể ng để gỡ lỗi WebUI. Vui lòng chỉ bật khi cần thiết.</string>
<string name="enable_web_debugging_summary">Có thể được sử dụng để gỡ lỗi WebUI, vui lòng chỉ bật khi cần.</string>
<string name="grant_root_failed">Không cấp được quyền root!</string>
<string name="settings_check_update">Kiểm tra cập nhật</string>
<string name="settings_check_update_summary">Tự động kiểm tra cập nhật khi mở ứng dụng</string>
<string name="open">Mở</string>
<string name="install_inactive_slot">Cài đặt vào phân vùng không hoạt động (Sau khi cập nhật OTA)</string>
<string name="install_inactive_slot_warning">Thiết bị của bạn sẽ **BẮT BUỘC** khởi động vào phân vùng không hoạt động hiện tại sau khi khởi động lại!\nChỉ dùng tùy chọn này khi cập nhật OTA đã hoàn tất.\nTiếp tục?</string>
<string name="install_inactive_slot">Cài đặt vào khe không hoạt động (Sau OTA)</string>
<string name="install_inactive_slot_warning">Thiết bị của bạn sẽ **BẮT BUỘC** khởi động vào khe không hoạt động hiện tại sau khi khởi động lại!
\nChỉ sử dụng tùy chọn này sau khi OTA hoàn tất.
\nTiếp tục?</string>
<string name="settings_uninstall_temporary_message">Tạm thời gỡ cài đặt KernelSU, khôi phục về trạng thái ban đầu sau lần khởi động lại tiếp theo.</string>
<string name="select_kmi">Chọn KMI</string>
<string name="install_next">Kế tiếp</string>
<string name="direct_install">Cài đặt trực tiếp (Khuyến nghị)</string>
<string name="direct_install">Cài đặt trực tiếp (Được khuyến nghị)</string>
<string name="select_file">Chọn một tệp</string>
<string name="settings_uninstall">Gỡ cài đặt</string>
<string name="settings_uninstall_temporary">Gỡ cài đặt tạm thời</string>
<string name="settings_uninstall_permanent">Gỡ cài đặt vĩnh viễn</string>
<string name="settings_restore_stock_image">Khôi phục hình ảnh gốc</string>
<string name="settings_uninstall_permanent_message">Gỡ hoàn toàn KernelSU khỏi thiết bị, bao gồm cả quyền root và tất cả mô-đun đã cài.</string>
<string name="settings_restore_stock_image_message">Khôi phục hình ảnh gốc nhà máy (nếu bạn đã sao lưu trước đó), thường thực hiện trước khi cập nhật OTA; còn nếu muốn gỡ cài đặt KernelSU thì hãy chọn “Gỡ cài đặt vĩnh viễn.</string>
<string name="settings_uninstall_permanent_message">Gỡ cài đặt KernelSU (Root và tất cả các mô-đun) hoàn toàn và vĩnh viễn.</string>
<string name="settings_restore_stock_image_message">Khôi phục hình ảnh gốc của nhà máy (nếu có bản sao lưu), thường được sử dụng trước OTA; nếu bạn cần gỡ cài đặt KernelSU, vui lòng sử dụng \"Gỡ cài đặt vĩnh viễn\".</string>
<string name="flashing">Đang cài</string>
<string name="flash_success">Cài thành công</string>
<string name="flash_failed">Cài thất bại</string>
<string name="selected_lkm">Đã chọn LKM: %s</string>
<string name="selected_lkm">Đã chọn lkm: %s</string>
<string name="select_file_tip">Nên sử dụng hình ảnh phân vùng %1$s</string>
<string name="shrink_sparse_image">Giảm kích thước hình ảnh sparse</string>
<string name="shrink_sparse_image_message">Thay đổi kích thước hình ảnh sparse chứa mô-đun về đúng kích thước thực của nó. Lưu ý điều này có thể khiến mô-đun hoạt động không ổn định, vui lòng chỉ sử dụng khi cần thiết (Chẳng hạn như khi sao lưu).</string>
<string name="shrink_sparse_image">Giảm thiểu hình ảnh thưa thớt</string>
<string name="shrink_sparse_image_message">Thay đổi kích thước hình ảnh thưa nơi đặt mô-đun theo kích thước thực tế của nó. Lưu ý điều này có thể khiến module hoạt động không bình thường nên vui lòng chỉ sử dụng khi cần thiết (chẳng hạn như để sao lưu)</string>
<string name="save_log">Lưu Nhật Ký</string>
<string name="module_sort_action_first">Sắp xếp (Hoạt động trước)</string>
<string name="module_install_prompt_with_name">Các mô-đun sau sẽ được cài đặt: %1$s</string>
<string name="confirm">Xác nhận</string>
<string name="module_sort_enabled_first">Sắp xếp (Đã bật trước)</string>
<string name="su_not_allowed">Không thể cấp quyền Superuser cho %s</string>
<string name="action">Hoạt động</string>
<string name="log_saved">Đã lưu nhật ký</string>
<string name="settings_disable_su_summary">Tạm thời ngăn các ứng dụng mới sử dụng quyền root qua lệnh su (các tiến trình đã được cấp quyền root sẽ không bị ảnh hưởng).</string>
<string name="settings_disable_su">Tắt khả năng tương thích với su</string>
</resources>

View File

@@ -1,17 +1,17 @@
[versions]
agp = "8.12.0"
kotlin = "2.2.0"
ksp = "2.2.0-2.0.2"
compose-bom = "2025.07.00"
lifecycle = "2.9.2"
navigation = "2.9.3"
agp = "8.10.0"
kotlin = "2.1.21"
ksp = "2.1.20-2.0.1"
compose-bom = "2025.05.00"
lifecycle = "2.9.0"
navigation = "2.9.0"
activity-compose = "1.10.1"
kotlinx-coroutines = "1.10.2"
coil-compose = "2.7.0"
compose-destination = "2.2.0"
sheets-compose-dialogs = "1.3.0"
markdown = "4.6.2"
webkit = "1.14.0"
webkit = "1.13.0"
appiconloader-coil = "1.5.0"
parcelablelist = "2.0.1"
libsu = "6.0.0"
@@ -71,4 +71,4 @@ sheet-compose-dialogs-input = { group = "com.maxkeppeler.sheets-compose-dialogs"
markdown = { group = "io.noties.markwon", name = "core", version.ref = "markdown" }
lsposed-cxx = { module = "org.lsposed.libcxx:libcxx", version = "28.1.13356709" }
lsposed-cxx = { module = "org.lsposed.libcxx:libcxx", version = "27.0.12077973" }

View File

@@ -483,6 +483,17 @@ dependencies = [
"crypto-common",
]
[[package]]
name = "displaydoc"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "either"
version = "1.15.0"
@@ -584,7 +595,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece"
dependencies = [
"crc32fast",
"libz-rs-sys",
"miniz_oxide",
]
@@ -672,7 +682,7 @@ dependencies = [
"errno 0.2.8",
"libc",
"memmap",
"thiserror",
"thiserror 1.0.69",
"winapi",
]
@@ -873,15 +883,6 @@ version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de"
[[package]]
name = "libz-rs-sys"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "172a788537a2221661b480fee8dc5f96c580eb34fa88764d3205dc356c7e4221"
dependencies = [
"zlib-rs",
]
[[package]]
name = "linux-raw-sys"
version = "0.4.15"
@@ -1310,7 +1311,16 @@ version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
dependencies = [
"thiserror-impl",
"thiserror-impl 1.0.69",
]
[[package]]
name = "thiserror"
version = "2.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc"
dependencies = [
"thiserror-impl 2.0.11",
]
[[package]]
@@ -1324,6 +1334,17 @@ dependencies = [
"syn",
]
[[package]]
name = "thiserror-impl"
version = "2.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "time"
version = "0.3.41"
@@ -1704,10 +1725,12 @@ dependencies = [
"arbitrary",
"crc32fast",
"deflate64",
"displaydoc",
"flate2",
"indexmap",
"lzma-rs",
"memchr",
"thiserror 2.0.11",
"time",
"xz2",
"zopfli",
@@ -1722,12 +1745,6 @@ dependencies = [
"zip",
]
[[package]]
name = "zlib-rs"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "626bd9fa9734751fc50d6060752170984d7053f5a39061f524cda68023d4db8a"
[[package]]
name = "zopfli"
version = "0.8.2"

Binary file not shown.

Binary file not shown.

View File

@@ -14,7 +14,7 @@ fn get_git_version() -> Result<(u32, String), std::io::Error> {
let version_code: u32 = version_code
.trim()
.parse()
.map_err(|_| std::io::Error::other("Failed to parse git count"))?;
.map_err(|_| std::io::Error::new(std::io::ErrorKind::Other, "Failed to parse git count"))?;
let version_code = 10000 + 200 + version_code; // For historical reasons
let version_name = String::from_utf8(
@@ -23,7 +23,12 @@ fn get_git_version() -> Result<(u32, String), std::io::Error> {
.output()?
.stdout,
)
.map_err(|_| std::io::Error::other("Failed to read git describe stdout"))?;
.map_err(|_| {
std::io::Error::new(
std::io::ErrorKind::Other,
"Failed to read git describe stdout",
)
})?;
let version_name = version_name.trim_start_matches('v').to_string();
Ok((version_code, version_name))
}

View File

@@ -153,40 +153,38 @@ fn parse_kmi_from_boot(magiskboot: &Path, image: &PathBuf, workdir: &Path) -> Re
parse_kmi_from_kernel(&image_path, workdir)
}
fn do_cpio_cmd(magiskboot: &Path, workdir: &Path, cpio_path: &Path, cmd: &str) -> Result<()> {
fn do_cpio_cmd(magiskboot: &Path, workdir: &Path, cmd: &str) -> Result<()> {
let status = Command::new(magiskboot)
.current_dir(workdir)
.stdout(Stdio::null())
.stderr(Stdio::null())
.arg("cpio")
.arg(cpio_path)
.arg("ramdisk.cpio")
.arg(cmd)
.status()?;
ensure!(status.success(), "magiskboot cpio {} failed", cmd);
Ok(())
}
fn is_magisk_patched(magiskboot: &Path, workdir: &Path, cpio_path: &Path) -> Result<bool> {
fn is_magisk_patched(magiskboot: &Path, workdir: &Path) -> Result<bool> {
let status = Command::new(magiskboot)
.current_dir(workdir)
.stdout(Stdio::null())
.stderr(Stdio::null())
.arg("cpio")
.arg(cpio_path)
.arg("test")
.args(["cpio", "ramdisk.cpio", "test"])
.status()?;
// 0: stock, 1: magisk
Ok(status.code() == Some(1))
}
fn is_kernelsu_patched(magiskboot: &Path, workdir: &Path, cpio_path: &Path) -> Result<bool> {
fn is_kernelsu_patched(magiskboot: &Path, workdir: &Path) -> Result<bool> {
let status = Command::new(magiskboot)
.current_dir(workdir)
.stdout(Stdio::null())
.stderr(Stdio::null())
.arg("cpio")
.arg(cpio_path)
.arg("exists kernelsu.ko")
.args(["cpio", "ramdisk.cpio", "exists kernelsu.ko"])
.status()?;
Ok(status.success())
@@ -236,37 +234,18 @@ pub fn restore(
.status()?;
ensure!(status.success(), "magiskboot unpack failed");
let mut ramdisk = workdir.join("ramdisk.cpio");
if !ramdisk.exists() {
ramdisk = workdir.join("vendor_ramdisk").join("init_boot.cpio")
}
if !ramdisk.exists() {
ramdisk = workdir.join("vendor_ramdisk").join("ramdisk.cpio");
}
if !ramdisk.exists() {
bail!("No compatible ramdisk found.")
}
let ramdisk = ramdisk.as_path();
let is_kernelsu_patched = is_kernelsu_patched(&magiskboot, workdir, ramdisk)?;
let is_kernelsu_patched = is_kernelsu_patched(&magiskboot, workdir)?;
ensure!(is_kernelsu_patched, "boot image is not patched by KernelSU");
let mut new_boot = None;
let mut from_backup = false;
#[cfg(target_os = "android")]
if do_cpio_cmd(
&magiskboot,
workdir,
ramdisk,
&format!("exists {BACKUP_FILENAME}"),
)
.is_ok()
{
if do_cpio_cmd(&magiskboot, workdir, &format!("exists {BACKUP_FILENAME}")).is_ok() {
do_cpio_cmd(
&magiskboot,
workdir,
ramdisk,
&format!("extract {BACKUP_FILENAME} {BACKUP_FILENAME}"),
&format!("extract {0} {0}", BACKUP_FILENAME),
)?;
let sha = std::fs::read(workdir.join(BACKUP_FILENAME))?;
let sha = String::from_utf8(sha)?;
@@ -289,12 +268,15 @@ pub fn restore(
if new_boot.is_none() {
// remove kernelsu.ko
do_cpio_cmd(&magiskboot, workdir, ramdisk, "rm kernelsu.ko")?;
do_cpio_cmd(&magiskboot, workdir, "rm kernelsu.ko")?;
// if init.real exists, restore it
let status = do_cpio_cmd(&magiskboot, workdir, ramdisk, "exists init.real").is_ok();
let status = do_cpio_cmd(&magiskboot, workdir, "exists init.real").is_ok();
if status {
do_cpio_cmd(&magiskboot, workdir, ramdisk, "mv init.real init")?;
do_cpio_cmd(&magiskboot, workdir, "mv init.real init")?;
} else {
let ramdisk = workdir.join("ramdisk.cpio");
std::fs::remove_file(ramdisk)?;
}
println!("- Repacking boot image");
@@ -303,7 +285,7 @@ pub fn restore(
.stdout(Stdio::null())
.stderr(Stdio::null())
.arg("repack")
.arg(&bootimage)
.arg(bootimage.display().to_string())
.status()?;
ensure!(status.success(), "magiskboot repack failed");
new_boot = Some(workdir.join("new-boot.img"));
@@ -402,7 +384,7 @@ fn do_patch(
match get_current_kmi() {
Ok(value) => value,
Err(e) => {
println!("- {e}");
println!("- {}", e);
if let Some(image_path) = &image {
println!(
"- Trying to auto detect KMI version for {}",
@@ -427,7 +409,7 @@ fn do_patch(
let (bootimage, bootdevice) =
find_boot_image(&image, skip_init, ota, is_replace_kernel, workdir)?;
let bootimage = bootimage.as_path();
let bootimage = bootimage.display().to_string();
// try extract magiskboot/bootctl
let _ = assets::ensure_binaries(false);
@@ -456,54 +438,48 @@ fn do_patch(
assets::copy_assets_to_file("ksuinit", init_file).context("copy ksuinit failed")?;
}
// magiskboot unpack boot.img
// magiskboot cpio ramdisk.cpio 'cp init init.real'
// magiskboot cpio ramdisk.cpio 'add 0755 ksuinit init'
// magiskboot cpio ramdisk.cpio 'add 0755 <kmod> kernelsu.ko'
println!("- Unpacking boot image");
let status = Command::new(&magiskboot)
.current_dir(workdir)
.stdout(Stdio::null())
.stderr(Stdio::null())
.arg("unpack")
.arg(bootimage)
.arg(&bootimage)
.status()?;
ensure!(status.success(), "magiskboot unpack failed");
let mut ramdisk = workdir.join("ramdisk.cpio");
if !ramdisk.exists() {
ramdisk = workdir.join("vendor_ramdisk").join("init_boot.cpio")
}
if !ramdisk.exists() {
ramdisk = workdir.join("vendor_ramdisk").join("ramdisk.cpio");
}
if !ramdisk.exists() {
bail!("No compatible ramdisk found.");
}
let ramdisk = ramdisk.as_path();
let is_magisk_patched = is_magisk_patched(&magiskboot, workdir, ramdisk)?;
ensure!(!is_magisk_patched, "Cannot work with Magisk patched image");
let no_ramdisk = !workdir.join("ramdisk.cpio").exists();
let is_magisk_patched = is_magisk_patched(&magiskboot, workdir)?;
ensure!(
no_ramdisk || !is_magisk_patched,
"Cannot work with Magisk patched image"
);
println!("- Adding KernelSU LKM");
let is_kernelsu_patched = is_kernelsu_patched(&magiskboot, workdir, ramdisk)?;
let is_kernelsu_patched = is_kernelsu_patched(&magiskboot, workdir)?;
let mut need_backup = false;
if !is_kernelsu_patched {
// kernelsu.ko is not exist, backup init if necessary
let status = do_cpio_cmd(&magiskboot, workdir, ramdisk, "exists init");
let status = do_cpio_cmd(&magiskboot, workdir, "exists init");
if status.is_ok() {
do_cpio_cmd(&magiskboot, workdir, ramdisk, "mv init init.real")?;
do_cpio_cmd(&magiskboot, workdir, "mv init init.real")?;
}
need_backup = flash;
}
do_cpio_cmd(&magiskboot, workdir, ramdisk, "add 0755 init init")?;
do_cpio_cmd(
&magiskboot,
workdir,
ramdisk,
"add 0755 kernelsu.ko kernelsu.ko",
)?;
do_cpio_cmd(&magiskboot, workdir, "add 0755 init init")?;
do_cpio_cmd(&magiskboot, workdir, "add 0755 kernelsu.ko kernelsu.ko")?;
#[cfg(target_os = "android")]
if need_backup {
if let Err(e) = do_backup(&magiskboot, workdir, ramdisk, bootimage) {
if let Err(e) = do_backup(&magiskboot, workdir, &bootimage) {
println!("- Backup stock image failed: {e}");
}
}
@@ -515,7 +491,7 @@ fn do_patch(
.stdout(Stdio::null())
.stderr(Stdio::null())
.arg("repack")
.arg(bootimage)
.arg(&bootimage)
.status()?;
ensure!(status.success(), "magiskboot repack failed");
let new_boot = workdir.join("new-boot.img");
@@ -566,11 +542,11 @@ fn calculate_sha1(file_path: impl AsRef<Path>) -> Result<String> {
}
let result = hasher.finalize();
Ok(format!("{result:x}"))
Ok(format!("{:x}", result))
}
#[cfg(target_os = "android")]
fn do_backup(magiskboot: &Path, workdir: &Path, cpio_path: &Path, image: &Path) -> Result<()> {
fn do_backup(magiskboot: &Path, workdir: &Path, image: &str) -> Result<()> {
let sha1 = calculate_sha1(image)?;
let filename = format!("{KSU_BACKUP_FILE_PREFIX}{sha1}");
@@ -582,8 +558,7 @@ fn do_backup(magiskboot: &Path, workdir: &Path, cpio_path: &Path, image: &Path)
do_cpio_cmd(
magiskboot,
workdir,
cpio_path,
&format!("add 0755 {BACKUP_FILENAME} {BACKUP_FILENAME}"),
&format!("add 0755 {0} {0}", BACKUP_FILENAME),
)?;
println!("- Stock image has been backup to");
println!("- {target}");
@@ -593,7 +568,7 @@ fn do_backup(magiskboot: &Path, workdir: &Path, cpio_path: &Path, image: &Path)
#[cfg(target_os = "android")]
fn clean_backup(sha1: &str) -> Result<()> {
println!("- Clean up backup");
let backup_name = format!("{KSU_BACKUP_FILE_PREFIX}{sha1}");
let backup_name = format!("{}{}", KSU_BACKUP_FILE_PREFIX, sha1);
let dir = std::fs::read_dir(defs::KSU_BACKUP_DIR)?;
for entry in dir.flatten() {
let path = entry.path();
@@ -680,12 +655,8 @@ fn find_boot_image(
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}")
};

View File

@@ -374,13 +374,13 @@ pub fn run() -> Result<()> {
Commands::BootInfo { command } => match command {
BootInfo::CurrentKmi => {
let kmi = crate::boot_patch::get_current_kmi()?;
println!("{kmi}");
println!("{}", kmi);
// return here to avoid printing the error message
return Ok(());
}
BootInfo::SupportedKmi => {
let kmi = crate::assets::list_supported_kmi()?;
kmi.iter().for_each(|kmi| println!("{kmi}"));
kmi.iter().for_each(|kmi| println!("{}", kmi));
return Ok(());
}
},
@@ -392,7 +392,7 @@ pub fn run() -> Result<()> {
};
if let Err(e) = &result {
log::error!("Error: {e:?}");
log::error!("Error: {:?}", e);
}
result
}

View File

@@ -30,7 +30,7 @@ fn set_kernel_param(uid: u32) -> Result<()> {
fn get_pkg_uid(pkg: &str) -> Result<u32> {
// stat /data/data/<pkg>
let uid = rustix::fs::stat(format!("/data/data/{pkg}"))
.with_context(|| format!("stat /data/data/{pkg}"))?
.with_context(|| format!("stat /data/data/{}", pkg))?
.st_uid;
Ok(uid)
}

View File

@@ -83,13 +83,13 @@ pub fn mount_modules_systemlessly(module_dir: &str) -> Result<()> {
// mount /system first
if let Err(e) = mount_partition("system", &system_lowerdir) {
warn!("mount system failed: {e:#}");
warn!("mount system failed: {:#}", e);
}
// mount other partitions
for (k, v) in partition_lowerdir {
if let Err(e) = mount_partition(&k, &v) {
warn!("mount {k} failed: {e:#}");
warn!("mount {k} failed: {:#}", e);
}
}
@@ -120,7 +120,7 @@ pub fn on_post_data_fs() -> Result<()> {
} else {
// Then exec common post-fs-data scripts
if let Err(e) = crate::module::exec_common_scripts("post-fs-data.d", true) {
warn!("exec common post-fs-data scripts failed: {e}");
warn!("exec common post-fs-data scripts failed: {}", e);
}
}
@@ -168,17 +168,17 @@ pub fn on_post_data_fs() -> Result<()> {
if safe_mode {
warn!("safe mode, skip post-fs-data scripts and disable all modules!");
if let Err(e) = crate::module::disable_all_modules() {
warn!("disable all modules failed: {e}");
warn!("disable all modules failed: {}", e);
}
return Ok(());
}
if let Err(e) = prune_modules() {
warn!("prune modules failed: {e}");
warn!("prune modules failed: {}", e);
}
if let Err(e) = restorecon::restorecon() {
warn!("restorecon failed: {e}");
warn!("restorecon failed: {}", e);
}
// load sepolicy.rule
@@ -187,28 +187,28 @@ pub fn on_post_data_fs() -> Result<()> {
}
if let Err(e) = crate::profile::apply_sepolies() {
warn!("apply root profile sepolicy failed: {e}");
warn!("apply root profile sepolicy failed: {}", e);
}
// mount temp dir
if let Err(e) = mount::mount_tmpfs(defs::TEMP_DIR) {
warn!("do temp dir mount failed: {e}");
warn!("do temp dir mount failed: {}", e);
}
// exec modules post-fs-data scripts
// TODO: Add timeout
if let Err(e) = crate::module::exec_stage_script("post-fs-data", true) {
warn!("exec post-fs-data scripts failed: {e}");
warn!("exec post-fs-data scripts failed: {}", e);
}
// load system.prop
if let Err(e) = crate::module::load_system_prop() {
warn!("load system.prop failed: {e}");
warn!("load system.prop failed: {}", e);
}
// mount module systemlessly by overlay
if let Err(e) = mount_modules_systemlessly(module_dir) {
warn!("do systemless mount failed: {e}");
warn!("do systemless mount failed: {}", e);
}
run_stage("post-mount", true);
@@ -298,7 +298,7 @@ fn catch_bootlog(logname: &str, command: Vec<&str>) -> Result<()> {
};
if let Err(e) = result {
warn!("Failed to start logcat: {e:#}");
warn!("Failed to start logcat: {:#}", e);
}
Ok(())

View File

@@ -268,7 +268,7 @@ pub fn prune_modules() -> Result<()> {
let uninstaller = module.join("uninstall.sh");
if uninstaller.exists() {
if let Err(e) = exec_script(uninstaller, true) {
warn!("Failed to exec uninstaller: {e}");
warn!("Failed to exec uninstaller: {}", e);
}
}
@@ -341,7 +341,7 @@ fn _install_module(zip: &str) -> Result<()> {
module_prop.insert(k, v);
},
)?;
info!("module prop: {module_prop:?}");
info!("module prop: {:?}", module_prop);
let Some(module_id) = module_prop.get("id") else {
bail!("module id not found in module.prop!");
@@ -440,13 +440,13 @@ fn _install_module(zip: &str) -> Result<()> {
let _dontdrop = mount::AutoMountExt4::try_new(tmp_module_img, module_update_tmp_dir, true)?;
info!("mounted {tmp_module_img} to {module_update_tmp_dir}");
info!("mounted {} to {}", tmp_module_img, module_update_tmp_dir);
setsyscon(module_update_tmp_dir)?;
let module_dir = format!("{module_update_tmp_dir}/{module_id}");
ensure_clean_dir(&module_dir)?;
info!("module dir: {module_dir}");
info!("module dir: {}", module_dir);
// unzip the image and move it to modules_update/<id> dir
let file = File::open(zip)?;
@@ -584,7 +584,7 @@ pub fn uninstall_module(id: &str) -> Result<()> {
}
pub fn run_action(id: &str) -> Result<()> {
let action_script_path = format!("/data/adb/modules/{id}/action.sh");
let action_script_path = format!("/data/adb/modules/{}/action.sh", id);
exec_script(&action_script_path, true)
}
@@ -674,11 +674,11 @@ fn _list_modules(path: &str) -> Vec<HashMap<String, String>> {
if !module_prop_map.contains_key("id") || module_prop_map["id"].is_empty() {
match entry.file_name().to_str() {
Some(id) => {
info!("Use dir name as module id: {id}");
info!("Use dir name as module id: {}", id);
module_prop_map.insert("id".to_owned(), id.to_owned());
}
_ => {
info!("Failed to get module id: {module_prop:?}");
info!("Failed to get module id: {:?}", module_prop);
continue;
}
}

View File

@@ -135,7 +135,7 @@ pub fn mount_overlayfs(
})();
if let Err(e) = result {
warn!("fsopen mount failed: {e:#}, fallback to mount");
warn!("fsopen mount failed: {:#}, fallback to mount", e);
let mut data = format!("lowerdir={lowerdir_config}");
if let (Some(upperdir), Some(workdir)) = (upperdir, workdir) {
data = format!("{data},upperdir={upperdir},workdir={workdir}");
@@ -225,7 +225,7 @@ fn mount_overlay_child(
}
// merge modules and stock
if let Err(e) = mount_overlayfs(&lower_dirs, stock_root, None, None, mount_point) {
warn!("failed: {e:#}, fallback to bind mount");
warn!("failed: {:#}, fallback to bind mount", e);
bind_mount(stock_root, mount_point)?;
}
Ok(())
@@ -238,7 +238,7 @@ pub fn mount_overlay(
workdir: Option<PathBuf>,
upperdir: Option<PathBuf>,
) -> Result<()> {
info!("mount overlay for {root}");
info!("mount overlay for {}", root);
std::env::set_current_dir(root).with_context(|| format!("failed to chdir to {root}"))?;
let stock_root = ".";
@@ -269,7 +269,10 @@ pub fn mount_overlay(
continue;
}
if let Err(e) = mount_overlay_child(mount_point, &relative, module_roots, &stock_root) {
warn!("failed to mount overlay for child {mount_point}: {e:#}, revert");
warn!(
"failed to mount overlay for child {}: {:#}, revert",
mount_point, e
);
umount_dir(root).with_context(|| format!("failed to revert {root}"))?;
bail!(e);
}

View File

@@ -70,9 +70,9 @@ pub fn apply_sepolies() -> Result<()> {
};
let sepolicy = sepolicy.path();
if sepolicy::apply_file(&sepolicy).is_ok() {
log::info!("profile sepolicy applied: {sepolicy:?}");
log::info!("profile sepolicy applied: {:?}", sepolicy);
} else {
log::info!("profile sepolicy apply failed: {sepolicy:?}");
log::info!("profile sepolicy apply failed: {:?}", sepolicy);
}
}
Ok(())

View File

@@ -697,7 +697,7 @@ fn apply_one_rule<'a>(statement: &'a PolicyStatement<'a>, strict: bool) -> Resul
for policy in policies {
if !rustix::process::ksu_set_policy(&FfiPolicy::from(policy)) {
log::warn!("apply rule: {statement:?} failed.");
log::warn!("apply rule: {:?} failed.", statement);
if strict {
return Err(anyhow::anyhow!("apply rule {:?} failed.", statement));
}

View File

@@ -72,7 +72,6 @@ pub fn root_shell() -> Result<()> {
#[cfg(any(target_os = "linux", target_os = "android"))]
pub fn root_shell() -> Result<()> {
// we are root now, this was set in kernel!
use anyhow::anyhow;
let env_args: Vec<String> = env::args().collect();
let program = env_args[0].clone();

View File

@@ -108,12 +108,12 @@ pub fn is_safe_mode() -> bool {
|| getprop("ro.sys.safemode")
.filter(|prop| prop == "1")
.is_some();
log::info!("safemode: {safemode}");
log::info!("safemode: {}", safemode);
if safemode {
return true;
}
let safemode = ksucalls::check_kernel_safemode();
log::info!("kernel_safemode: {safemode}");
log::info!("kernel_safemode: {}", safemode);
safemode
}
@@ -303,7 +303,7 @@ fn copy_xattrs(src_path: impl AsRef<Path>, dest_path: impl AsRef<Path>) -> Resul
if let Err(e) =
extattr::lsetxattr(dest_path.as_ref(), &xattr, &value, extattr::Flags::empty())
{
log::warn!("Failed to set xattr: {e}");
log::warn!("Failed to set xattr: {}", e);
}
}
Ok(())
@@ -336,7 +336,7 @@ pub fn copy_module_files(source: impl AsRef<Path>, destination: impl AsRef<Path>
std::fs::remove_file(&dest_path).context("Failed to remove file")?;
}
let target = std::fs::read_link(entry.path()).context("Failed to read symlink")?;
log::info!("Symlink: {dest_path:?} -> {target:?}");
log::info!("Symlink: {:?} -> {:?}", dest_path, target);
std::os::unix::fs::symlink(target, &dest_path).context("Failed to create symlink")?;
copy_xattrs(&source_path, &dest_path)?;
} else if entry.file_type().is_dir() {

View File

@@ -9,7 +9,7 @@ export default defineConfig( {
head: [
['script', {
async: 'async',
src: 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-2610070972052494',
src: 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-4345548567024241',
crossorigin: 'anonymous',
}],
],

View File

@@ -1 +1 @@
google.com, pub-2610070972052494, DIRECT, f08c47fec0942fa0
google.com, pub-4345548567024241, DIRECT, f08c47fec0942fa0