Skip to content

Commit f5e9c30

Browse files
backslashxxExtremeXTacroreiser
committed
kernel: squash all changes
SQUASH: kernel: drop LKM and kprobes support kernel: restore compat code required for old kernels kernel: expose allowlist workaround as Kconfig option kernel: core_hook: screw path_umount backport, call sys_umount directly kernel: core_hook: expose prctl interface for umount list (5ec1cff#16) kernel: core_hook: add wipe umount list cmd kernel: core_hook: only umount when unmountable > 0 kernel: core_hook: expose nuke_ext4_sysfs to prctl interface kernel: throne_tracker: offload to kthread (tiann#2632) kernel: sucompat: increase reliability, commonize and micro-optimize (tiann#2656) kernel: sucompat: sucompat toggle support for non-kp (tiann#2506) kernel: ksud: migrate ksud execution to security_bprm_check (tiann#2653) kernel: core_hook: remove devpts workaround kernel: compat: migrate sucompat strncpy_from_user to copy_from_user kernel: selinux: fix pointer mismatch with 32-bit ksud on 64-bit kernels kernel: ksud: provide dummy handlers for old hooks kernel: core_hook: earlier escape_to_root already-root check kernel: expose KSU_LSM_SECURITY_HOOKS on Kconfig kernel: sucompat: provide do_execve_common handler for < 3.14 kernel: sucompat: provide getname_flags (user) ultimatum hook kernel: sucompat: provide getname_flags (kernel) ultimatum hook kernel: sucompat: provide vfs_statx hook handler >= 5.18 kernel: core_hook: harden prctl handler kernel: harden barriers for arm/arm64 kernel: core_hook: add support for KernelNoSU v2 kernel: kp_ksud: restore kprobes for early-boot and used-once hooks kernel: kp_ksud: add security_bounded_transition hook for < 4.14 (tiann#1704) kernel: rp_sucompat: add kretprobes-hooked getname_flags for sucompat kernel: extras: base implementation of avc log spoofing kernel: extras/avc_spoof: add kprobe support kernel: ksud: provide is_ksu_transition check v2 kernel: apk_sign: casting to char for strcmp -> memcmp kernel: apk_sign: migrate generic_file_llseek -> vfs_llseek kernel: core_hook: no ext4_unregister_sysfs, no problem kernel: ksud: d_is_reg to S_ISREG kernel: Makefile: remove overlayfs requirement kernel: throne_tracker: resolve s_magic for < 3.9 kernel: ksud: handle conditional read_iter requirement for < 3.16 kernel: throne_tracker: handle filldir_t ABI mismatch on <= 3.18 kernel: compat: iterate_dir -> vfs_readdir compat for < 3.11 kernel: sucompat: bruteforce writeable stack from start_stack for < 3.8 kernel: apk_sign: provide bin2hex compat for < 3.18 kernel: throne_tracker: add strscpy pseudo-compat for < 4.3 kernel: apk_sign: fix return check for ksu_sha256 kernel: handle backports kernel: apk_sign: add more size/hash pairs kernel: ksu: printout quirks / backports / etc on init Signed-off-by: backslashxx <[email protected]> Co-Authored-By: ExtremeXT <[email protected]> Co-Authored-By: Yaroslav Zviezda <[email protected]>
1 parent 5dcc2eb commit f5e9c30

27 files changed

+2186
-1036
lines changed

kernel/Kconfig

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,35 @@
11
menu "KernelSU"
22

33
config KSU
4-
tristate "KernelSU function support"
5-
depends on OVERLAY_FS
4+
bool "KernelSU function support"
65
default y
76
help
87
Enable kernel-level root privileges on Android System.
9-
To compile as a module, choose M here: the
10-
module will be called kernelsu.
8+
9+
config KSU_EXTRAS
10+
bool "Enable custom stuff"
11+
default n
12+
help
13+
Custom extensions. Experimental.
14+
Currently, only avc log spoofing is implemented.
15+
16+
config KSU_KPROBES_KSUD
17+
bool "Enable dynamic kprobes for early boot hooks"
18+
depends on KPROBES
19+
default y
20+
help
21+
Use dynamic hooks via kprobes for functions needed only
22+
on early boot. Hooks are unregistered at boot complete
23+
to reduce overhead.
24+
25+
config KSU_KRETPROBES_SUCOMPAT
26+
bool "EXPERIMENTAL: kretprobes for sucompat"
27+
depends on KRETPROBES
28+
default n
29+
help
30+
EXPERIMENTAL: Use kretprobes for hooking getname_flags, mainly for
31+
sucompat. This method will hijack all fs-related syscalls, but
32+
thwarts timing based detections.
1133

1234
config KSU_DEBUG
1335
bool "KernelSU debug mode"
@@ -16,4 +38,29 @@ config KSU_DEBUG
1638
help
1739
Enable KernelSU debug mode.
1840

41+
config KSU_THRONE_TRACKER_ALWAYS_THREADED
42+
bool "Always run throne tracker in a kthread"
43+
default n
44+
help
45+
Enable this option to run throne tracker in a kthread for the first
46+
run, which happens at boot time / decryption stage. This can decrease
47+
boot time, but can cause crowning failure on some FDE/FBEv1 setups.
48+
If unsure, say n.
49+
50+
config KSU_ALLOWLIST_WORKAROUND
51+
bool "KernelSU Session Keyring Init workaround"
52+
depends on KSU
53+
default n
54+
help
55+
Enable session keyring init workaround for problematic devices.
56+
Useful for situations where the SU allowlist is not kept after a reboot.
57+
58+
config KSU_LSM_SECURITY_HOOKS
59+
bool "Use LSM security hooks"
60+
depends on KSU
61+
default y
62+
help
63+
Disabling this is mostly useful for kernels < 4.2 and > 6.8.
64+
Make sure to implement manual hooks on security/security.c.
65+
1966
endmenu

kernel/Makefile

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,23 @@ kernelsu-objs += allowlist.o
33
kernelsu-objs += apk_sign.o
44
kernelsu-objs += sucompat.o
55
kernelsu-objs += throne_tracker.o
6-
kernelsu-objs += pkg_observer.o
76
kernelsu-objs += core_hook.o
87
kernelsu-objs += ksud.o
98
kernelsu-objs += embed_ksud.o
109
kernelsu-objs += kernel_compat.o
1110

11+
ifeq ($(CONFIG_KSU_EXTRAS),y)
12+
kernelsu-objs += extras.o
13+
endif
14+
15+
ifeq ($(CONFIG_KSU_KPROBES_KSUD),y)
16+
kernelsu-objs += kp_ksud.o
17+
endif
18+
19+
ifeq ($(CONFIG_KSU_KRETPROBES_SUCOMPAT),y)
20+
kernelsu-objs += rp_sucompat.o
21+
endif
22+
1223
kernelsu-objs += selinux/selinux.o
1324
kernelsu-objs += selinux/sepolicy.o
1425
kernelsu-objs += selinux/rules.o
@@ -50,6 +61,14 @@ $(warning "KSU_GIT_VERSION not defined! It is better to make KernelSU a git repo
5061
ccflags-y += -DKSU_VERSION=16
5162
endif
5263

64+
ifeq ($(shell grep -q " current_sid(void)" $(srctree)/security/selinux/include/objsec.h; echo $$?),0)
65+
ccflags-y += -DKSU_COMPAT_HAS_CURRENT_SID
66+
endif
67+
68+
ifeq ($(shell grep -q "struct selinux_state " $(srctree)/security/selinux/include/security.h; echo $$?),0)
69+
ccflags-y += -DKSU_COMPAT_HAS_SELINUX_STATE
70+
endif
71+
5372
ifndef KSU_EXPECTED_SIZE
5473
KSU_EXPECTED_SIZE := 0x033b
5574
endif
@@ -69,6 +88,48 @@ $(info -- KernelSU Manager signature hash: $(KSU_EXPECTED_HASH))
6988
ccflags-y += -DEXPECTED_SIZE=$(KSU_EXPECTED_SIZE)
7089
ccflags-y += -DEXPECTED_HASH=\"$(KSU_EXPECTED_HASH)\"
7190

91+
# UL, look for iterate_dir on ‎fs/readdir.c
92+
ifeq ($(shell grep -q "^int iterate_dir" $(srctree)/fs/readdir.c 2>/dev/null; echo $$?),0)
93+
$(info -- KernelSU/compat: iterate_dir found!)
94+
ccflags-y += -DKSU_HAS_ITERATE_DIR
95+
endif
96+
97+
# UL, look for read_iter on f_op struct
98+
ifeq ($(shell grep -q "read_iter" $(srctree)/include/linux/fs.h 2>/dev/null; echo $$?),0)
99+
$(info -- KernelSU/compat: f_op->read_iter found!)
100+
ccflags-y += -DKSU_HAS_FOP_READ_ITER
101+
endif
102+
103+
# UL, look for "ext4_unregister_sysfs" on fs/ext4
104+
ifeq ($(shell grep -q "^extern void ext4_unregister_sysfs" $(srctree)/fs/ext4/ext4.h 2>/dev/null; echo $$?),0)
105+
ccflags-y += -DKSU_HAS_MODERN_EXT4
106+
endif
107+
108+
ifeq ($(shell grep -q "int path_umount" $(srctree)/fs/namespace.c; echo $$?),0)
109+
$(info -- KernelSU/compat: path_umount found)
110+
ccflags-y += -DKSU_HAS_PATH_UMOUNT
111+
endif
112+
113+
ifeq ($(shell grep -q "^long copy_from_user_nofault" $(srctree)/include/linux/uaccess.h; echo $$?),0)
114+
$(info -- KernelSU/compat: copy_from_user_nofault found)
115+
ccflags-y += -DKSU_COPY_FROM_USER_NOFAULT
116+
endif
117+
118+
ifeq ($(shell grep -q "^extern long probe_user_read" $(srctree)/include/linux/uaccess.h; echo $$?),0)
119+
$(info -- KernelSU/compat: probe_user_read found)
120+
ccflags-y += -DKSU_PROBE_USER_READ
121+
endif
122+
123+
ifeq ($(shell grep -q "ssize_t kernel_read" $(srctree)/fs/read_write.c; echo $$?),0)
124+
$(info -- KernelSU/compat: newer kernel_read found)
125+
ccflags-y += -DKSU_NEW_KERNEL_READ
126+
endif
127+
128+
ifeq ($(shell grep "ssize_t kernel_write" $(srctree)/fs/read_write.c | grep -q "const void" ; echo $$?),0)
129+
$(info -- KernelSU/compat: newer kernel_write found)
130+
ccflags-y += -DKSU_NEW_KERNEL_WRITE
131+
endif
132+
72133
ccflags-y += -Wno-implicit-function-declaration -Wno-strict-prototypes -Wno-int-conversion -Wno-gcc-compat
73134
ccflags-y += -Wno-declaration-after-statement -Wno-unused-function
74135

kernel/allowlist.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
#include <linux/slab.h>
99
#include <linux/types.h>
1010
#include <linux/version.h>
11+
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)
1112
#include <linux/compiler_types.h>
13+
#endif
1214

1315
#include "ksu.h"
1416
#include "klog.h" // IWYU pragma: keep

kernel/apk_sign.c

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "apk_sign.h"
1818
#include "klog.h" // IWYU pragma: keep
1919
#include "kernel_compat.h"
20+
#include "throne_tracker.h"
2021

2122

2223
struct sdesc {
@@ -100,7 +101,7 @@ static bool check_block(struct file *fp, u32 *size4, loff_t *pos, u32 *offset,
100101
}
101102
ksu_kernel_read_compat(fp, cert, *size4, pos);
102103
unsigned char digest[SHA256_DIGEST_SIZE];
103-
if (IS_ERR(ksu_sha256(cert, *size4, digest))) {
104+
if (ksu_sha256(cert, *size4, digest) < 0 ) {
104105
pr_info("sha256 error\n");
105106
return false;
106107
}
@@ -187,6 +188,23 @@ static __always_inline bool check_v2_signature(char *path,
187188
bool v3_1_signing_exist = false;
188189

189190
int i;
191+
struct path kpath;
192+
if (kern_path(path, 0, &kpath))
193+
return false;
194+
195+
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)
196+
if (inode_is_locked(kpath.dentry->d_inode))
197+
#else
198+
if (mutex_is_locked(&kpath.dentry->d_inode->i_mutex))
199+
#endif
200+
{
201+
pr_info("%s: inode is locked for %s\n", __func__, path);
202+
path_put(&kpath);
203+
return false;
204+
}
205+
206+
path_put(&kpath);
207+
190208
struct file *fp = ksu_filp_open_compat(path, O_RDONLY, 0);
191209
if (IS_ERR(fp)) {
192210
pr_err("open %s error.\n", path);
@@ -199,7 +217,7 @@ static __always_inline bool check_v2_signature(char *path,
199217
// https://en.wikipedia.org/wiki/Zip_(file_format)#End_of_central_directory_record_(EOCD)
200218
for (i = 0;; ++i) {
201219
unsigned short n;
202-
pos = generic_file_llseek(fp, -i - 2, SEEK_END);
220+
pos = vfs_llseek(fp, -i - 2, SEEK_END);
203221
ksu_kernel_read_compat(fp, &n, 2, &pos);
204222
if (n == i) {
205223
pos -= 22;
@@ -221,7 +239,8 @@ static __always_inline bool check_v2_signature(char *path,
221239

222240
ksu_kernel_read_compat(fp, &size8, 0x8, &pos);
223241
ksu_kernel_read_compat(fp, buffer, 0x10, &pos);
224-
if (strcmp((char *)buffer, "APK Sig Block 42")) {
242+
// !! remove this casting to char just to strcmp
243+
if (memcmp(buffer, "APK Sig Block 42", 16)) {
225244
goto clean;
226245
}
227246

@@ -316,8 +335,28 @@ module_param_cb(ksu_debug_manager_uid, &expected_size_ops,
316335

317336
bool is_manager_apk(char *path)
318337
{
338+
int tries = 0;
339+
340+
while (tries++ < 10) {
341+
if (!is_lock_held(path))
342+
break;
343+
344+
pr_info("%s: waiting for %s\n", __func__, path);
345+
msleep(100);
346+
}
347+
348+
// let it go, if retry fails, check_v2_signature will fail to open it anyway
349+
if (tries == 10) {
350+
pr_info("%s: timeout for %s\n", __func__, path);
351+
return false;
352+
}
353+
319354
return (check_v2_signature(path, 0x363, "4359c171f32543394cbc23ef908c4bb94cad7c8087002ba164c8230948c21549") // dummy.keystore
320355
|| check_v2_signature(path, EXPECTED_SIZE, EXPECTED_HASH) // ksu official
321-
/* || check_v2_signature(path, custom_size, custom_hash) // add more as you like */
356+
|| check_v2_signature(path, 384, "7e0c6d7278a3bb8e364e0fcba95afaf3666cf5ff3c245a3b63c8833bd0445cc4") // 5ec1cff/KernelSU
357+
|| check_v2_signature(path, 0x375, "484fcba6e6c43b1fb09700633bf2fb4758f13cb0b2f4457b80d075084b26c588") // KOWX712/KernelSU
358+
|| check_v2_signature(path, 0x396, "f415f4ed9435427e1fdf7f1fccd4dbc07b3d6b8751e4dbcec6f19671f427870b") // rsuntk/KernelSU
359+
|| check_v2_signature(path, 0x3e6, "79e590113c4c4c0c222978e413a5faa801666957b1212a328e46c00c69821bf7") // rifsxd/KernelSU-Next
360+
|| check_v2_signature(path, 0x35c, "947ae944f3de4ed4c21a7e4f7953ecf351bfa2b36239da37a34111ad29993eef") // ShirkNeko/SukiSU-Ultra
322361
);
323362
}

kernel/arch.h

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,40 @@
1818
#define __PT_SP_REG sp
1919
#define __PT_IP_REG pc
2020

21-
#define PRCTL_SYMBOL "__arm64_sys_prctl"
22-
#define SYS_READ_SYMBOL "__arm64_sys_read"
23-
#define SYS_NEWFSTATAT_SYMBOL "__arm64_sys_newfstatat"
24-
#define SYS_FACCESSAT_SYMBOL "__arm64_sys_faccessat"
21+
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0)
2522
#define SYS_EXECVE_SYMBOL "__arm64_sys_execve"
23+
#else
24+
#define SYS_EXECVE_SYMBOL "sys_execve"
25+
#endif
26+
27+
#elif defined(__arm__)
28+
29+
// https://elixir.bootlin.com/linux/v6.17-rc6/source/tools/lib/bpf/bpf_tracing.h
30+
#define __PT_PARM1_REG uregs[0]
31+
#define __PT_PARM2_REG uregs[1]
32+
#define __PT_PARM3_REG uregs[2]
33+
#define __PT_PARM4_REG uregs[3]
34+
35+
// seems to work atleast on 3.0 on samsung galaxy s3
36+
// nfi what im doing
37+
#define __PT_SYSCALL_PARM4_REG uregs[3]
38+
#define __PT_CCALL_PARM4_REG uregs[3]
39+
40+
#define __PT_PARM1_SYSCALL_REG __PT_PARM1_REG
41+
#define __PT_PARM2_SYSCALL_REG __PT_PARM2_REG
42+
#define __PT_PARM3_SYSCALL_REG __PT_PARM3_REG
43+
#define __PT_PARM4_SYSCALL_REG __PT_PARM4_REG
44+
#define __PT_PARM5_SYSCALL_REG uregs[4]
45+
#define __PT_PARM6_SYSCALL_REG uregs[5]
46+
#define __PT_PARM7_SYSCALL_REG uregs[6]
47+
48+
#define __PT_RET_REG uregs[14]
49+
#define __PT_FP_REG uregs[11] /* Works only with CONFIG_FRAME_POINTER */
50+
#define __PT_RC_REG uregs[0]
51+
#define __PT_SP_REG uregs[13]
52+
#define __PT_IP_REG uregs[12]
53+
54+
#define SYS_EXECVE_SYMBOL "sys_execve"
2655

2756
#elif defined(__x86_64__)
2857

@@ -39,11 +68,12 @@
3968
#define __PT_RC_REG ax
4069
#define __PT_SP_REG sp
4170
#define __PT_IP_REG ip
42-
#define PRCTL_SYMBOL "__x64_sys_prctl"
43-
#define SYS_READ_SYMBOL "__x64_sys_read"
44-
#define SYS_NEWFSTATAT_SYMBOL "__x64_sys_newfstatat"
45-
#define SYS_FACCESSAT_SYMBOL "__x64_sys_faccessat"
71+
72+
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0)
4673
#define SYS_EXECVE_SYMBOL "__x64_sys_execve"
74+
#else
75+
#define SYS_EXECVE_SYMBOL "sys_execve"
76+
#endif
4777

4878
#else
4979
#error "Unsupported arch"
@@ -67,6 +97,10 @@
6797
#define PT_REGS_SP(x) (__PT_REGS_CAST(x)->__PT_SP_REG)
6898
#define PT_REGS_IP(x) (__PT_REGS_CAST(x)->__PT_IP_REG)
6999

100+
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0)
70101
#define PT_REAL_REGS(regs) ((struct pt_regs *)PT_REGS_PARM1(regs))
102+
#else
103+
#define PT_REAL_REGS(regs) ((regs))
104+
#endif
71105

72106
#endif

0 commit comments

Comments
 (0)