Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build-kasumi-lkm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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'
2 changes: 1 addition & 1 deletion .github/workflows/build-lkm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ jobs:
secrets: inherit
with:
kmi: ${{ matrix.kmi }}
ddk_release: '20251104'
ddk_release: '20260313'
4 changes: 2 additions & 2 deletions .github/workflows/ddk-lkm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ on:
ddk_release:
description: 'DDK release version'
required: false
default: '20251104'
default: '20260313'
type: string

jobs:
build-kernelsu-ko:
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:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/kasumi-lkm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ on:
ddk_release:
description: "DDK release version"
required: false
default: "20251104"
default: "20260313"
type: string

jobs:
Expand Down
2 changes: 1 addition & 1 deletion kernel/Kbuild
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
4 changes: 2 additions & 2 deletions kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@ 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:
make -C $(KDIR) M=$(MDIR) 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:
Expand Down
1 change: 1 addition & 0 deletions kernel/hook/syscall_event_bridge.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"

/*
Expand Down
1 change: 1 addition & 0 deletions kernel/manager/superkey.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "klog.h"
#include "manager/manager_identity.h"
#include <crypto/hash.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/module.h>
#include <linux/sched/signal.h>
Expand Down
4 changes: 2 additions & 2 deletions kernel/manager/throne_tracker.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
Expand Down
1 change: 1 addition & 0 deletions kernel/supercall/dispatch.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
74 changes: 40 additions & 34 deletions kernel/supercall/supercall.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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 &&
Expand Down Expand Up @@ -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");
}
Comment on lines +394 to 401
}

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");
}
}
}
Expand All @@ -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
Expand All @@ -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
}
Expand Down
4 changes: 2 additions & 2 deletions kernel/supercall/supercall.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
4 changes: 2 additions & 2 deletions scripts/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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}"
Expand Down Expand Up @@ -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 && \
Expand Down
Loading