Skip to content

Commit 08f3ae0

Browse files
committed
kernel: Revert "[1.0] Drop Non-GKI Support (tiann#1483)"
This reverts commit 898e9d4. Allowing Non-GKI kernel support.
1 parent 985c55e commit 08f3ae0

File tree

14 files changed

+581
-11
lines changed

14 files changed

+581
-11
lines changed

kernel/Makefile

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,14 @@ $(warning "KSU_GIT_VERSION not defined! It is better to make KernelSU a git subm
2929
ccflags-y += -DKSU_VERSION=16
3030
endif
3131

32+
ifeq ($(shell grep -q " current_sid(void)" $(srctree)/security/selinux/include/objsec.h; echo $$?),0)
33+
ccflags-y += -DKSU_COMPAT_HAS_CURRENT_SID
34+
endif
35+
36+
ifeq ($(shell grep -q "struct selinux_state " $(srctree)/security/selinux/include/security.h; echo $$?),0)
37+
ccflags-y += -DKSU_COMPAT_HAS_SELINUX_STATE
38+
endif
39+
3240
ifndef KSU_EXPECTED_SIZE
3341
KSU_EXPECTED_SIZE := 0x033b
3442
endif
@@ -48,6 +56,13 @@ $(info -- KernelSU Manager signature hash: $(KSU_EXPECTED_HASH))
4856
ccflags-y += -DEXPECTED_SIZE=$(KSU_EXPECTED_SIZE)
4957
ccflags-y += -DEXPECTED_HASH=\"$(KSU_EXPECTED_HASH)\"
5058

59+
ifeq ($(shell grep -q "int path_umount" $(srctree)/fs/namespace.c; echo $$?),0)
60+
ccflags-y += -DKSU_UMOUNT
61+
else
62+
$(info -- Did you know you can backport path_umount to fs/namespace.c from 5.9?)
63+
$(info -- Read: https://kernelsu.org/guide/how-to-integrate-for-non-gki.html#how-to-backport-path-umount)
64+
endif
65+
5166
ccflags-y += -Wno-implicit-function-declaration -Wno-strict-prototypes -Wno-int-conversion -Wno-gcc-compat
5267
ccflags-y += -Wno-declaration-after-statement -Wno-unused-function
5368

kernel/allowlist.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
#include <linux/slab.h>
88
#include <linux/types.h>
99
#include <linux/version.h>
10+
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)
1011
#include <linux/compiler_types.h>
12+
#endif
1113

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

kernel/arch.h

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

21+
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0)
2122
#define PRCTL_SYMBOL "__arm64_sys_prctl"
2223
#define SYS_READ_SYMBOL "__arm64_sys_read"
2324
#define SYS_NEWFSTATAT_SYMBOL "__arm64_sys_newfstatat"
2425
#define SYS_FACCESSAT_SYMBOL "__arm64_sys_faccessat"
2526
#define SYS_EXECVE_SYMBOL "__arm64_sys_execve"
27+
#else
28+
#define PRCTL_SYMBOL "sys_prctl"
29+
#define SYS_READ_SYMBOL "sys_read"
30+
#define SYS_NEWFSTATAT_SYMBOL "sys_newfstatat"
31+
#define SYS_FACCESSAT_SYMBOL "sys_faccessat"
32+
#define SYS_EXECVE_SYMBOL "sys_execve"
33+
#endif
2634

2735
#elif defined(__x86_64__)
2836

@@ -39,11 +47,19 @@
3947
#define __PT_RC_REG ax
4048
#define __PT_SP_REG sp
4149
#define __PT_IP_REG ip
50+
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0)
4251
#define PRCTL_SYMBOL "__x64_sys_prctl"
4352
#define SYS_READ_SYMBOL "__x64_sys_read"
4453
#define SYS_NEWFSTATAT_SYMBOL "__x64_sys_newfstatat"
4554
#define SYS_FACCESSAT_SYMBOL "__x64_sys_faccessat"
4655
#define SYS_EXECVE_SYMBOL "__x64_sys_execve"
56+
#else
57+
#define PRCTL_SYMBOL "sys_prctl"
58+
#define SYS_READ_SYMBOL "sys_read"
59+
#define SYS_NEWFSTATAT_SYMBOL "sys_newfstatat"
60+
#define SYS_FACCESSAT_SYMBOL "sys_faccessat"
61+
#define SYS_EXECVE_SYMBOL "sys_execve"
62+
#endif
4763

4864
#else
4965
#error "Unsupported arch"
@@ -67,6 +83,10 @@
6783
#define PT_REGS_SP(x) (__PT_REGS_CAST(x)->__PT_SP_REG)
6884
#define PT_REGS_IP(x) (__PT_REGS_CAST(x)->__PT_IP_REG)
6985

86+
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0)
7087
#define PT_REAL_REGS(regs) ((struct pt_regs *)PT_REGS_PARM1(regs))
88+
#else
89+
#define PT_REAL_REGS(regs) ((regs))
90+
#endif
7191

7292
#endif

kernel/core_hook.c

Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,11 @@ static void setup_groups(struct root_profile *profile, struct cred *cred)
9999
put_group_info(group_info);
100100
return;
101101
}
102+
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)
102103
group_info->gid[i] = kgid;
104+
#else
105+
GROUP_AT(group_info, i) = kgid;
106+
#endif
103107
}
104108

105109
groups_sort(group_info);
@@ -446,12 +450,14 @@ static bool should_umount(struct path *path)
446450
return false;
447451
}
448452

449-
static void ksu_umount_mnt(struct path *path, int flags)
453+
static int ksu_umount_mnt(struct path *path, int flags)
450454
{
451-
int err = path_umount(path, flags);
452-
if (err) {
453-
pr_info("umount %s failed: %d\n", path->dentry->d_iname, err);
454-
}
455+
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0) || defined(KSU_UMOUNT)
456+
return path_umount(path, flags);
457+
#else
458+
// TODO: umount for non GKI kernel
459+
return -ENOSYS;
460+
#endif
455461
}
456462

457463
static void try_umount(const char *mnt, bool check_mnt, int flags)
@@ -472,7 +478,10 @@ static void try_umount(const char *mnt, bool check_mnt, int flags)
472478
return;
473479
}
474480

475-
ksu_umount_mnt(&path, flags);
481+
err = ksu_umount_mnt(&path, flags);
482+
if (err) {
483+
pr_warn("umount %s failed: %d\n", mnt, err);
484+
}
476485
}
477486

478487
int ksu_handle_setuid(struct cred *new, const struct cred *old)
@@ -549,8 +558,14 @@ static int handler_pre(struct kprobe *p, struct pt_regs *regs)
549558
int option = (int)PT_REGS_PARM1(real_regs);
550559
unsigned long arg2 = (unsigned long)PT_REGS_PARM2(real_regs);
551560
unsigned long arg3 = (unsigned long)PT_REGS_PARM3(real_regs);
561+
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0)
552562
// PRCTL_SYMBOL is the arch-specificed one, which receive raw pt_regs from syscall
553563
unsigned long arg4 = (unsigned long)PT_REGS_SYSCALL_PARM4(real_regs);
564+
#else
565+
// PRCTL_SYMBOL is the common one, called by C convention in do_syscall_64
566+
// https://elixir.bootlin.com/linux/v4.15.18/source/arch/x86/entry/common.c#L287
567+
unsigned long arg4 = (unsigned long)PT_REGS_CCALL_PARM4(real_regs);
568+
#endif
554569
unsigned long arg5 = (unsigned long)PT_REGS_PARM5(real_regs);
555570

556571
return ksu_handle_prctl(option, arg2, arg3, arg4, arg5);
@@ -610,7 +625,23 @@ static int ksu_task_prctl(int option, unsigned long arg2, unsigned long arg3,
610625
ksu_handle_prctl(option, arg2, arg3, arg4, arg5);
611626
return -ENOSYS;
612627
}
613-
628+
// kernel 4.4 and 4.9
629+
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || defined(CONFIG_IS_HW_HISI)
630+
static int ksu_key_permission(key_ref_t key_ref, const struct cred *cred,
631+
unsigned perm)
632+
{
633+
if (init_session_keyring != NULL) {
634+
return 0;
635+
}
636+
if (strcmp(current->comm, "init")) {
637+
// we are only interested in `init` process
638+
return 0;
639+
}
640+
init_session_keyring = cred->session_keyring;
641+
pr_info("kernel_compat: got init_session_keyring\n");
642+
return 0;
643+
}
644+
#endif
614645
static int ksu_inode_rename(struct inode *old_inode, struct dentry *old_dentry,
615646
struct inode *new_inode, struct dentry *new_dentry)
616647
{
@@ -628,11 +659,19 @@ static struct security_hook_list ksu_hooks[] = {
628659
LSM_HOOK_INIT(task_prctl, ksu_task_prctl),
629660
LSM_HOOK_INIT(inode_rename, ksu_inode_rename),
630661
LSM_HOOK_INIT(task_fix_setuid, ksu_task_fix_setuid),
662+
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || defined(CONFIG_IS_HW_HISI)
663+
LSM_HOOK_INIT(key_permission, ksu_key_permission)
664+
#endif
631665
};
632666

633667
void __init ksu_lsm_hook_init(void)
634668
{
669+
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
635670
security_add_hooks(ksu_hooks, ARRAY_SIZE(ksu_hooks), "ksu");
671+
#else
672+
// https://elixir.bootlin.com/linux/v4.10.17/source/include/linux/lsm_hooks.h#L1892
673+
security_add_hooks(ksu_hooks, ARRAY_SIZE(ksu_hooks));
674+
#endif
636675
}
637676

638677
#else

kernel/kernel_compat.c

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,39 @@
11
#include <linux/version.h>
22
#include <linux/fs.h>
33
#include <linux/nsproxy.h>
4+
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)
45
#include <linux/sched/task.h>
6+
#else
7+
#include <linux/sched.h>
8+
#endif
59
#include <linux/uaccess.h>
610
#include "klog.h" // IWYU pragma: keep
7-
#include "kernel_compat.h"
11+
#include "kernel_compat.h" // Add check Huawei Device
12+
13+
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || defined(CONFIG_IS_HW_HISI)
14+
#include <linux/key.h>
15+
#include <linux/errno.h>
16+
#include <linux/cred.h>
17+
struct key *init_session_keyring = NULL;
18+
19+
static inline int install_session_keyring(struct key *keyring)
20+
{
21+
struct cred *new;
22+
int ret;
23+
24+
new = prepare_creds();
25+
if (!new)
26+
return -ENOMEM;
27+
28+
ret = install_session_keyring_to_cred(new, keyring);
29+
if (ret < 0) {
30+
abort_creds(new);
31+
return ret;
32+
}
33+
34+
return commit_creds(new);
35+
}
36+
#endif
837

938
extern struct task_struct init_task;
1039

@@ -50,6 +79,13 @@ void ksu_android_ns_fs_check()
5079

5180
struct file *ksu_filp_open_compat(const char *filename, int flags, umode_t mode)
5281
{
82+
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || defined(CONFIG_IS_HW_HISI)
83+
if (init_session_keyring != NULL && !current_cred()->session_keyring &&
84+
(current->flags & PF_WQ_WORKER)) {
85+
pr_info("installing init session keyring for older kernel\n");
86+
install_session_keyring(init_session_keyring);
87+
}
88+
#endif
5389
// switch mnt_ns even if current is not wq_worker, to ensure what we open is the correct file in android mnt_ns, rather than user created mnt_ns
5490
struct ksu_ns_fs_saved saved;
5591
if (android_context_saved_enabled) {
@@ -72,17 +108,69 @@ struct file *ksu_filp_open_compat(const char *filename, int flags, umode_t mode)
72108
ssize_t ksu_kernel_read_compat(struct file *p, void *buf, size_t count,
73109
loff_t *pos)
74110
{
111+
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)
75112
return kernel_read(p, buf, count, pos);
113+
#else
114+
loff_t offset = pos ? *pos : 0;
115+
ssize_t result = kernel_read(p, offset, (char *)buf, count);
116+
if (pos && result > 0) {
117+
*pos = offset + result;
118+
}
119+
return result;
120+
#endif
76121
}
77122

78123
ssize_t ksu_kernel_write_compat(struct file *p, const void *buf, size_t count,
79124
loff_t *pos)
80125
{
126+
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)
81127
return kernel_write(p, buf, count, pos);
128+
#else
129+
loff_t offset = pos ? *pos : 0;
130+
ssize_t result = kernel_write(p, buf, count, offset);
131+
if (pos && result > 0) {
132+
*pos = offset + result;
133+
}
134+
return result;
135+
#endif
82136
}
83137

138+
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
84139
long ksu_strncpy_from_user_nofault(char *dst, const void __user *unsafe_addr,
85140
long count)
86141
{
87142
return strncpy_from_user_nofault(dst, unsafe_addr, count);
88143
}
144+
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
145+
long ksu_strncpy_from_user_nofault(char *dst, const void __user *unsafe_addr,
146+
long count)
147+
{
148+
return strncpy_from_unsafe_user(dst, unsafe_addr, count);
149+
}
150+
#else
151+
// Copied from: https://elixir.bootlin.com/linux/v4.9.337/source/mm/maccess.c#L201
152+
long ksu_strncpy_from_user_nofault(char *dst, const void __user *unsafe_addr,
153+
long count)
154+
{
155+
mm_segment_t old_fs = get_fs();
156+
long ret;
157+
158+
if (unlikely(count <= 0))
159+
return 0;
160+
161+
set_fs(USER_DS);
162+
pagefault_disable();
163+
ret = strncpy_from_user(dst, unsafe_addr, count);
164+
pagefault_enable();
165+
set_fs(old_fs);
166+
167+
if (ret >= count) {
168+
ret = count;
169+
dst[ret - 1] = '\0';
170+
} else if (ret > 0) {
171+
ret++;
172+
}
173+
174+
return ret;
175+
}
176+
#endif

kernel/kernel_compat.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ extern long ksu_strncpy_from_user_nofault(char *dst,
2424
const void __user *unsafe_addr,
2525
long count);
2626

27+
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || defined(CONFIG_IS_HW_HISI)
28+
extern struct key *init_session_keyring;
29+
#endif
30+
2731
extern void ksu_android_ns_fs_check();
2832
extern struct file *ksu_filp_open_compat(const char *filename, int flags,
2933
umode_t mode);

kernel/ksu.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,4 +94,7 @@ module_exit(kernelsu_exit);
9494
MODULE_LICENSE("GPL");
9595
MODULE_AUTHOR("weishu");
9696
MODULE_DESCRIPTION("Android KernelSU");
97+
98+
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
9799
MODULE_IMPORT_NS(VFS_internal_I_am_really_a_filesystem_and_am_NOT_a_driver);
100+
#endif

0 commit comments

Comments
 (0)