Skip to content

Commit 1ef829a

Browse files
committed
kernel: drop LKM and kprobes support
Since upstream has kprobes default, and now a requirement, cleaning up support for LKM and kprobes is kind of a must. This simplifies porting small changes, debloat, and makes it easier to maintain downstream, e.g. avoiding excessive use of conditionals (ifdef hell). what breaks: current_user_stack_pointer, sucompat.c - mitigate this by including linux/ptrace.h fatal_signal_pending, ksud.c - mitigate this by including linux/sched/signal.h other changes: Kconfig, CONFIG_KSU, tristate to bool ksud.c, stop_input_hook(), short-circuit redundant logic left by this change. Signed-off-by: backslashxx <[email protected]>
1 parent 808e008 commit 1ef829a

File tree

9 files changed

+11
-621
lines changed

9 files changed

+11
-621
lines changed

kernel/Kconfig

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
menu "KernelSU"
22

33
config KSU
4-
tristate "KernelSU function support"
4+
bool "KernelSU function support"
55
depends on OVERLAY_FS
66
default y
77
help
88
Enable kernel-level root privileges on Android System.
9-
To compile as a module, choose M here: the
10-
module will be called kernelsu.
119

1210
config KSU_DEBUG
1311
bool "KernelSU debug mode"

kernel/arch.h

Lines changed: 0 additions & 72 deletions
This file was deleted.

kernel/core_hook.c

Lines changed: 1 addition & 261 deletions
Original file line numberDiff line numberDiff line change
@@ -4,37 +4,21 @@
44
#include <linux/err.h>
55
#include <linux/init.h>
66
#include <linux/init_task.h>
7-
#include <linux/kallsyms.h>
87
#include <linux/kernel.h>
9-
#include <linux/kprobes.h>
108
#include <linux/lsm_hooks.h>
11-
#include <linux/mm.h>
129
#include <linux/nsproxy.h>
1310
#include <linux/path.h>
1411
#include <linux/printk.h>
15-
#include <linux/sched.h>
16-
#include <linux/security.h>
17-
#include <linux/stddef.h>
1812
#include <linux/string.h>
19-
#include <linux/types.h>
2013
#include <linux/uaccess.h>
2114
#include <linux/uidgid.h>
2215
#include <linux/version.h>
2316
#include <linux/mount.h>
24-
2517
#include <linux/fs.h>
2618
#include <linux/namei.h>
2719

28-
#ifdef MODULE
29-
#include <linux/list.h>
30-
#include <linux/irqflags.h>
31-
#include <linux/mm_types.h>
32-
#include <linux/rcupdate.h>
33-
#include <linux/vmalloc.h>
34-
#endif
35-
3620
#include "allowlist.h"
37-
#include "arch.h"
21+
3822
#include "core_hook.h"
3923
#include "klog.h" // IWYU pragma: keep
4024
#include "ksu.h"
@@ -305,9 +289,6 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
305289
pr_err("prctl reply error, cmd: %lu\n", arg2);
306290
}
307291
u32 version_flags = 0;
308-
#ifdef MODULE
309-
version_flags |= 0x1;
310-
#endif
311292
if (arg4 &&
312293
copy_to_user(arg4, &version_flags, sizeof(version_flags))) {
313294
pr_err("prctl reply error, cmd: %lu\n", arg2);
@@ -644,69 +625,6 @@ int ksu_handle_setuid(struct cred *new, const struct cred *old)
644625
return 0;
645626
}
646627

647-
// Init functons
648-
649-
static int handler_pre(struct kprobe *p, struct pt_regs *regs)
650-
{
651-
struct pt_regs *real_regs = PT_REAL_REGS(regs);
652-
int option = (int)PT_REGS_PARM1(real_regs);
653-
unsigned long arg2 = (unsigned long)PT_REGS_PARM2(real_regs);
654-
unsigned long arg3 = (unsigned long)PT_REGS_PARM3(real_regs);
655-
// PRCTL_SYMBOL is the arch-specificed one, which receive raw pt_regs from syscall
656-
unsigned long arg4 = (unsigned long)PT_REGS_SYSCALL_PARM4(real_regs);
657-
unsigned long arg5 = (unsigned long)PT_REGS_PARM5(real_regs);
658-
659-
return ksu_handle_prctl(option, arg2, arg3, arg4, arg5);
660-
}
661-
662-
static struct kprobe prctl_kp = {
663-
.symbol_name = PRCTL_SYMBOL,
664-
.pre_handler = handler_pre,
665-
};
666-
667-
static int renameat_handler_pre(struct kprobe *p, struct pt_regs *regs)
668-
{
669-
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0)
670-
// https://elixir.bootlin.com/linux/v5.12-rc1/source/include/linux/fs.h
671-
struct renamedata *rd = PT_REGS_PARM1(regs);
672-
struct dentry *old_entry = rd->old_dentry;
673-
struct dentry *new_entry = rd->new_dentry;
674-
#else
675-
struct dentry *old_entry = (struct dentry *)PT_REGS_PARM2(regs);
676-
struct dentry *new_entry = (struct dentry *)PT_REGS_CCALL_PARM4(regs);
677-
#endif
678-
679-
return ksu_handle_rename(old_entry, new_entry);
680-
}
681-
682-
static struct kprobe renameat_kp = {
683-
.symbol_name = "vfs_rename",
684-
.pre_handler = renameat_handler_pre,
685-
};
686-
687-
__maybe_unused int ksu_kprobe_init(void)
688-
{
689-
int rc = 0;
690-
rc = register_kprobe(&prctl_kp);
691-
692-
if (rc) {
693-
pr_info("prctl kprobe failed: %d.\n", rc);
694-
return rc;
695-
}
696-
697-
rc = register_kprobe(&renameat_kp);
698-
pr_info("renameat kp: %d\n", rc);
699-
700-
return rc;
701-
}
702-
703-
__maybe_unused int ksu_kprobe_exit(void)
704-
{
705-
unregister_kprobe(&prctl_kp);
706-
unregister_kprobe(&renameat_kp);
707-
return 0;
708-
}
709-
710628
static int ksu_task_prctl(int option, unsigned long arg2, unsigned long arg3,
711629
unsigned long arg4, unsigned long arg5)
712630
{
@@ -726,7 +644,6 @@ static int ksu_task_fix_setuid(struct cred *new, const struct cred *old,
726644
return ksu_handle_setuid(new, old);
727645
}
728646

729-
#ifndef MODULE
730647
static struct security_hook_list ksu_hooks[] = {
731648
LSM_HOOK_INIT(task_prctl, ksu_task_prctl),
732649
LSM_HOOK_INIT(inode_rename, ksu_inode_rename),
@@ -738,184 +655,7 @@ void __init ksu_lsm_hook_init(void)
738655
security_add_hooks(ksu_hooks, ARRAY_SIZE(ksu_hooks), "ksu");
739656
}
740657

741-
#else
742-
static int override_security_head(void *head, const void *new_head, size_t len)
743-
{
744-
unsigned long base = (unsigned long)head & PAGE_MASK;
745-
unsigned long offset = offset_in_page(head);
746-
747-
// this is impossible for our case because the page alignment
748-
// but be careful for other cases!
749-
BUG_ON(offset + len > PAGE_SIZE);
750-
struct page *page = phys_to_page(__pa(base));
751-
if (!page) {
752-
return -EFAULT;
753-
}
754-
755-
void *addr = vmap(&page, 1, VM_MAP, PAGE_KERNEL);
756-
if (!addr) {
757-
return -ENOMEM;
758-
}
759-
local_irq_disable();
760-
memcpy(addr + offset, new_head, len);
761-
local_irq_enable();
762-
vunmap(addr);
763-
return 0;
764-
}
765-
766-
static void free_security_hook_list(struct hlist_head *head)
767-
{
768-
struct hlist_node *temp;
769-
struct security_hook_list *entry;
770-
771-
if (!head)
772-
return;
773-
774-
hlist_for_each_entry_safe (entry, temp, head, list) {
775-
hlist_del(&entry->list);
776-
kfree(entry);
777-
}
778-
779-
kfree(head);
780-
}
781-
782-
struct hlist_head *copy_security_hlist(struct hlist_head *orig)
783-
{
784-
struct hlist_head *new_head = kmalloc(sizeof(*new_head), GFP_KERNEL);
785-
if (!new_head)
786-
return NULL;
787-
788-
INIT_HLIST_HEAD(new_head);
789-
790-
struct security_hook_list *entry;
791-
struct security_hook_list *new_entry;
792-
793-
hlist_for_each_entry (entry, orig, list) {
794-
new_entry = kmalloc(sizeof(*new_entry), GFP_KERNEL);
795-
if (!new_entry) {
796-
free_security_hook_list(new_head);
797-
return NULL;
798-
}
799-
800-
*new_entry = *entry;
801-
802-
hlist_add_tail_rcu(&new_entry->list, new_head);
803-
}
804-
805-
return new_head;
806-
}
807-
808-
#define LSM_SEARCH_MAX 180 // This should be enough to iterate
809-
static void *find_head_addr(void *security_ptr, int *index)
810-
{
811-
if (!security_ptr) {
812-
return NULL;
813-
}
814-
struct hlist_head *head_start =
815-
(struct hlist_head *)&security_hook_heads;
816-
817-
for (int i = 0; i < LSM_SEARCH_MAX; i++) {
818-
struct hlist_head *head = head_start + i;
819-
struct security_hook_list *pos;
820-
hlist_for_each_entry (pos, head, list) {
821-
if (pos->hook.capget == security_ptr) {
822-
if (index) {
823-
*index = i;
824-
}
825-
return head;
826-
}
827-
}
828-
}
829-
830-
return NULL;
831-
}
832-
833-
#define GET_SYMBOL_ADDR(sym) \
834-
({ \
835-
void *addr = kallsyms_lookup_name(#sym ".cfi_jt"); \
836-
if (!addr) { \
837-
addr = kallsyms_lookup_name(#sym); \
838-
} \
839-
addr; \
840-
})
841-
842-
#define KSU_LSM_HOOK_HACK_INIT(head_ptr, name, func) \
843-
do { \
844-
static struct security_hook_list hook = { \
845-
.hook = { .name = func } \
846-
}; \
847-
hook.head = head_ptr; \
848-
hook.lsm = "ksu"; \
849-
struct hlist_head *new_head = copy_security_hlist(hook.head); \
850-
if (!new_head) { \
851-
pr_err("Failed to copy security list: %s\n", #name); \
852-
break; \
853-
} \
854-
hlist_add_tail_rcu(&hook.list, new_head); \
855-
if (override_security_head(hook.head, new_head, \
856-
sizeof(*new_head))) { \
857-
free_security_hook_list(new_head); \
858-
pr_err("Failed to hack lsm for: %s\n", #name); \
859-
} \
860-
} while (0)
861-
862-
void __init ksu_lsm_hook_init(void)
863-
{
864-
void *cap_prctl = GET_SYMBOL_ADDR(cap_task_prctl);
865-
void *prctl_head = find_head_addr(cap_prctl, NULL);
866-
if (prctl_head) {
867-
if (prctl_head != &security_hook_heads.task_prctl) {
868-
pr_warn("prctl's address has shifted!\n");
869-
}
870-
KSU_LSM_HOOK_HACK_INIT(prctl_head, task_prctl, ksu_task_prctl);
871-
} else {
872-
pr_warn("Failed to find task_prctl!\n");
873-
}
874-
875-
int inode_killpriv_index = -1;
876-
void *cap_killpriv = GET_SYMBOL_ADDR(cap_inode_killpriv);
877-
find_head_addr(cap_killpriv, &inode_killpriv_index);
878-
if (inode_killpriv_index < 0) {
879-
pr_warn("Failed to find inode_rename, use kprobe instead!\n");
880-
register_kprobe(&renameat_kp);
881-
} else {
882-
int inode_rename_index = inode_killpriv_index +
883-
&security_hook_heads.inode_rename -
884-
&security_hook_heads.inode_killpriv;
885-
struct hlist_head *head_start =
886-
(struct hlist_head *)&security_hook_heads;
887-
void *inode_rename_head = head_start + inode_rename_index;
888-
if (inode_rename_head != &security_hook_heads.inode_rename) {
889-
pr_warn("inode_rename's address has shifted!\n");
890-
}
891-
KSU_LSM_HOOK_HACK_INIT(inode_rename_head, inode_rename,
892-
ksu_inode_rename);
893-
}
894-
void *cap_setuid = GET_SYMBOL_ADDR(cap_task_fix_setuid);
895-
void *setuid_head = find_head_addr(cap_setuid, NULL);
896-
if (setuid_head) {
897-
if (setuid_head != &security_hook_heads.task_fix_setuid) {
898-
pr_warn("setuid's address has shifted!\n");
899-
}
900-
KSU_LSM_HOOK_HACK_INIT(setuid_head, task_fix_setuid,
901-
ksu_task_fix_setuid);
902-
} else {
903-
pr_warn("Failed to find task_fix_setuid!\n");
904-
}
905-
smp_mb();
906-
}
907-
#endif
908-
909658
void __init ksu_core_init(void)
910659
{
911660
ksu_lsm_hook_init();
912661
}
913-
914-
void ksu_core_exit(void)
915-
{
916-
#ifdef CONFIG_KPROBES
917-
pr_info("ksu_core_kprobe_exit\n");
918-
// we dont use this now
919-
// ksu_kprobe_exit();
920-
#endif
921-
}

0 commit comments

Comments
 (0)