Signed-off-by: Ookiineko <chiisaineko@protonmail.com> Co-authored-by: f19 <58457605+F-19-F@users.noreply.github.com> Co-authored-by: Scirese <nuclearlight91@gmail.com>
This commit is contained in:
@@ -1,3 +1,8 @@
|
|||||||
|
#ifndef __KSU_H_KERNEL_COMPAT
|
||||||
|
#define __KSU_H_KERNEL_COMPAT
|
||||||
|
|
||||||
#include "linux/fs.h"
|
#include "linux/fs.h"
|
||||||
|
|
||||||
extern ssize_t kernel_read_compat(struct file *p, void* buf, size_t count, loff_t *pos);
|
extern ssize_t kernel_read_compat(struct file *p, void* buf, size_t count, loff_t *pos);
|
||||||
extern ssize_t kernel_write_compat(struct file *p, const void *buf, size_t count, loff_t *pos);
|
extern ssize_t kernel_write_compat(struct file *p, const void *buf, size_t count, loff_t *pos);
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -212,11 +212,9 @@ static int read_handler_pre(struct kprobe *p, struct pt_regs *regs)
|
|||||||
static struct kprobe execve_kp = {
|
static struct kprobe execve_kp = {
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0)
|
||||||
.symbol_name = "do_execveat_common",
|
.symbol_name = "do_execveat_common",
|
||||||
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) && \
|
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)
|
||||||
LINUX_VERSION_CODE < KERNEL_VERSION(5, 9, 0)
|
|
||||||
.symbol_name = "__do_execve_file",
|
.symbol_name = "__do_execve_file",
|
||||||
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0) && \
|
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)
|
||||||
LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0)
|
|
||||||
.symbol_name = "do_execveat_common",
|
.symbol_name = "do_execveat_common",
|
||||||
#endif
|
#endif
|
||||||
.pre_handler = execve_handler_pre,
|
.pre_handler = execve_handler_pre,
|
||||||
|
|||||||
@@ -53,35 +53,50 @@ if (!is_domain_permissive) {
|
|||||||
|
|
||||||
void setenforce(bool enforce)
|
void setenforce(bool enforce)
|
||||||
{
|
{
|
||||||
#if LINUX_VERSION_CODE > KERNEL_VERSION(4, 14, 0)
|
|
||||||
#ifdef CONFIG_SECURITY_SELINUX_DEVELOP
|
#ifdef CONFIG_SECURITY_SELINUX_DEVELOP
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0)
|
||||||
selinux_state.enforcing = enforce;
|
selinux_state.enforcing = enforce;
|
||||||
#endif
|
|
||||||
#else
|
#else
|
||||||
selinux_enabled = enforce;
|
selinux_enabled = enforce;
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool getenforce()
|
bool getenforce()
|
||||||
{
|
{
|
||||||
#if LINUX_VERSION_CODE > KERNEL_VERSION(4, 14, 0)
|
|
||||||
#ifdef CONFIG_SECURITY_SELINUX_DISABLE
|
#ifdef CONFIG_SECURITY_SELINUX_DISABLE
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0)
|
||||||
if (selinux_state.disabled) {
|
if (selinux_state.disabled) {
|
||||||
|
#else
|
||||||
|
if (selinux_disabled) {
|
||||||
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_SECURITY_SELINUX_DEVELOP
|
#ifdef CONFIG_SECURITY_SELINUX_DEVELOP
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0)
|
||||||
return selinux_state.enforcing;
|
return selinux_state.enforcing;
|
||||||
#else
|
#else
|
||||||
return false;
|
return selinux_enabled;
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
return selinux_enabled;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0)
|
||||||
|
/*
|
||||||
|
* get the subjective security ID of the current task
|
||||||
|
*/
|
||||||
|
static inline u32 current_sid(void)
|
||||||
|
{
|
||||||
|
const struct task_security_struct *tsec = current_security();
|
||||||
|
|
||||||
|
return tsec->sid;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
bool is_ksu_domain()
|
bool is_ksu_domain()
|
||||||
{
|
{
|
||||||
return ksu_sid && current_sid() == ksu_sid;
|
return ksu_sid && current_sid() == ksu_sid;
|
||||||
|
|||||||
@@ -134,17 +134,16 @@ static int faccessat_handler_pre(struct kprobe *p, struct pt_regs *regs)
|
|||||||
|
|
||||||
static int newfstatat_handler_pre(struct kprobe *p, struct pt_regs *regs)
|
static int newfstatat_handler_pre(struct kprobe *p, struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
// static int vfs_statx(int dfd, const char __user *filename, int flags,struct kstat *stat, u32 request_mask)
|
|
||||||
int *dfd = (int *)&PT_REGS_PARM1(regs);
|
int *dfd = (int *)&PT_REGS_PARM1(regs);
|
||||||
const char __user **filename_user = (const char **)&PT_REGS_PARM2(regs);
|
const char __user **filename_user = (const char **)&PT_REGS_PARM2(regs);
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
|
||||||
|
// static int vfs_statx(int dfd, const char __user *filename, int flags, struct kstat *stat, u32 request_mask)
|
||||||
int *flags = (int *)&PT_REGS_PARM3(regs);
|
int *flags = (int *)&PT_REGS_PARM3(regs);
|
||||||
#else
|
#else
|
||||||
// int vfs_fstatat(int dfd, const char __user *filename, struct kstat *stat,int flag)
|
// int vfs_fstatat(int dfd, const char __user *filename, struct kstat *stat,int flag)
|
||||||
int *flags = (int *)&PT_REGS_PARM4(regs);
|
int *flags = (int *)&PT_REGS_PARM4(regs);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
return ksu_handle_stat(dfd, filename_user, flags);
|
return ksu_handle_stat(dfd, filename_user, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -172,10 +171,10 @@ static struct kprobe faccessat_kp = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static struct kprobe newfstatat_kp = {
|
static struct kprobe newfstatat_kp = {
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
|
||||||
.symbol_name = "vfs_statx",
|
.symbol_name = "vfs_statx",
|
||||||
#else
|
#else
|
||||||
.symbol_name = "vfs_fstatat",
|
.symbol_name = "vfs_fstatat",
|
||||||
#endif
|
#endif
|
||||||
.pre_handler = newfstatat_handler_pre,
|
.pre_handler = newfstatat_handler_pre,
|
||||||
};
|
};
|
||||||
@@ -183,14 +182,9 @@ static struct kprobe newfstatat_kp = {
|
|||||||
static struct kprobe execve_kp = {
|
static struct kprobe execve_kp = {
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0)
|
||||||
.symbol_name = "do_execveat_common",
|
.symbol_name = "do_execveat_common",
|
||||||
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) && \
|
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)
|
||||||
LINUX_VERSION_CODE < KERNEL_VERSION(5, 9, 0)
|
|
||||||
.symbol_name = "__do_execve_file",
|
.symbol_name = "__do_execve_file",
|
||||||
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) && \
|
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)
|
||||||
LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0)
|
|
||||||
.symbol_name = "do_execveat_common",
|
|
||||||
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0) && \
|
|
||||||
LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)
|
|
||||||
.symbol_name = "do_execveat_common",
|
.symbol_name = "do_execveat_common",
|
||||||
#endif
|
#endif
|
||||||
.pre_handler = execve_handler_pre,
|
.pre_handler = execve_handler_pre,
|
||||||
|
|||||||
@@ -142,4 +142,31 @@ You should found the four functions in kernel source:
|
|||||||
3. vfs_read, usually in `fs/read_write.c`
|
3. vfs_read, usually in `fs/read_write.c`
|
||||||
4. vfs_statx, usually in `fs/stat.c`
|
4. vfs_statx, usually in `fs/stat.c`
|
||||||
|
|
||||||
|
If your kernel does not have the `vfs_statx`, use `vfs_fstatat` instead:
|
||||||
|
|
||||||
|
```diff
|
||||||
|
diff --git a/fs/stat.c b/fs/stat.c
|
||||||
|
index 068fdbcc9e26..5348b7bb9db2 100644
|
||||||
|
--- a/fs/stat.c
|
||||||
|
+++ b/fs/stat.c
|
||||||
|
@@ -87,6 +87,8 @@ int vfs_fstat(unsigned int fd, struct kstat *stat)
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(vfs_fstat);
|
||||||
|
|
||||||
|
+extern int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags);
|
||||||
|
+
|
||||||
|
int vfs_fstatat(int dfd, const char __user *filename, struct kstat *stat,
|
||||||
|
int flag)
|
||||||
|
{
|
||||||
|
@@ -94,6 +96,8 @@ int vfs_fstatat(int dfd, const char __user *filename, struct kstat *stat,
|
||||||
|
int error = -EINVAL;
|
||||||
|
unsigned int lookup_flags = 0;
|
||||||
|
|
||||||
|
+ ksu_handle_stat(&dfd, &filename, &flag);
|
||||||
|
+
|
||||||
|
if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT |
|
||||||
|
AT_EMPTY_PATH)) != 0)
|
||||||
|
goto out;
|
||||||
|
```
|
||||||
|
|
||||||
Finally, build your kernel again, KernelSU should works well.
|
Finally, build your kernel again, KernelSU should works well.
|
||||||
|
|||||||
@@ -142,4 +142,31 @@ index 376543199b5a..82adcef03ecc 100644
|
|||||||
3. vfs_read,通常位于 `fs/read_write.c`
|
3. vfs_read,通常位于 `fs/read_write.c`
|
||||||
4. vfs_statx,通常位于 `fs/stat.c`
|
4. vfs_statx,通常位于 `fs/stat.c`
|
||||||
|
|
||||||
|
如果你的内核没有 `vfs_statx`, 使用 `vfs_fstatat` 来代替它:
|
||||||
|
|
||||||
|
```diff
|
||||||
|
diff --git a/fs/stat.c b/fs/stat.c
|
||||||
|
index 068fdbcc9e26..5348b7bb9db2 100644
|
||||||
|
--- a/fs/stat.c
|
||||||
|
+++ b/fs/stat.c
|
||||||
|
@@ -87,6 +87,8 @@ int vfs_fstat(unsigned int fd, struct kstat *stat)
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(vfs_fstat);
|
||||||
|
|
||||||
|
+extern int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags);
|
||||||
|
+
|
||||||
|
int vfs_fstatat(int dfd, const char __user *filename, struct kstat *stat,
|
||||||
|
int flag)
|
||||||
|
{
|
||||||
|
@@ -94,6 +96,8 @@ int vfs_fstatat(int dfd, const char __user *filename, struct kstat *stat,
|
||||||
|
int error = -EINVAL;
|
||||||
|
unsigned int lookup_flags = 0;
|
||||||
|
|
||||||
|
+ ksu_handle_stat(&dfd, &filename, &flag);
|
||||||
|
+
|
||||||
|
if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT |
|
||||||
|
AT_EMPTY_PATH)) != 0)
|
||||||
|
goto out;
|
||||||
|
```
|
||||||
|
|
||||||
改完之后重新编译内核即可。
|
改完之后重新编译内核即可。
|
||||||
|
|||||||
Reference in New Issue
Block a user