From 92e9f4068a634c599e875fd608584327db527c5f Mon Sep 17 00:00:00 2001 From: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com> Date: Sun, 9 Nov 2025 17:00:43 +0800 Subject: [PATCH] kernel: Rollback disable_seccomp Co-authored-by: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com> Co-authored-by: Faris --- kernel/app_profile.c | 30 +++++++++++++++++++++--------- kernel/app_profile.h | 2 +- kernel/setuid_hook.c | 34 +++++++++++++++++++--------------- 3 files changed, 41 insertions(+), 25 deletions(-) diff --git a/kernel/app_profile.c b/kernel/app_profile.c index 7dab0182..3a70f61d 100644 --- a/kernel/app_profile.c +++ b/kernel/app_profile.c @@ -66,21 +66,33 @@ static void setup_groups(struct root_profile *profile, struct cred *cred) put_group_info(group_info); } -void disable_seccomp(void) +void disable_seccomp(struct task_struct *tsk) { - assert_spin_locked(¤t->sighand->siglock); - // disable seccomp + assert_spin_locked(&tsk->sighand->siglock); + + // disable seccomp #if defined(CONFIG_GENERIC_ENTRY) && \ - LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0) - clear_syscall_work(SECCOMP); + LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0) + clear_syscall_work(SECCOMP); #else - clear_thread_flag(TIF_SECCOMP); + clear_thread_flag(TIF_SECCOMP); #endif #ifdef CONFIG_SECCOMP - current->seccomp.mode = 0; - current->seccomp.filter = NULL; + tsk->seccomp.mode = 0; + if (tsk->seccomp.filter) { + // 5.9+ have filter_count and use seccomp_filter_release +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0) + seccomp_filter_release(tsk); + atomic_set(&tsk->seccomp.filter_count, 0); #else + // for 6.11+ kernel support? +#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 9, 0) + put_seccomp_filter(tsk); +#endif + tsk->seccomp.filter = NULL; +#endif + } #endif } @@ -140,7 +152,7 @@ void escape_with_root_profile(void) // Refer to kernel/seccomp.c: seccomp_set_mode_strict // When disabling Seccomp, ensure that current->sighand->siglock is held during the operation. spin_lock_irq(¤t->sighand->siglock); - disable_seccomp(); + disable_seccomp(current); spin_unlock_irq(¤t->sighand->siglock); setup_selinux(profile->selinux_domain); diff --git a/kernel/app_profile.h b/kernel/app_profile.h index 871abb6f..80b2f916 100644 --- a/kernel/app_profile.h +++ b/kernel/app_profile.h @@ -65,6 +65,6 @@ void escape_with_root_profile(void); void escape_to_root_for_cmd_su(uid_t target_uid, pid_t target_pid); -void disable_seccomp(void); +void disable_seccomp(struct task_struct *tsk); #endif diff --git a/kernel/setuid_hook.c b/kernel/setuid_hook.c index f9ed0e57..131aac95 100644 --- a/kernel/setuid_hook.c +++ b/kernel/setuid_hook.c @@ -149,43 +149,47 @@ int ksu_handle_setresuid(uid_t ruid, uid_t euid, uid_t suid) } // if on private space, see if its possibly the manager - if (unlikely(new_uid > 100000 && new_uid % 100000 == ksu_get_manager_uid())) { + if (new_uid > 100000 && new_uid % 100000 == ksu_get_manager_uid()) { ksu_set_manager_uid(new_uid); } - if (unlikely(ksu_get_manager_uid() == new_uid)) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0) + if (ksu_get_manager_uid() == new_uid) { pr_info("install fd for manager: %d\n", new_uid); ksu_install_fd(); spin_lock_irq(¤t->sighand->siglock); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 2) // Android backport this feature in 5.10.2 ksu_seccomp_allow_cache(current->seccomp.filter, __NR_reboot); -#else - // we dont have those new fancy things upstream has - // lets just do original thing where we disable seccomp - disable_seccomp(); -#endif ksu_set_task_tracepoint_flag(current); spin_unlock_irq(¤t->sighand->siglock); return 0; } - if (unlikely(ksu_is_allow_uid_for_current(new_uid))) { + if (ksu_is_allow_uid_for_current(new_uid)) { if (current->seccomp.mode == SECCOMP_MODE_FILTER && current->seccomp.filter) { spin_lock_irq(¤t->sighand->siglock); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 2) // Android backport this feature in 5.10.2 ksu_seccomp_allow_cache(current->seccomp.filter, __NR_reboot); -#else - // we don't have those new fancy things upstream has - // lets just do original thing where we disable seccomp - disable_seccomp(); -#endif spin_unlock_irq(¤t->sighand->siglock); } ksu_set_task_tracepoint_flag(current); } else { ksu_clear_task_tracepoint_flag(current); } +#else + if (ksu_is_allow_uid_for_current(new_uid)) { + spin_lock_irq(¤t->sighand->siglock); + disable_seccomp(current); + spin_unlock_irq(¤t->sighand->siglock); + + if (ksu_get_manager_uid() == new_uid) { + pr_info("install fd for ksu manager(uid=%d)\n", + new_uid); + ksu_install_fd(); + } + + return 0; + } +#endif // Handle kernel umount ksu_handle_umount(old_uid, new_uid);