diff --git a/kernel/file_wrapper.c b/kernel/file_wrapper.c index 08c244deb29e..0f0fb8c6b06d 100644 --- a/kernel/file_wrapper.c +++ b/kernel/file_wrapper.c @@ -260,30 +260,19 @@ void ksu_wrapper_splice_eof(struct file *fp) #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 12, 0) -static int ksu_wrapper_setlease(struct file *fp, int arg1, - struct file_lease **fl, void **p) -{ - struct ksu_file_wrapper *data = fp->private_data; - struct file *orig = data->orig; - if (orig->f_op->setlease) { - return orig->f_op->setlease(orig, arg1, fl, p); - } - return -EINVAL; -} -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(6, 6, 0) -static int ksu_wrapper_setlease(struct file *fp, int arg1, - struct file_lock **fl, void **p) -{ - struct ksu_file_wrapper *data = fp->private_data; - struct file *orig = data->orig; - if (orig->f_op->setlease) { - return orig->f_op->setlease(orig, arg1, fl, p); - } - return -EINVAL; -} +#define __ksu_sl_file_lock file_lease #else -static int ksu_wrapper_setlease(struct file *fp, long arg1, - struct file_lock **fl, void **p) +#define __ksu_sl_file_lock file_lock +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 6, 0) +#define __ksu_sl_arg1 int +#else +#define __ksu_sl_arg1 long +#endif + +static int ksu_wrapper_setlease(struct file *fp, __ksu_sl_arg1 arg1, + struct __ksu_sl_file_lock **fl, void **p) { struct ksu_file_wrapper *data = fp->private_data; struct file *orig = data->orig; @@ -292,7 +281,6 @@ static int ksu_wrapper_setlease(struct file *fp, long arg1, } return -EINVAL; } -#endif static long ksu_wrapper_fallocate(struct file *fp, int mode, loff_t offset, loff_t len) diff --git a/kernel/ksud.c b/kernel/ksud.c index 1c824f55201b..bf39f3055861 100644 --- a/kernel/ksud.c +++ b/kernel/ksud.c @@ -63,6 +63,28 @@ static struct work_struct stop_init_rc_hook_work; static struct work_struct stop_execve_hook_work; static struct work_struct stop_input_hook_work; +long __strncpy_from_user_nofault(char *dst, const void __user *unsafe_addr, + long count) +{ + long ret; + + if (unlikely(count <= 0)) + return 0; + + pagefault_disable(); + ret = strncpy_from_user(dst, unsafe_addr, count); + pagefault_enable(); + + if (ret >= count) { + ret = count; + dst[ret - 1] = '\0'; + } else if (ret > 0) { + ret++; + } + + return ret; +} + void on_post_fs_data(void) { static bool done = false; @@ -205,7 +227,7 @@ static bool check_argv(struct user_arg_ptr argv, int index, if (!p || IS_ERR(p)) goto fail; - if (strncpy_from_user_nofault(buf, p, buf_len) <= 0) + if (__strncpy_from_user_nofault(buf, p, buf_len) <= 0) goto fail; buf[buf_len - 1] = '\0'; @@ -515,9 +537,9 @@ static int sys_execve_handler_pre(struct kprobe *p, struct pt_regs *regs) fn = (const char __user *)addr; memset(path, 0, sizeof(path)); - ret = strncpy_from_user_nofault(path, fn, 32); + ret = __strncpy_from_user_nofault(path, fn, 32); if (ret < 0 && try_set_access_flag(addr)) { - ret = strncpy_from_user_nofault(path, fn, 32); + ret = __strncpy_from_user_nofault(path, fn, 32); } if (ret < 0) { pr_err("Access filename failed for execve_handler_pre\n"); diff --git a/kernel/ksud.h b/kernel/ksud.h index 85720d3cd913..e49f075d32e0 100644 --- a/kernel/ksud.h +++ b/kernel/ksud.h @@ -16,6 +16,8 @@ bool ksu_is_safe_mode(void); int nuke_ext4_sysfs(const char *mnt); +long __strncpy_from_user_nofault(char *d, const void __user *a, long c); + extern u32 ksu_file_sid; extern bool ksu_module_mounted; extern bool ksu_boot_completed; diff --git a/kernel/pkg_observer.c b/kernel/pkg_observer.c index 96ebf6121f75..0c5e23923e7d 100644 --- a/kernel/pkg_observer.c +++ b/kernel/pkg_observer.c @@ -106,7 +106,7 @@ int ksu_observer_init(void) { int ret = 0; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 154) g = fsnotify_alloc_group(&ksu_ops, 0); #else g = fsnotify_alloc_group(&ksu_ops); diff --git a/kernel/selinux/selinux.c b/kernel/selinux/selinux.c index b477d59ce767..5b42cf3b8596 100644 --- a/kernel/selinux/selinux.c +++ b/kernel/selinux/selinux.c @@ -6,6 +6,10 @@ #include "../klog.h" // IWYU pragma: keep #include "../ksu.h" +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 18, 0) +#define cred_security_struct task_security_struct +#endif + /* * Cached SID values for frequently checked contexts. * These are resolved once at init and used for fast u32 comparison @@ -27,11 +31,7 @@ static int transive_to_domain(const char *domain, struct cred *cred) { u32 sid; int error; -#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 18, 0) - struct task_security_struct *tsec; -#else struct cred_security_struct *tsec; -#endif tsec = selinux_cred(cred); if (!tsec) { pr_err("tsec == NULL!\n"); @@ -163,11 +163,7 @@ static bool is_sid_match(const struct cred *cred, u32 cached_sid, if (!cred) { return false; } -#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 18, 0) - const struct task_security_struct *tsec = selinux_cred(cred); -#else const struct cred_security_struct *tsec = selinux_cred(cred); -#endif if (!tsec) { return false; } diff --git a/kernel/sucompat.c b/kernel/sucompat.c index 04d8d3ca8900..85d98e25272f 100644 --- a/kernel/sucompat.c +++ b/kernel/sucompat.c @@ -80,7 +80,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)); + __strncpy_from_user_nofault(path, *filename_user, sizeof(path)); if (unlikely(!memcmp(path, su, sizeof(su)))) { pr_info("faccessat su->sh!\n"); @@ -105,7 +105,7 @@ int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags) char path[sizeof(su) + 1]; memset(path, 0, sizeof(path)); - strncpy_from_user_nofault(path, *filename_user, sizeof(path)); + __strncpy_from_user_nofault(path, *filename_user, sizeof(path)); if (unlikely(!memcmp(path, su, sizeof(su)))) { pr_info("newfstatat su->sh!\n"); @@ -134,10 +134,10 @@ int ksu_handle_execve_sucompat(const char __user **filename_user, addr = untagged_addr((unsigned long)*filename_user); fn = (const char __user *)addr; memset(path, 0, sizeof(path)); - ret = strncpy_from_user_nofault(path, fn, sizeof(path)); + ret = __strncpy_from_user_nofault(path, fn, sizeof(path)); if (ret < 0 && try_set_access_flag(addr)) { - ret = strncpy_from_user_nofault(path, fn, sizeof(path)); + ret = __strncpy_from_user_nofault(path, fn, sizeof(path)); } if (ret < 0 && preempt_count()) { diff --git a/kernel/syscall_hook_manager.c b/kernel/syscall_hook_manager.c index 55f95d76c604..c7fe203a70d7 100644 --- a/kernel/syscall_hook_manager.c +++ b/kernel/syscall_hook_manager.c @@ -113,7 +113,7 @@ int ksu_get_task_mark(pid_t pid) int marked = -ESRCH; rcu_read_lock(); - task = find_task_by_vpid(pid); + task = pid_task(find_vpid(pid), PIDTYPE_PID); if (task) { get_task_struct(task); rcu_read_unlock(); @@ -138,7 +138,7 @@ int ksu_set_task_mark(pid_t pid, bool mark) int ret = -ESRCH; rcu_read_lock(); - task = find_task_by_vpid(pid); + task = pid_task(find_vpid(pid), PIDTYPE_PID); if (task) { get_task_struct(task); rcu_read_unlock(); @@ -260,9 +260,9 @@ int ksu_handle_init_mark_tracker(const char __user **filename_user) fn = (const char __user *)addr; memset(path, 0, sizeof(path)); - ret = strncpy_from_user_nofault(path, fn, sizeof(path)); + ret = __strncpy_from_user_nofault(path, fn, sizeof(path)); if (ret < 0 && try_set_access_flag(addr)) { - ret = strncpy_from_user_nofault(path, fn, sizeof(path)); + ret = __strncpy_from_user_nofault(path, fn, sizeof(path)); pr_info("ksu_handle_init_mark_tracker: %ld\n", ret); }