Skip to content

Commit d664fe3

Browse files
powellnormauser
authored andcommitted
kernel: selinux: add security_bounded_transition hook for kernel < 4.14
- torvalds/linux@af63f41 - SELinux domain transitions under NNP/nosuid environment was introduced in 4.14 by the above commit, for older kernels, we need to make sure our domain transitions are allowed when calling ksud at boot from the init - Adapted from #270 (comment) https://github.com/ookiineko/KernelSU/commit/0950fbba5e79820da539054f6eb6d1d48ec96ff4
1 parent f281665 commit d664fe3

File tree

6 files changed

+80
-2
lines changed

6 files changed

+80
-2
lines changed

kernel/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ kernelsu-objs += kernel_compat.o
1111
kernelsu-objs += selinux/selinux.o
1212
kernelsu-objs += selinux/sepolicy.o
1313
kernelsu-objs += selinux/rules.o
14+
kernelsu-objs += selinux/kernel_compat.o
1415
ccflags-y += -I$(srctree)/security/selinux -I$(srctree)/security/selinux/include
1516
ccflags-y += -I$(objtree)/security/selinux -include $(srctree)/include/uapi/asm-generic/errno.h
1617

kernel/ksu.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ extern void ksu_sucompat_exit();
3737
extern void ksu_ksud_init();
3838
extern void ksu_ksud_exit();
3939

40+
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)
41+
extern void ksu_enable_selinux_compat();
42+
#endif
43+
4044
int __init kernelsu_init(void)
4145
{
4246
#ifdef CONFIG_KSU_DEBUG
@@ -60,6 +64,9 @@ int __init kernelsu_init(void)
6064
#ifdef CONFIG_KPROBES
6165
ksu_sucompat_init();
6266
ksu_ksud_init();
67+
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)
68+
ksu_enable_selinux_compat();
69+
#endif
6370
#else
6471
pr_alert("KPROBES is disabled, KernelSU may not work, please check https://kernelsu.org/guide/how-to-integrate-for-non-gki.html");
6572
#endif

kernel/selinux/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
obj-y += selinux.o
22
obj-y += sepolicy.o
33
obj-y += rules.o
4+
obj-y += kernel_compat.o
45

56
ifeq ($(shell grep -q " current_sid(void)" $(srctree)/security/selinux/include/objsec.h; echo $$?),0)
67
ccflags-y += -DKSU_COMPAT_HAS_CURRENT_SID

kernel/selinux/kernel_compat.c

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#include "linux/version.h"
2+
3+
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)
4+
#include "linux/types.h"
5+
#ifdef CONFIG_KPROBES
6+
#include "linux/kprobes.h"
7+
#endif
8+
#include "avc_ss.h"
9+
10+
#include "selinux.h"
11+
#include "../klog.h" // IWYU pragma: keep
12+
#include "../arch.h"
13+
int ksu_handle_security_bounded_transition(u32 *old_sid, u32 *new_sid) {
14+
u32 init_sid, su_sid;
15+
int error;
16+
17+
if (!ss_initialized)
18+
return 0;
19+
20+
/* domain unchanged */
21+
if (*old_sid == *new_sid)
22+
return 0;
23+
24+
const char *init_domain = INIT_DOMAIN;
25+
const char *su_domain = KERNEL_SU_DOMAIN;
26+
27+
error = security_secctx_to_secid(init_domain, strlen(init_domain), &init_sid);
28+
if (error) {
29+
pr_warn("cannot get sid of init context, err %d\n", error);
30+
return 0;
31+
}
32+
33+
error = security_secctx_to_secid(su_domain, strlen(su_domain), &su_sid);
34+
if (error) {
35+
pr_warn("cannot get sid of su context, err %d\n", error);
36+
return 0;
37+
}
38+
39+
if (*old_sid == init_sid && *new_sid == su_sid) {
40+
pr_info("init to su transition found\n");
41+
*old_sid = *new_sid; // make the original func return 0
42+
}
43+
44+
return 0;
45+
}
46+
47+
#ifdef CONFIG_KPROBES
48+
static int handler_pre(struct kprobe *p, struct pt_regs *regs) {
49+
u32 *old_sid = (u32 *)&PT_REGS_PARM1(regs);
50+
u32 *new_sid = (u32 *)&PT_REGS_PARM2(regs);
51+
52+
return ksu_handle_security_bounded_transition(old_sid, new_sid);
53+
}
54+
55+
static struct kprobe kp = {
56+
.symbol_name = "security_bounded_transition",
57+
.pre_handler = handler_pre,
58+
};
59+
60+
// selinux_compat: make ksud init trigger work for kernel < 4.14
61+
void ksu_enable_selinux_compat() {
62+
int ret;
63+
64+
ret = register_kprobe(&kp);
65+
pr_info("selinux_compat: kp: %d\n", ret);
66+
}
67+
#endif
68+
#endif

kernel/selinux/selinux.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
#include "avc.h"
77
#endif
88

9-
#define KERNEL_SU_DOMAIN "u:r:su:s0"
10-
119
static int transive_to_domain(const char *domain)
1210
{
1311
struct cred *cred;

kernel/selinux/selinux.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
#include "linux/types.h"
55
#include "linux/version.h"
66

7+
#define KERNEL_SU_DOMAIN "u:r:su:s0"
8+
#define INIT_DOMAIN "u:r:init:s0"
9+
710
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)) || defined(KSU_COMPAT_HAS_SELINUX_STATE)
811
#define KSU_COMPAT_USE_SELINUX_STATE
912
#endif

0 commit comments

Comments
 (0)