Skip to content

Commit 94eb9e5

Browse files
backslashxxselfmusing
authored andcommitted
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 888d7f6 commit 94eb9e5

File tree

9 files changed

+11
-620
lines changed

9 files changed

+11
-620
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);
@@ -633,69 +614,6 @@ int ksu_handle_setuid(struct cred *new, const struct cred *old)
633614
return 0;
634615
}
635616

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

718-
#ifndef MODULE
719636
static struct security_hook_list ksu_hooks[] = {
720637
LSM_HOOK_INIT(task_prctl, ksu_task_prctl),
721638
LSM_HOOK_INIT(inode_rename, ksu_inode_rename),
@@ -727,184 +644,7 @@ void __init ksu_lsm_hook_init(void)
727644
security_add_hooks(ksu_hooks, ARRAY_SIZE(ksu_hooks), "ksu");
728645
}
729646

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

0 commit comments

Comments
 (0)