Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
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
1 change: 1 addition & 0 deletions .github/workflows/build-lkm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ on:
jobs:
build-lkm:
strategy:
fail-fast: false
matrix:
kmi:
- android12-5.10
Expand Down
16 changes: 9 additions & 7 deletions .github/workflows/build-manager.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ on:
- 'manager/**'
- 'kernel/**'
- 'userspace/**'
- 'scripts/ksubot.py'
pull_request:
branches: [ "main", "dev" ]
paths:
Expand All @@ -19,7 +20,9 @@ on:
- 'manager/**'
- 'kernel/**'
- 'userspace/**'
- 'scripts/ksubot.py'
workflow_call:
workflow_dispatch:

jobs:
build-lkm:
Expand Down Expand Up @@ -79,14 +82,14 @@ jobs:
- name: Setup need_upload
id: need_upload
run: |
if [ ! -z "${{ secrets.BOT_TOKEN }}" ]; then
if [ ! -z "${{ secrets.BOT_TOKEN }}" ] && [ "${{ github.event_name }}" != "workflow_dispatch" ]; then
echo "UPLOAD=true" >> $GITHUB_OUTPUT
else
echo "UPLOAD=false" >> $GITHUB_OUTPUT
fi

- name: Write key
if: ${{ ( github.event_name != 'pull_request' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/dev' )) || github.ref_type == 'tag' }}
if: ${{ github.event_name != 'pull_request' || github.ref_type == 'tag' }}
run: |
if [ ! -z "${{ secrets.KEYSTORE }}" ]; then
{
Expand All @@ -95,7 +98,7 @@ jobs:
echo KEY_PASSWORD='${{ secrets.KEY_PASSWORD }}'
echo KEYSTORE_FILE='key.jks'
} >> gradle.properties
echo ${{ secrets.KEYSTORE }} | base64 -d > key.jks
echo "${{ secrets.KEYSTORE }}" | base64 -d > key.jks
fi

- name: Setup Java
Expand Down Expand Up @@ -157,11 +160,10 @@ jobs:
- name: Upload to telegram
if: github.event_name != 'pull_request' && steps.need_upload.outputs.UPLOAD == 'true'
env:
CHAT_ID: ${{ secrets.CHAT_ID }}
CHAT_ID: ${{ vars.CHAT_ID }}
BOT_TOKEN: ${{ secrets.BOT_TOKEN }}
MESSAGE_THREAD_ID: ${{ secrets.MESSAGE_THREAD_ID }}
COMMIT_MESSAGE: ${{ github.event.head_commit.message }}
COMMIT_URL: ${{ github.event.head_commit.url }}
MESSAGE_THREAD_ID: ${{ vars.MESSAGE_THREAD_ID }}
GITHUB_EVENT: ${{ toJson(github.event) }}
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
TITLE: Manager
BRANCH: ${{ github.ref_name }}
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.idea
.vscode
/.vscode
CLAUDE.md
AGENTS.md
4 changes: 2 additions & 2 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
**English** | [Español](README_ES.md) | [简体中文](README_CN.md) | [繁體中文](README_TW.md) | [日本語](README_JP.md) | [한국어](README_KR.md) | [Polski](README_PL.md) | [Português (Brasil)](README_PT-BR.md) | [Türkçe](README_TR.md) | [Русский](README_RU.md) | [Tiếng Việt](README_VI.md) | [Indonesia](README_ID.md) | [עברית](README_IW.md) | [हिंदी](README_IN.md) | [Italiano](README_IT.md)

# KernelSU
# My KernelSU

<img src="https://kernelsu.org/logo.png" style="width: 96px;" alt="logo">

A kernel-based root solution for Android devices.
A [KernelSU](https://github.com/tiann/KernelSU/commit/dc719b58f76d67806093e7ce8cd475362c6b7f73)-based root solution for Android devices.

[![Latest release](https://img.shields.io/github/v/release/tiann/KernelSU?label=Release&logo=github)](https://github.com/tiann/KernelSU/releases/latest)
[![Weblate](https://img.shields.io/badge/Localization-Weblate-teal?logo=weblate)](https://hosted.weblate.org/engage/kernelsu)
Expand Down
2 changes: 1 addition & 1 deletion kernel/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ compile_commands.json
*.mod.c
*.symvers*
*.order
.*.ko.cmd
.*.cmd
.tmp_versions/
libs/
obj/
Expand Down
2 changes: 2 additions & 0 deletions kernel/.vscode/generate_compdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ def gen_compile_commands(cmd_file_search_path, out_dir):

if not cmd_file_search_path:
cmd_file_search_path = [out_dir]
else:
cmd_file_search_path += [out_dir]

cmd_files = []
for search_path in cmd_file_search_path:
Expand Down
42 changes: 39 additions & 3 deletions kernel/Kbuild
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ kernelsu-objs += feature.o
kernelsu-objs += ksud.o
kernelsu-objs += seccomp_cache.o
kernelsu-objs += file_wrapper.o
kernelsu-objs += util.o
kernelsu-objs += pte.o
kernelsu-objs += patch.o
kernelsu-objs += inline_hook.o
kernelsu-objs += trampoline.o

kernelsu-objs += selinux/selinux.o
kernelsu-objs += selinux/sepolicy.o
Expand Down Expand Up @@ -60,12 +63,35 @@ $(warning "KSU_GIT_VERSION not defined! It is better to make KernelSU a git repo
ccflags-y += -DKSU_VERSION=16
endif

KSU_NEW_DCACHE_FLUSH := $(shell grep -q __flush_dcache_area $(srctree)/arch/arm64/include/asm/cacheflush.h ; echo $$?)
$(info -- KSU_NEW_DCACHE_FLUSH: $(KSU_NEW_DCACHE_FLUSH))

KSU_MTE_SYNC_TAGS_DEF := $(shell grep 'void mte_sync_tags' $(srctree)/arch/arm64/include/asm/mte.h | grep -v 'static inline')
# 6.6
KSU_MTE_SYNC_TAGS_NR_PAGES := $(shell echo '$(KSU_MTE_SYNC_TAGS_DEF)' | grep -q 'nr_pages' && echo 1 || echo 0)
# 6.1
KSU_MTE_SYNC_TAGS_NORMAL := $(shell echo '$(KSU_MTE_SYNC_TAGS_DEF)' | grep -q '(pte_t pte)' && echo 1 || echo 0)
# 13-5.10
KSU_MTE_SYNC_TAGS_OLD_PTE := $(shell echo '$(KSU_MTE_SYNC_TAGS_DEF)' | grep -q 'old_pte' && echo 1 || echo 0)
# 12-5.10
KSU_MTE_SYNC_TAGS_PTEP := $(shell echo '$(KSU_MTE_SYNC_TAGS_DEF)' | grep -q '*ptep' && echo 1 || echo 0)
KSU_DEF_MTE_SYNC_TAGS := 'extern $(KSU_MTE_SYNC_TAGS_DEF)'

$(info -- KSU_DEF_MTE_SYNC_TAGS: $(KSU_DEF_MTE_SYNC_TAGS))
$(info -- KSU_MTE_SYNC_TAGS_NR_PAGES: $(KSU_MTE_SYNC_TAGS_NR_PAGES))
$(info -- KSU_MTE_SYNC_TAGS_PTEP: $(KSU_MTE_SYNC_TAGS_PTEP))
$(info -- KSU_MTE_SYNC_TAGS_OLD_PTE: $(KSU_MTE_SYNC_TAGS_OLD_PTE))
$(info -- KSU_MTE_SYNC_TAGS_NORMAL: $(KSU_MTE_SYNC_TAGS_NORMAL))

OFFICIAL_EXPECTED_SIZE := 0x033b
OFFICIAL_EXPECTED_HASH := c371061b19d8c7d7d6133c6a9bafe198fa944e50c1b31c9d8daa8d7f1fc2d2d6

ifndef KSU_EXPECTED_SIZE
KSU_EXPECTED_SIZE := 0x033b
KSU_EXPECTED_SIZE := 384
endif

ifndef KSU_EXPECTED_HASH
KSU_EXPECTED_HASH := c371061b19d8c7d7d6133c6a9bafe198fa944e50c1b31c9d8daa8d7f1fc2d2d6
KSU_EXPECTED_HASH := 7e0c6d7278a3bb8e364e0fcba95afaf3666cf5ff3c245a3b63c8833bd0445cc4
endif

ifdef KSU_MANAGER_PACKAGE
Expand All @@ -78,6 +104,16 @@ $(info -- KernelSU Manager signature hash: $(KSU_EXPECTED_HASH))

ccflags-y += -DEXPECTED_SIZE=$(KSU_EXPECTED_SIZE)
ccflags-y += -DEXPECTED_HASH=\"$(KSU_EXPECTED_HASH)\"
ccflags-y += -DOFFICIAL_EXPECTED_SIZE=$(OFFICIAL_EXPECTED_SIZE)
ccflags-y += -DOFFICIAL_EXPECTED_HASH=\"$(OFFICIAL_EXPECTED_HASH)\"

ccflags-y += -DKSU_NEW_DCACHE_FLUSH=$(KSU_NEW_DCACHE_FLUSH)

ccflags-y += -DKSU_DEF_MTE_SYNC_TAGS=$(KSU_DEF_MTE_SYNC_TAGS)
ccflags-y += -DKSU_MTE_SYNC_TAGS_NR_PAGES=$(KSU_MTE_SYNC_TAGS_NR_PAGES)
ccflags-y += -DKSU_MTE_SYNC_TAGS_PTEP=$(KSU_MTE_SYNC_TAGS_PTEP)
ccflags-y += -DKSU_MTE_SYNC_TAGS_OLD_PTE=$(KSU_MTE_SYNC_TAGS_OLD_PTE)
ccflags-y += -DKSU_MTE_SYNC_TAGS_NORMAL=$(KSU_MTE_SYNC_TAGS_NORMAL)

ccflags-y += -Wno-strict-prototypes -Wno-int-conversion -Wno-gcc-compat -Wno-missing-prototypes
ccflags-y += -Wno-declaration-after-statement -Wno-unused-function
Expand Down
2 changes: 1 addition & 1 deletion kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ $(info -- MDIR: $(MDIR))
.PHONY: all compdb clean format check-format

all: check_symbol
make -C $(KDIR) M=$(MDIR) modules
CONFIG_KSU=m make -C $(KDIR) M=$(MDIR) modules
./check_symbol kernelsu.ko $(KDIR)/vmlinux
compdb:
python3 $(MDIR)/.vscode/generate_compdb.py -O $(KDIR) $(MDIR)
Expand Down
8 changes: 8 additions & 0 deletions kernel/allowlist.c
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,10 @@ bool __ksu_is_allow_uid(uid_t uid)
return true;
}

if (unlikely(allow_shell) && uid == 2000) {
return true;
}

if (likely(uid <= BITMAP_UID_MAX)) {
return !!(allow_list_bitmap[uid / BITS_PER_BYTE] &
(1 << (uid % BITS_PER_BYTE)));
Expand Down Expand Up @@ -339,6 +343,10 @@ void ksu_get_root_profile(uid_t uid, struct root_profile *profile)
goto use_default;
}

if (unlikely(allow_shell && uid == SHELL_UID)) {
goto use_default;
}

rcu_read_lock();
list_for_each_entry_rcu (p, &allow_list, list) {
if (uid == p->profile.current_uid && p->profile.allow_su) {
Expand Down
2 changes: 2 additions & 0 deletions kernel/allowlist.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,5 @@ static inline bool is_isolated_process(uid_t uid)
return appid >= FIRST_ISOLATED_UID && appid <= LAST_ISOLATED_UID;
}
#endif

extern bool allow_shell;
4 changes: 3 additions & 1 deletion kernel/apk_sign.c
Original file line number Diff line number Diff line change
Expand Up @@ -360,5 +360,7 @@ bool is_manager_apk(char *path)
return false;
}
#endif
return check_v2_signature(path, EXPECTED_SIZE, EXPECTED_HASH);
return check_v2_signature(path, EXPECTED_SIZE, EXPECTED_HASH) ||
check_v2_signature(path, OFFICIAL_EXPECTED_SIZE,
OFFICIAL_EXPECTED_HASH);
}
2 changes: 1 addition & 1 deletion kernel/app_profile.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ static void disable_seccomp(void)
{
struct task_struct *fake;

fake = kmalloc(sizeof(*fake), GFP_ATOMIC);
fake = kmalloc(sizeof(*fake), GFP_KERNEL);
if (!fake) {
pr_warn("failed to alloc fake task_struct\n");
return;
Expand Down
93 changes: 93 additions & 0 deletions kernel/hook.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (C) 2023 bmax121. All Rights Reserved.
*/

#ifndef __KSU_H_HOOK_
#define __KSU_H_HOOK_
#include "linux/types.h" // IWYU pragma: keep
#include "linux/version.h"

#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 14, 0)
#include "asm/patching.h" // IWYU pragma: keep
#else
#include "asm/insn.h" // IWYU pragma: keep
#endif

// https://github.com/bmax121/KernelPatch/blob/94e5be9cc3f8a6fbd9574155e3e9753200ab9bfb/kernel/include/hook.h#L54

#define HOOK_INTO_BRANCH_FUNC

typedef enum {
HOOK_NO_ERR = 0,
HOOK_BAD_ADDRESS = 4095,
HOOK_DUPLICATED = 4094,
HOOK_NO_MEM = 4093,
HOOK_BAD_RELO = 4092,
HOOK_TRANSIT_NO_MEM = 4091,
HOOK_CHAIN_FULL = 4090,
} hook_err_t;

#define HOOK_MEM_REGION_NUM 4
#define TRAMPOLINE_MAX_NUM 6
#define RELOCATE_INST_NUM (4 * 8 + 8 - 4)

#define HOOK_CHAIN_NUM 0x10

#define ARM64_NOP 0xd503201f
#define ARM64_BTI_C 0xd503245f
#define ARM64_BTI_J 0xd503249f
#define ARM64_BTI_JC 0xd50324df
#define ARM64_PACIASP 0xd503233f
#define ARM64_PACIBSP 0xd503237f

typedef struct {
// in
uint64_t func_addr;
uint64_t origin_addr;
uint64_t replace_addr;
uint64_t relo_addr;
// out
int32_t tramp_insts_num;
int32_t relo_insts_num;
uint32_t origin_insts[TRAMPOLINE_MAX_NUM] __attribute__((aligned(8)));
uint32_t tramp_insts[TRAMPOLINE_MAX_NUM] __attribute__((aligned(8)));
uint32_t relo_insts[RELOCATE_INST_NUM] __attribute__((aligned(8)));
} hook_t __attribute__((aligned(8)));

static inline int is_bad_address(void *addr)
{
return ((uint64_t)addr & 0x8000000000000000) != 0x8000000000000000;
}

int32_t branch_from_to(uint32_t *tramp_buf, uint64_t src_addr,
uint64_t dst_addr);
int32_t branch_relative(uint32_t *buf, uint64_t src_addr, uint64_t dst_addr);
int32_t branch_absolute(uint32_t *buf, uint64_t addr);
int32_t ret_absolute(uint32_t *buf, uint64_t addr);

hook_err_t hook_prepare(hook_t *hook);
int hook_install(hook_t *hook);

/**
* @brief Inline-hook function which address is @param func with function @param replace,
* after hook, original @param func is backuped in @param backup.
*
* @note If multiple modules hook this function simultaneously,
* it will cause abnormality when unload the modules. Please use hook_wrap instead
*
* @see hook_wrap
*
* @param func
* @param replace
* @param backup
* @return hook_err_t
*/
hook_err_t hook(void *func, void *replace, void **backup);

#define KSU_PATCH_TEXT_FLUSH_DCACHE 1
#define KSU_PATCH_TEXT_FLUSH_ICACHE 2

int ksu_patch_text(void *dst, void *src, size_t len, int flags);

#endif
Loading