添加 KPM 模块支持,包括 KPM 配置选项、核心功能实现及相关头文件
This commit is contained in:
@@ -16,6 +16,13 @@ config KSU_DEBUG
|
|||||||
help
|
help
|
||||||
Enable KernelSU debug mode.
|
Enable KernelSU debug mode.
|
||||||
|
|
||||||
|
config KPM
|
||||||
|
bool "Enable KernelSU KPM"
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
This option enables the KernelSU KPM feature. If enabled, it will
|
||||||
|
override the kernel version check and enable the hook functionality.
|
||||||
|
|
||||||
config KSU_ALLOWLIST_WORKAROUND
|
config KSU_ALLOWLIST_WORKAROUND
|
||||||
bool "KernelSU Session Keyring Init workaround"
|
bool "KernelSU Session Keyring Init workaround"
|
||||||
depends on KSU
|
depends on KSU
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ kernelsu-objs += selinux/rules.o
|
|||||||
ccflags-y += -I$(srctree)/security/selinux -I$(srctree)/security/selinux/include
|
ccflags-y += -I$(srctree)/security/selinux -I$(srctree)/security/selinux/include
|
||||||
ccflags-y += -I$(objtree)/security/selinux -include $(srctree)/include/uapi/asm-generic/errno.h
|
ccflags-y += -I$(objtree)/security/selinux -include $(srctree)/include/uapi/asm-generic/errno.h
|
||||||
|
|
||||||
|
obj-$(CONFIG_KPM) += kpm/
|
||||||
|
|
||||||
# Do checks before compile
|
# Do checks before compile
|
||||||
ifneq ($(shell grep -q "int path_umount" $(srctree)/fs/namespace.c; echo $$?),0)
|
ifneq ($(shell grep -q "int path_umount" $(srctree)/fs/namespace.c; echo $$?),0)
|
||||||
$(error -- Backporting path_umount is mandatory !! Read: https://kernelsu.org/guide/how-to-integrate-for-non-gki.html#how-to-backport-path-umount)
|
$(error -- Backporting path_umount is mandatory !! Read: https://kernelsu.org/guide/how-to-integrate-for-non-gki.html#how-to-backport-path-umount)
|
||||||
@@ -44,7 +46,7 @@ endif
|
|||||||
|
|
||||||
obj-$(CONFIG_KSU) += kernelsu.o
|
obj-$(CONFIG_KSU) += kernelsu.o
|
||||||
|
|
||||||
KSU_MANUAL_VERSION := 12553
|
KSU_MANUAL_VERSION := 12570
|
||||||
|
|
||||||
ifeq ($(strip $(KSU_MANUAL_VERSION)),)
|
ifeq ($(strip $(KSU_MANUAL_VERSION)),)
|
||||||
ifeq ($(shell test -e $(srctree)/$(src)/../.git; echo $$?),0)
|
ifeq ($(shell test -e $(srctree)/$(src)/../.git; echo $$?),0)
|
||||||
@@ -57,7 +59,7 @@ ifeq ($(strip $(KSU_MANUAL_VERSION)),)
|
|||||||
else
|
else
|
||||||
# .git is a text file while the module is imported by 'git submodule add'.
|
# .git is a text file while the module is imported by 'git submodule add'.
|
||||||
$(warning "KSU_GIT_VERSION not defined! Using default version.")
|
$(warning "KSU_GIT_VERSION not defined! Using default version.")
|
||||||
KSU_VERSION := 12553
|
KSU_VERSION := 12570
|
||||||
$(info -- KernelSU version (Default): $(KSU_VERSION))
|
$(info -- KernelSU version (Default): $(KSU_VERSION))
|
||||||
ccflags-y += -DKSU_VERSION=$(KSU_VERSION)
|
ccflags-y += -DKSU_VERSION=$(KSU_VERSION)
|
||||||
endif
|
endif
|
||||||
|
|||||||
@@ -506,6 +506,22 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_KPM
|
||||||
|
// ADD: 添加KPM模块控制
|
||||||
|
if(sukisu_is_kpm_control_code(arg2)) {
|
||||||
|
int res;
|
||||||
|
|
||||||
|
pr_info("KPM: calling before arg2=%d\n", (int) arg2);
|
||||||
|
|
||||||
|
res = sukisu_handle_kpm(arg2, arg3, arg4);
|
||||||
|
copy_to_user(result, &res, sizeof(res));
|
||||||
|
|
||||||
|
pr_info("KPM: calling before arg2=%d res=%d\n", (int) arg2, (int) res);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_KSU_SUSFS
|
#ifdef CONFIG_KSU_SUSFS
|
||||||
if (current_uid_val == 0) {
|
if (current_uid_val == 0) {
|
||||||
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
#ifdef CONFIG_KSU_SUSFS_SUS_PATH
|
||||||
|
|||||||
2
kernel/kpm/Makefile
Normal file
2
kernel/kpm/Makefile
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
obj-y += kpm.o
|
||||||
|
obj-y += compact.o
|
||||||
100
kernel/kpm/compact.c
Normal file
100
kernel/kpm/compact.c
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
#include <linux/export.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/fs.h>
|
||||||
|
#include <linux/kernfs.h>
|
||||||
|
#include <linux/file.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#include <linux/vmalloc.h>
|
||||||
|
#include <linux/uaccess.h>
|
||||||
|
#include <linux/elf.h>
|
||||||
|
#include <linux/kallsyms.h>
|
||||||
|
#include <linux/version.h>
|
||||||
|
#include <linux/list.h>
|
||||||
|
#include <linux/spinlock.h>
|
||||||
|
#include <linux/rcupdate.h>
|
||||||
|
#include <asm/elf.h> /* 包含 ARM64 重定位类型定义 */
|
||||||
|
#include <linux/vmalloc.h>
|
||||||
|
#include <linux/mm.h>
|
||||||
|
#include <linux/string.h>
|
||||||
|
#include <asm/cacheflush.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/vmalloc.h>
|
||||||
|
#include <linux/set_memory.h>
|
||||||
|
#include <linux/version.h>
|
||||||
|
#include <linux/export.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#include "kpm.h"
|
||||||
|
#include "compact.h"
|
||||||
|
|
||||||
|
unsigned long sukisu_compact_find_symbol(const char* name);
|
||||||
|
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
const char* kpver = "0.10";
|
||||||
|
|
||||||
|
struct CompactAddressSymbol {
|
||||||
|
const char* symbol_name;
|
||||||
|
void* addr;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CompactAliasSymbol {
|
||||||
|
const char* symbol_name;
|
||||||
|
const char* compact_symbol_name;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CompactAddressSymbol address_symbol [] = {
|
||||||
|
{ "kallsyms_lookup_name", &kallsyms_lookup_name },
|
||||||
|
{ "compact_find_symbol", &sukisu_compact_find_symbol },
|
||||||
|
{ "compat_copy_to_user", ©_to_user },
|
||||||
|
{ "compat_strncpy_from_user", &strncpy_from_user },
|
||||||
|
{ "kpver", &kpver },
|
||||||
|
{ "is_run_in_sukisu_ultra", (void*)1 }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CompactAliasSymbol alias_symbol[] = {
|
||||||
|
{"kf_strncat", "strncat"},
|
||||||
|
{"kf_strlen", "strlen" },
|
||||||
|
{"kf_strcpy", "strcpy"},
|
||||||
|
{"compat_copy_to_user", "__arch_copy_to_user"}
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned long sukisu_compact_find_symbol(const char* name) {
|
||||||
|
int i;
|
||||||
|
unsigned long addr;
|
||||||
|
|
||||||
|
// 先自己在地址表部分查出来
|
||||||
|
for(i = 0; i < (sizeof(address_symbol) / sizeof(struct CompactAddressSymbol)); i++) {
|
||||||
|
struct CompactAddressSymbol* symbol = &address_symbol[i];
|
||||||
|
if(strcmp(name, symbol->symbol_name) == 0) {
|
||||||
|
return (unsigned long) symbol->addr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 如果符号名以 "kf__" 开头,尝试解析去掉前缀的部分 */
|
||||||
|
if (strncmp(name, "kf__", 4) == 0) {
|
||||||
|
const char *real_name = name + 4; // 去掉 "kf__"
|
||||||
|
addr = (unsigned long)kallsyms_lookup_name(real_name);
|
||||||
|
if (addr) {
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 通过内核来查
|
||||||
|
addr = kallsyms_lookup_name(name);
|
||||||
|
if(addr) {
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查不到就查查兼容的符号
|
||||||
|
for(i = 0; i < (sizeof(alias_symbol) / sizeof(struct CompactAliasSymbol)); i++) {
|
||||||
|
struct CompactAliasSymbol* symbol = &alias_symbol[i];
|
||||||
|
if(strcmp(name, symbol->symbol_name) == 0) {
|
||||||
|
addr = kallsyms_lookup_name(symbol->compact_symbol_name);
|
||||||
|
if(addr)
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
6
kernel/kpm/compact.h
Normal file
6
kernel/kpm/compact.h
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef ___SUKISU_KPM_COMPACT_H
|
||||||
|
#define ___SUKISU_KPM_COMPACT_H
|
||||||
|
|
||||||
|
unsigned long sukisu_compact_find_symbol(const char* name);
|
||||||
|
|
||||||
|
#endif
|
||||||
1340
kernel/kpm/kpm.c
Normal file
1340
kernel/kpm/kpm.c
Normal file
File diff suppressed because it is too large
Load Diff
44
kernel/kpm/kpm.h
Normal file
44
kernel/kpm/kpm.h
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
#ifndef ___SUKISU_KPM_H
|
||||||
|
#define ___SUKISU_KPM_H
|
||||||
|
|
||||||
|
int sukisu_handle_kpm(unsigned long arg3, unsigned long arg4, unsigned long arg5);
|
||||||
|
int sukisu_is_kpm_control_code(unsigned long arg2);
|
||||||
|
|
||||||
|
// KPM控制代码
|
||||||
|
#define CMD_KPM_CONTROL 28
|
||||||
|
#define CMD_KPM_CONTROL_MAX 34
|
||||||
|
|
||||||
|
// 控制代码
|
||||||
|
|
||||||
|
// prctl(xxx, xxx, 1, "PATH", "ARGS")
|
||||||
|
// success return 0, error return -N
|
||||||
|
#define SUKISU_KPM_LOAD 28
|
||||||
|
|
||||||
|
// prctl(xxx, xxx, 2, "NAME")
|
||||||
|
// success return 0, error return -N
|
||||||
|
#define SUKISU_KPM_UNLOAD 29
|
||||||
|
|
||||||
|
// num = prctl(xxx, xxx, 3)
|
||||||
|
// error return -N
|
||||||
|
// success return +num or 0
|
||||||
|
#define SUKISU_KPM_NUM 30
|
||||||
|
|
||||||
|
// prctl(xxx, xxx, 4, Buffer, BufferSize)
|
||||||
|
// success return +out, error return -N
|
||||||
|
#define SUKISU_KPM_LIST 31
|
||||||
|
|
||||||
|
// prctl(xxx, xxx, 5, "NAME", Buffer[256])
|
||||||
|
// success return +out, error return -N
|
||||||
|
#define SUKISU_KPM_INFO 32
|
||||||
|
|
||||||
|
// prctl(xxx, xxx, 6, "NAME", "ARGS")
|
||||||
|
// success return KPM's result value
|
||||||
|
// error return -N
|
||||||
|
#define SUKISU_KPM_CONTROL 33
|
||||||
|
|
||||||
|
// prctl(xxx, xxx, 7)
|
||||||
|
// success will printf to stdout and return 0
|
||||||
|
// error will return -1
|
||||||
|
#define SUKISU_KPM_PRINT 34
|
||||||
|
|
||||||
|
#endif
|
||||||
0
kernel/kpm/super_access.c
Normal file
0
kernel/kpm/super_access.c
Normal file
0
kernel/kpm/super_access.h
Normal file
0
kernel/kpm/super_access.h
Normal file
Reference in New Issue
Block a user