diff --git a/.github/workflows/build-kasumi-lkm.yml b/.github/workflows/build-kasumi-lkm.yml index 870049b3..f004e14c 100644 --- a/.github/workflows/build-kasumi-lkm.yml +++ b/.github/workflows/build-kasumi-lkm.yml @@ -45,4 +45,4 @@ jobs: kmi: ${{ matrix.kmi }} arch: ${{ matrix.arch }} kasumi_ref: ${{ inputs.kasumi_ref || (startsWith(github.head_ref || github.ref_name, 'feat/hymofs') && 'dev' || 'main') }} - ddk_release: '20251104' + ddk_release: '20260313' diff --git a/.github/workflows/build-lkm.yml b/.github/workflows/build-lkm.yml index a2f9168b..5cc14e78 100644 --- a/.github/workflows/build-lkm.yml +++ b/.github/workflows/build-lkm.yml @@ -19,4 +19,4 @@ jobs: secrets: inherit with: kmi: ${{ matrix.kmi }} - ddk_release: '20251104' + ddk_release: '20260313' diff --git a/.github/workflows/ddk-lkm.yml b/.github/workflows/ddk-lkm.yml index 220d552e..c7228a75 100644 --- a/.github/workflows/ddk-lkm.yml +++ b/.github/workflows/ddk-lkm.yml @@ -10,7 +10,7 @@ on: ddk_release: description: 'DDK release version' required: false - default: '20251104' + default: '20260313' type: string jobs: @@ -18,7 +18,7 @@ jobs: name: Build kernelsu.ko for ${{ inputs.kmi }} runs-on: ubuntu-latest container: - image: ghcr.io/ylarod/ddk:${{ inputs.kmi }}-${{ inputs.ddk_release }} + image: ghcr.io/ylarod/ddk-min:${{ inputs.kmi }}-${{ inputs.ddk_release }} options: --privileged steps: diff --git a/.github/workflows/kasumi-lkm.yml b/.github/workflows/kasumi-lkm.yml index 8fc4c333..c963905a 100644 --- a/.github/workflows/kasumi-lkm.yml +++ b/.github/workflows/kasumi-lkm.yml @@ -19,7 +19,7 @@ on: ddk_release: description: "DDK release version" required: false - default: "20251104" + default: "20260313" type: string jobs: diff --git a/kernel/Kbuild b/kernel/Kbuild index c6422c06..efbe9396 100644 --- a/kernel/Kbuild +++ b/kernel/Kbuild @@ -68,7 +68,7 @@ endif endif endif -ccflags-y += -Wno-implicit-function-declaration -Wno-strict-prototypes +ccflags-y += -Wno-strict-prototypes ccflags-y += -Wno-declaration-after-statement -Wno-unused-function -Wno-unused-variable -Wno-missing-braces ccflags-y += -Wno-int-to-pointer-cast -Wno-declaration-after-statement diff --git a/kernel/Makefile b/kernel/Makefile index f90d305f..21f0b1d3 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -8,8 +8,9 @@ endif .PHONY: all compdb clean format check-format -all: +all: check_symbol make -C $(KDIR) M=$(MDIR) modules + ./check_symbol kernelsu.ko $(KDIR)/vmlinux compdb: python3 $(MDIR)/.vscode/generate_compdb.py -O $(KDIR) $(MDIR) clean: @@ -17,7 +18,6 @@ clean: rm check_symbol check_symbol: tools/check_symbol.c $(CC) tools/check_symbol.c -o check_symbol - ./check_symbol kernelsu.ko $(KDIR)/vmlinux format: git -C $(MDIR) ls-files -z -- "*.c" "*.h" | xargs -0 clang-format -i check-format: diff --git a/kernel/hook/syscall_event_bridge.c b/kernel/hook/syscall_event_bridge.c index f2507530..a75925b0 100644 --- a/kernel/hook/syscall_event_bridge.c +++ b/kernel/hook/syscall_event_bridge.c @@ -17,6 +17,7 @@ #include "klog.h" // IWYU pragma: keep #include "policy/app_profile.h" #include "runtime/ksud.h" +#include "selinux/selinux.h" #include "sulog/event.h" /* diff --git a/kernel/manager/superkey.c b/kernel/manager/superkey.c index 9741cf22..e7d1511f 100644 --- a/kernel/manager/superkey.c +++ b/kernel/manager/superkey.c @@ -3,6 +3,7 @@ #include "klog.h" #include "manager/manager_identity.h" #include +#include #include #include #include diff --git a/kernel/manager/throne_tracker.c b/kernel/manager/throne_tracker.c index ea37b74f..bafd708f 100644 --- a/kernel/manager/throne_tracker.c +++ b/kernel/manager/throne_tracker.c @@ -650,8 +650,8 @@ void track_throne(bool prune_only) manager_exist = (ksu_manager_appid != KSU_INVALID_UID); if (!manager_exist) { #ifdef CONFIG_KSU_SUPERKEY - extern void ksu_superkey_register_prctl_kprobe(void); - ksu_superkey_register_prctl_kprobe(); + extern void ksu_superkey_register_prctl_hook(void); + ksu_superkey_register_prctl_hook(); #endif // #ifdef CONFIG_KSU_SUPERKEY } } diff --git a/kernel/supercall/dispatch.c b/kernel/supercall/dispatch.c index 5290a4ba..3b00e814 100644 --- a/kernel/supercall/dispatch.c +++ b/kernel/supercall/dispatch.c @@ -25,6 +25,7 @@ #include "feature/kernel_umount.h" #include "klog.h" // IWYU pragma: keep #include "ksu.h" +#include "manager/apk_sign.h" #include "runtime/ksud_boot.h" #include "runtime/ksud.h" #include "manager/manager_identity.h" diff --git a/kernel/supercall/supercall.c b/kernel/supercall/supercall.c index babe19e6..8e9bf710 100644 --- a/kernel/supercall/supercall.c +++ b/kernel/supercall/supercall.c @@ -17,6 +17,7 @@ #include "policy/allowlist.h" #include "arch.h" +#include "hook/syscall_hook.h" #include "policy/feature.h" #include "feature/selinux_hide.h" #include "infra/file_wrapper.h" @@ -249,8 +250,8 @@ static void ksu_superkey_prctl_tw_func(struct callback_head *cb) superkey_on_auth_success(uid); ksu_set_manager_uid(uid); - // Unregister prctl kprobe after successful authentication - ksu_superkey_unregister_prctl_kprobe(); + // Unregister the prctl TSR hook after successful authentication + ksu_superkey_unregister_prctl_hook(); // Allow reboot syscall for this process if (current->seccomp.mode == SECCOMP_MODE_FILTER && @@ -371,43 +372,47 @@ static int ksu_handle_prctl_superkey(int option, unsigned long arg2) return 0; } -static int prctl_handler_pre(struct kprobe *p, struct pt_regs *regs) +/* + * SuperKey prctl interception via TSR (Tracepoint Syscall Redirect) instead of + * a kprobe. It runs in the sleepable dispatcher context (not the atomic kprobe + * breakpoint handler) and avoids planting a breakpoint on the hot __NR_prctl + * path. Must be __nocfi: it tail-calls the original syscall through + * ksu_syscall_table[orig_nr], a kallsyms-resolved pointer with no .cfi_jt on + * some kernels. + */ +static long __nocfi ksu_hook_prctl(int orig_nr, const struct pt_regs *regs) { - struct pt_regs *real_regs = PT_REAL_REGS(regs); - int option = (int)PT_REGS_PARM1(real_regs); - unsigned long arg2 = PT_REGS_PARM2(real_regs); - return ksu_handle_prctl_superkey(option, arg2); -} + int option = (int)PT_REGS_PARM1(regs); + unsigned long arg2 = PT_REGS_PARM2(regs); -static struct kprobe prctl_kp = { - .symbol_name = SYS_PRCTL_SYMBOL, - .pre_handler = prctl_handler_pre, -}; + ksu_handle_prctl_superkey(option, arg2); + return ksu_syscall_table[orig_nr](regs); +} -static bool prctl_kprobe_registered = false; +static bool prctl_hook_registered = false; -void ksu_superkey_unregister_prctl_kprobe(void) +void ksu_superkey_unregister_prctl_hook(void) { - if (prctl_kprobe_registered) { - unregister_kprobe(&prctl_kp); - prctl_kprobe_registered = false; - pr_info("SuperKey: prctl kprobe unregistered after " + if (prctl_hook_registered) { + ksu_unregister_syscall_hook(__NR_prctl); + prctl_hook_registered = false; + pr_info("SuperKey: prctl TSR hook unregistered after " "authentication\n"); } } -void ksu_superkey_register_prctl_kprobe(void) +void ksu_superkey_register_prctl_hook(void) { int rc; - if (!prctl_kprobe_registered) { - rc = register_kprobe(&prctl_kp); + if (!prctl_hook_registered) { + rc = ksu_register_syscall_hook(__NR_prctl, ksu_hook_prctl); if (rc) { pr_err( - "SuperKey: prctl kprobe re-register failed: %d\n", + "SuperKey: prctl TSR hook re-register failed: %d\n", rc); } else { - prctl_kprobe_registered = true; - pr_info("SuperKey: prctl kprobe re-registered\n"); + prctl_hook_registered = true; + pr_info("SuperKey: prctl TSR hook re-registered\n"); } } } @@ -425,19 +430,20 @@ void ksu_supercalls_init(void) pr_info("reboot kprobe registered successfully\n"); } - // SuperKey prctl kprobe - only register when SuperKey is configured. + // SuperKey prctl TSR hook - only register when SuperKey is configured. #ifdef CONFIG_KSU_SUPERKEY if (superkey_is_set()) { - rc = register_kprobe(&prctl_kp); + rc = ksu_register_syscall_hook(__NR_prctl, ksu_hook_prctl); if (rc) { - pr_err("prctl kprobe failed: %d\n", rc); - prctl_kprobe_registered = false; + pr_err("prctl TSR hook failed: %d\n", rc); + prctl_hook_registered = false; } else { - pr_info("prctl kprobe registered for SuperKey auth\n"); - prctl_kprobe_registered = true; + pr_info( + "prctl TSR hook registered for SuperKey auth\n"); + prctl_hook_registered = true; } } else { - pr_info("SuperKey: no SuperKey configured, prctl kprobe not " + pr_info("SuperKey: no SuperKey configured, prctl TSR hook not " "registered (signature-only mode)\n"); } #endif // #ifdef CONFIG_KSU_SUPERKEY @@ -447,9 +453,9 @@ void ksu_supercalls_exit(void) { unregister_kprobe(&reboot_kp); #ifdef CONFIG_KSU_SUPERKEY - if (prctl_kprobe_registered) { - unregister_kprobe(&prctl_kp); - prctl_kprobe_registered = false; + if (prctl_hook_registered) { + ksu_unregister_syscall_hook(__NR_prctl); + prctl_hook_registered = false; } #endif // #ifdef CONFIG_KSU_SUPERKEY } diff --git a/kernel/supercall/supercall.h b/kernel/supercall/supercall.h index d3b731c9..75404295 100644 --- a/kernel/supercall/supercall.h +++ b/kernel/supercall/supercall.h @@ -8,8 +8,8 @@ void ksu_supercalls_init(void); void ksu_supercalls_exit(void); #ifdef CONFIG_KSU_SUPERKEY -void ksu_superkey_unregister_prctl_kprobe(void); -void ksu_superkey_register_prctl_kprobe(void); +void ksu_superkey_unregister_prctl_hook(void); +void ksu_superkey_register_prctl_hook(void); #endif // #ifdef CONFIG_KSU_SUPERKEY #endif // #ifndef __KSU_H_SUPERCALL diff --git a/scripts/build.sh b/scripts/build.sh index 88ce0e45..0c739cc7 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -12,7 +12,7 @@ KMI="android16-6.12" ABI="arm64-v8a" SKIP_LKM=false SKIP_KASUMI=false -DDK_RELEASE="20251104" +DDK_RELEASE="20260313" DO_INSTALL=false # 默认从当前 Kasumi 主仓库编译 ko;可用 --kasumi-dir 覆盖 KASUMI_DIR="${KASUMI_DIR:-/Volumes/Workspace/Kasumi}" @@ -119,7 +119,7 @@ if [[ "$SKIP_LKM" != "true" ]]; then echo ">>> [1/5] 构建 KernelSU LKM (DDK) ..." mkdir -p "$OUT_DIR" docker run --rm -v "$REPO_ROOT:/src" -w /src \ - "ghcr.io/ylarod/ddk:${KMI}-${DDK_RELEASE}" \ + "ghcr.io/ylarod/ddk-min:${KMI}-${DDK_RELEASE}" \ bash -c "cd kernel && test -f include/uapi/supercall.h && \ CONFIG_KSU=m CONFIG_KSU_SUPERKEY=y CC=clang make -j${MAKE_JOBS} && \ mkdir -p /src/out && cp kernelsu.ko /src/out/${KMI}_kernelsu.ko && \