kernel: Fix compilation for non-gki kernels (#593)

This commit is contained in:
TwinbornPlate75
2025-11-17 20:10:06 +08:00
committed by GitHub
parent 55ddeb63fb
commit 9d5c6ab3fd
10 changed files with 36 additions and 100 deletions

View File

@@ -19,6 +19,7 @@
#include "klog.h" // IWYU pragma: keep
#include "ksud.h"
#include "kernel_compat.h"
#include "selinux/selinux.h"
#include "allowlist.h"
#include "manager.h"
@@ -431,11 +432,7 @@ void persistent_allow_list()
goto put_task;
}
cb->func = do_persistent_allow_list;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0)
task_work_add(tsk, cb, TWA_RESUME);
#else
task_work_add(tsk, cb, true);
#endif
put_task:
put_task_struct(tsk);

View File

@@ -279,7 +279,7 @@ static int ksu_wrapper_fadvise(struct file *fp, loff_t off1, loff_t off2, int fl
static int ksu_wrapper_clone_file_range(struct file *file_in, loff_t pos_in,
struct file *file_out, loff_t pos_out, u64 len) {
// TODO: determine which file to use
struct ksu_file_proxy* data = file_in->private_data;
struct ksu_file_wrapper* data = file_in->private_data;
struct file* orig = data->orig;
if (orig->f_op->clone_file_range) {
return orig->f_op->clone_file_range(orig, pos_in, file_out, pos_out, len);
@@ -290,7 +290,7 @@ static int ksu_wrapper_clone_file_range(struct file *file_in, loff_t pos_in,
static ssize_t ksu_wrapper_dedupe_file_range(struct file *src_file, u64 loff,
u64 len, struct file *dst_file, u64 dst_loff) {
// TODO: determine which file to use
struct ksu_file_proxy* data = src_file->private_data;
struct ksu_file_wrapper* data = src_file->private_data;
struct file* orig = data->orig;
if (orig->f_op->dedupe_file_range) {
return orig->f_op->dedupe_file_range(orig, loff, len, dst_file, dst_loff);

View File

@@ -78,57 +78,3 @@ long ksu_strncpy_from_user_nofault(char *dst, const void __user *unsafe_addr,
return ret;
}
#endif
long ksu_strncpy_from_user_retry(char *dst, const void __user *unsafe_addr,
long count)
{
long ret;
ret = ksu_strncpy_from_user_nofault(dst, unsafe_addr, count);
if (likely(ret >= 0))
return ret;
// we faulted! fallback to slow path
if (unlikely(!ksu_access_ok(unsafe_addr, count))) {
#ifdef CONFIG_KSU_DEBUG
pr_err("%s: faulted!\n", __func__);
#endif
return -EFAULT;
}
// why we don't do like how strncpy_from_user_nofault?
ret = strncpy_from_user(dst, unsafe_addr, count);
if (ret >= count) {
ret = count;
dst[ret - 1] = '\0';
} else if (likely(ret >= 0)) {
ret++;
}
return ret;
}
long ksu_copy_from_user_nofault(void *dst, const void __user *src, size_t size)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
return copy_from_user_nofault(dst, src, size);
#else
// https://elixir.bootlin.com/linux/v5.8/source/mm/maccess.c#L205
long ret = -EFAULT;
mm_segment_t old_fs = get_fs();
set_fs(USER_DS);
// tweaked to use ksu_access_ok
if (ksu_access_ok(src, size)) {
pagefault_disable();
ret = __copy_from_user_inatomic(dst, src, size);
pagefault_enable();
}
set_fs(old_fs);
if (ret)
return -EFAULT;
return 0;
#endif
}

View File

@@ -15,32 +15,12 @@
extern long ksu_strncpy_from_user_nofault(char *dst,
const void __user *unsafe_addr,
long count);
extern long ksu_strncpy_from_user_retry(char *dst,
const void __user *unsafe_addr,
long count);
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || \
defined(CONFIG_IS_HW_HISI) || \
defined(CONFIG_KSU_ALLOWLIST_WORKAROUND)
extern struct key *init_session_keyring;
#endif
/*
* ksu_copy_from_user_retry
* try nofault copy first, if it fails, try with plain
* paramters are the same as copy_from_user
* 0 = success
*/
extern long ksu_copy_from_user_nofault(void *dst, const void __user *src, size_t size);
static long ksu_copy_from_user_retry(void *to,
const void __user *from, unsigned long count)
{
long ret = ksu_copy_from_user_nofault(to, from, count);
if (likely(!ret))
return ret;
// we faulted! fallback to slow path
return copy_from_user(to, from, count);
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
#define ksu_access_ok(addr, size) access_ok(addr, size)
@@ -48,4 +28,14 @@ static long ksu_copy_from_user_retry(void *to,
#define ksu_access_ok(addr, size) access_ok(VERIFY_READ, addr, size)
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 7, 0)
#define TWA_RESUME true
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0)
#define ksu_force_sig(sig) force_sig(sig);
#else
#define ksu_force_sig(sig) force_sig(sig, current);
#endif
#endif

View File

@@ -10,10 +10,12 @@
#include <linux/path.h>
#include <linux/printk.h>
#include <linux/types.h>
#include <linux/uaccess.h>
#include "manager.h"
#include "kernel_umount.h"
#include "klog.h" // IWYU pragma: keep
#include "kernel_compat.h"
#include "allowlist.h"
#include "selinux/selinux.h"
#include "feature.h"
@@ -245,11 +247,7 @@ int ksu_handle_umount(uid_t old_uid, uid_t new_uid)
tw->old_cred = get_current_cred();
tw->cb.func = umount_tw_func;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0)
int err = task_work_add(current, &tw->cb, TWA_RESUME);
#else
int err = task_work_add(current, &tw->cb, true);
#endif
if (err) {
if (tw->old_cred) {
put_cred(tw->old_cred);

View File

@@ -32,6 +32,7 @@
#include "arch.h"
#include "klog.h" // IWYU pragma: keep
#include "ksud.h"
#include "kernel_compat.h"
#include "selinux/selinux.h"
#include "throne_tracker.h"
@@ -254,7 +255,7 @@ int ksu_handle_execveat_ksud(int *fd, struct filename **filename_ptr,
const char __user *p = get_user_arg_ptr(*argv, 1);
if (p && !IS_ERR(p)) {
char first_arg[16];
strncpy_from_user_nofault(first_arg, p, sizeof(first_arg));
ksu_strncpy_from_user_nofault(first_arg, p, sizeof(first_arg));
pr_info("/system/bin/init first arg: %s\n", first_arg);
if (!strcmp(first_arg, "second_stage")) {
pr_info("/system/bin/init second_stage executed\n");
@@ -276,7 +277,7 @@ int ksu_handle_execveat_ksud(int *fd, struct filename **filename_ptr,
const char __user *p = get_user_arg_ptr(*argv, 1);
if (p && !IS_ERR(p)) {
char first_arg[16];
strncpy_from_user_nofault(first_arg, p, sizeof(first_arg));
ksu_strncpy_from_user_nofault(first_arg, p, sizeof(first_arg));
pr_info("/init first arg: %s\n", first_arg);
if (!strcmp(first_arg, "--second-stage")) {
pr_info("/init second_stage executed\n");
@@ -298,7 +299,7 @@ int ksu_handle_execveat_ksud(int *fd, struct filename **filename_ptr,
}
char env[256];
// Reading environment variable strings from user space
if (strncpy_from_user_nofault(env, p, sizeof(env)) < 0)
if (ksu_strncpy_from_user_nofault(env, p, sizeof(env)) < 0)
continue;
// Parsing environment variable names and values
char *env_name = env;
@@ -543,7 +544,7 @@ static int sys_execve_handler_pre(struct kprobe *p, struct pt_regs *regs)
return 0;
memset(path, 0, sizeof(path));
strncpy_from_user_nofault(path, *filename_user, 32);
ksu_strncpy_from_user_nofault(path, *filename_user, 32);
filename_in.name = path;
filename_p = &filename_in;

View File

@@ -52,6 +52,7 @@
#include "setuid_hook.h"
#include "feature.h"
#include "klog.h" // IWYU pragma: keep
#include "kernel_compat.h"
#include "ksu.h"
#include "manager.h"
#include "selinux/selinux.h"
@@ -147,7 +148,7 @@ int ksu_handle_setresuid(uid_t ruid, uid_t euid, uid_t suid)
if (!is_ksu_domain()) {
pr_warn("find suspicious EoP: %d %s, from %d to %d\n",
current->pid, current->comm, old_uid, new_uid);
force_sig(SIGKILL);
ksu_force_sig(SIGKILL);
return 0;
}
}
@@ -156,7 +157,7 @@ int ksu_handle_setresuid(uid_t ruid, uid_t euid, uid_t suid)
if (euid < current_euid().val && !ksu_is_allow_uid_for_current(old_uid)) {
pr_warn("find suspicious EoP: %d %s, from %d to %d\n",
current->pid, current->comm, old_uid, new_uid);
force_sig(SIGKILL);
ksu_force_sig(SIGKILL);
return 0;
}
}
@@ -227,7 +228,7 @@ int ksu_handle_setresuid(uid_t ruid, uid_t euid, uid_t suid){
if (!is_ksu_domain()) {
pr_warn("find suspicious EoP: %d %s, from %d to %d\n",
current->pid, current->comm, old_uid, new_uid);
force_sig(SIGKILL);
ksu_force_sig(SIGKILL);
return 0;
}
}
@@ -236,7 +237,7 @@ int ksu_handle_setresuid(uid_t ruid, uid_t euid, uid_t suid){
if (euid < current_euid().val && !ksu_is_allow_uid_for_current(old_uid)) {
pr_warn("find suspicious EoP: %d %s, from %d to %d\n",
current->pid, current->comm, old_uid, new_uid);
force_sig(SIGKILL);
ksu_force_sig(SIGKILL);
return 0;
}
}

View File

@@ -97,7 +97,7 @@ int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode,
char path[sizeof(su) + 1];
memset(path, 0, sizeof(path));
strncpy_from_user_nofault(path, *filename_user, sizeof(path));
ksu_strncpy_from_user_nofault(path, *filename_user, sizeof(path));
if (unlikely(!memcmp(path, su, sizeof(su)))) {
#if __SULOG_GATE
@@ -144,7 +144,7 @@ int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags)
pr_info("vfs_statx su->sh!\n");
memcpy((void *)filename->name, sh, sizeof(sh));
#else
strncpy_from_user_nofault(path, *filename_user, sizeof(path));
ksu_strncpy_from_user_nofault(path, *filename_user, sizeof(path));
if (unlikely(!memcmp(path, su, sizeof(su)))) {
#if __SULOG_GATE
@@ -174,7 +174,7 @@ int ksu_handle_execve_sucompat(const char __user **filename_user,
return 0;
memset(path, 0, sizeof(path));
strncpy_from_user_nofault(path, *filename_user, sizeof(path));
ksu_strncpy_from_user_nofault(path, *filename_user, sizeof(path));
if (likely(memcmp(path, su, sizeof(su))))
return 0;
@@ -260,7 +260,7 @@ int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode,
return 0;
}
strncpy_from_user_nofault(path, *filename_user, sizeof(path));
ksu_strncpy_from_user_nofault(path, *filename_user, sizeof(path));
if (unlikely(!memcmp(path, su_path, sizeof(su_path)))) {
#if __SULOG_GATE
@@ -316,7 +316,7 @@ int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags)
pr_info("ksu_handle_stat: su->sh!\n");
memcpy((void *)filename->name, sh_path, sizeof(sh_path));
#else
strncpy_from_user_nofault(path, *filename_user, sizeof(path));
ksu_strncpy_from_user_nofault(path, *filename_user, sizeof(path));
if (unlikely(!memcmp(path, su_path, sizeof(su_path)))) {
#if __SULOG_GATE

View File

@@ -19,6 +19,7 @@
#include "feature.h"
#include "klog.h" // IWYU pragma: keep
#include "ksud.h"
#include "kernel_compat.h"
#include "manager.h"
#include "sulog.h"
#include "selinux/selinux.h"
@@ -812,10 +813,10 @@ static void ksu_install_fd_tw_func(struct callback_head *cb)
if (copy_to_user(tw->outp, &fd, sizeof(fd))) {
pr_err("install ksu fd reply err\n");
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)
close_fd(fd);
#else
ksys_close(fd);
__close_fd(current->files, fd);
#endif
}

View File

@@ -235,7 +235,9 @@ static inline bool check_syscall_fastpath(int nr)
case __NR_execve:
case __NR_setresuid:
case __NR_clone:
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0)
case __NR_clone3:
#endif
return true;
default:
return false;
@@ -251,7 +253,7 @@ int ksu_handle_init_mark_tracker(const char __user **filename_user)
return 0;
memset(path, 0, sizeof(path));
strncpy_from_user_nofault(path, *filename_user, sizeof(path));
ksu_strncpy_from_user_nofault(path, *filename_user, sizeof(path));
if (likely(strstr(path, "/app_process") == NULL && strstr(path, "/adbd") == NULL && strstr(path, "/ksud") == NULL)) {
pr_info("hook_manager: unmark %d exec %s", current->pid, path);