diff --git a/kernel/Makefile b/kernel/Makefile index d3d4d1c9..0d2909b9 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -12,6 +12,7 @@ kernelsu-objs += embed_ksud.o kernelsu-objs += kernel_compat.o kernelsu-objs += throne_comm.o kernelsu-objs += sulog.o +kernelsu-objs += ksu_netlink.o ifeq ($(CONFIG_KSU_MANUAL_SU), y) ccflags-y += -DCONFIG_KSU_MANUAL_SU @@ -199,7 +200,7 @@ endif $(info -- Supported Unofficial Manager: 5ec1cff (GKI) rsuntk (Non-GKI) ShirkNeko udochina (GKI and non-GKI and KPM)) ccflags-y += -Wno-implicit-function-declaration -Wno-strict-prototypes -Wno-int-conversion -Wno-gcc-compat -ccflags-y += -Wno-declaration-after-statement -Wno-unused-function +ccflags-y += -Wno-declaration-after-statement -Wno-unused-function -Wno-unused-variable ## For susfs stuff ## ifeq ($(shell test -e $(srctree)/fs/susfs.c; echo $$?),0) diff --git a/kernel/core_hook.c b/kernel/core_hook.c index a5a938aa..e02f573b 100644 --- a/kernel/core_hook.c +++ b/kernel/core_hook.c @@ -61,13 +61,6 @@ #include "supercalls.h" #include "sulog.h" -#ifdef CONFIG_KSU_MANUAL_SU -#include "manual_su.h" -#endif - -#ifdef CONFIG_KPM -#include "kpm/kpm.h" -#endif #ifdef CONFIG_KSU_SUSFS bool susfs_is_boot_completed_triggered = false; @@ -516,9 +509,6 @@ static void sulog_prctl_cmd(uid_t uid, unsigned long cmd) const char *name = NULL; switch (cmd) { -#ifdef CONFIG_KSU_MANUAL_SU - case CMD_MANUAL_SU_REQUEST: name = "prctl_manual_su_request"; break; -#endif #ifdef CONFIG_KSU_SUSFS case CMD_SUSFS_ADD_SUS_PATH: name = "prctl_susfs_add_sus_path"; break; @@ -559,21 +549,11 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5) { - bool is_manual_su_cmd = false; -#ifdef CONFIG_KSU_MANUAL_SU - is_manual_su_cmd = (arg2 == CMD_MANUAL_SU_REQUEST); -#endif #ifdef CONFIG_KSU_SUSFS - bool saved_umount_flag = false; -#ifdef CONFIG_KSU_MANUAL_SU - if (is_manual_su_cmd || is_system_uid()) { - saved_umount_flag = test_and_clear_ti_thread_flag(¤t->thread_info, TIF_PROC_UMOUNTED); - } -#endif // - We straight up check if process is supposed to be umounted, return 0 if so // - This is to prevent side channel attack as much as possible - if (likely(!saved_umount_flag && susfs_is_current_proc_umounted())) + if (likely(susfs_is_current_proc_umounted())) return 0; #endif @@ -604,18 +584,6 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3, pr_info("option: 0x%x, cmd: %ld\n", option, arg2); #endif - #ifdef CONFIG_KPM - if(sukisu_is_kpm_control_code(arg2)) { - int res; - - pr_info("KPM: calling before arg2=%d\n", (int) arg2); - - res = sukisu_handle_kpm(arg2, arg3, arg4, arg5); - - return 0; - } -#endif - #ifdef CONFIG_KSU_MANUAL_SU if (arg2 == CMD_MANUAL_SU_REQUEST) { struct manual_su_request request; @@ -858,11 +826,6 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3, } #endif //#ifdef CONFIG_KSU_SUSFS -#if defined(CONFIG_KSU_SUSFS) && defined(CONFIG_KSU_MANUAL_SU) - if (unlikely(saved_umount_flag)) - set_ti_thread_flag(¤t->thread_info, TIF_PROC_UMOUNTED); -#endif - return 0; } @@ -1654,6 +1617,7 @@ void __init ksu_core_init(void) if (ksu_register_feature_handler(&kernel_umount_handler)) { pr_err("Failed to register umount feature handler\n"); } + ksu_netlink_init(); } void ksu_core_exit(void) @@ -1669,4 +1633,5 @@ void ksu_core_exit(void) ksu_kprobe_exit(); #endif ksu_unregister_feature_handler(KSU_FEATURE_KERNEL_UMOUNT); + ksu_netlink_exit(); } diff --git a/kernel/ksu.h b/kernel/ksu.h index ca9357d4..f3693e1a 100644 --- a/kernel/ksu.h +++ b/kernel/ksu.h @@ -9,10 +9,6 @@ extern bool ksu_uid_scanner_enabled; -#ifdef CONFIG_KSU_MANUAL_SU -#define CMD_MANUAL_SU_REQUEST 50 -#endif - #define EVENT_POST_FS_DATA 1 #define EVENT_BOOT_COMPLETED 2 #define EVENT_MODULE_MOUNTED 3 diff --git a/kernel/ksu_netlink.c b/kernel/ksu_netlink.c new file mode 100644 index 00000000..230416bf --- /dev/null +++ b/kernel/ksu_netlink.c @@ -0,0 +1,119 @@ +#include +#include +#include +#include +#include +#include +#include "ksu_netlink.h" +#include "manual_su.h" +#include "ksu.h" + +static struct sock *ksu_nl_sock = NULL; + +extern int ksu_handle_manual_su_request(int option, struct manual_su_request *request); + +static void ksu_netlink_recv_msg(struct sk_buff *skb) +{ + struct nlmsghdr *nlh; + struct ksu_netlink_msg *msg; + struct ksu_netlink_msg reply; + struct sk_buff *skb_out; + int msg_size; + int res; + u32 pid; + + if (!skb) { + pr_err("ksu_netlink: received NULL skb\n"); + return; + } + + nlh = (struct nlmsghdr *)skb->data; + pid = nlh->nlmsg_pid; + + if (!nlh || nlh->nlmsg_len < NLMSG_HDRLEN + sizeof(struct ksu_netlink_msg)) { + pr_err("ksu_netlink: invalid message size\n"); + return; + } + + msg = (struct ksu_netlink_msg *)nlmsg_data(nlh); + + if (msg->cmd != KSU_NETLINK_CMD_MANUAL_SU) { + pr_warn("ksu_netlink: unknown command %d\n", msg->cmd); + return; + } + + pr_info("ksu_netlink: received manual_su request, option=%d, uid=%d, pid=%d\n", + msg->option, msg->target_uid, msg->target_pid); + + memset(&reply, 0, sizeof(reply)); + reply.cmd = msg->cmd; + reply.option = msg->option; + reply.target_uid = msg->target_uid; + reply.target_pid = msg->target_pid; + + struct manual_su_request request = { + .target_uid = msg->target_uid, + .target_pid = msg->target_pid + }; + + if (msg->option == MANUAL_SU_OP_GENERATE_TOKEN || + msg->option == MANUAL_SU_OP_ESCALATE) { + memcpy(request.token_buffer, msg->token_buffer, KSU_TOKEN_LENGTH + 1); + } + + res = ksu_handle_manual_su_request(msg->option, &request); + + reply.result = res; + if (msg->option == MANUAL_SU_OP_GENERATE_TOKEN && res == 0) { + memcpy(reply.token_buffer, request.token_buffer, KSU_TOKEN_LENGTH + 1); + } + + msg_size = sizeof(struct ksu_netlink_msg); + skb_out = nlmsg_new(msg_size, GFP_KERNEL); + if (!skb_out) { + pr_err("ksu_netlink: failed to allocate reply skb\n"); + return; + } + + nlh = nlmsg_put(skb_out, 0, 0, NLMSG_DONE, msg_size, 0); + if (!nlh) { + pr_err("ksu_netlink: nlmsg_put failed\n"); + kfree_skb(skb_out); + return; + } + + NETLINK_CB(skb_out).dst_group = 0; + memcpy(nlmsg_data(nlh), &reply, sizeof(reply)); + + res = nlmsg_unicast(ksu_nl_sock, skb_out, pid); + if (res < 0) { + pr_err("ksu_netlink: failed to send reply: %d\n", res); + } else { + pr_info("ksu_netlink: reply sent successfully\n"); + } +} + +int ksu_netlink_init(void) +{ + struct netlink_kernel_cfg cfg = { + .input = ksu_netlink_recv_msg, + }; + + ksu_nl_sock = netlink_kernel_create(&init_net, KSU_NETLINK_PROTOCOL, &cfg); + if (!ksu_nl_sock) { + pr_err("ksu_netlink: failed to create netlink socket\n"); + return -ENOMEM; + } + + pr_info("ksu_netlink: initialized with protocol %d\n", KSU_NETLINK_PROTOCOL); + return 0; +} + +void ksu_netlink_exit(void) +{ + if (ksu_nl_sock) { + netlink_kernel_release(ksu_nl_sock); + ksu_nl_sock = NULL; + pr_info("ksu_netlink: released\n"); + } +} diff --git a/kernel/ksu_netlink.h b/kernel/ksu_netlink.h new file mode 100644 index 00000000..bbfa2c3f --- /dev/null +++ b/kernel/ksu_netlink.h @@ -0,0 +1,23 @@ +#ifndef __KSU_NETLINK_H +#define __KSU_NETLINK_H + +#include +#include +#include + +#define KSU_NETLINK_PROTOCOL 2 +#define KSU_NETLINK_CMD_MANUAL_SU 50 + +struct ksu_netlink_msg { + int cmd; + int option; + uid_t target_uid; + pid_t target_pid; + char token_buffer[33]; + int result; +}; + +int ksu_netlink_init(void); +void ksu_netlink_exit(void); + +#endif diff --git a/kernel/throne_tracker.c b/kernel/throne_tracker.c index 47e2c371..ca491309 100644 --- a/kernel/throne_tracker.c +++ b/kernel/throne_tracker.c @@ -430,11 +430,11 @@ void track_throne(void) { struct list_head uid_list; struct uid_data *np, *n; - __maybe_unused struct file *fp; - __maybe_unused char chr = 0; - __maybe_unused loff_t pos = 0; - __maybe_unused loff_t line_start = 0; - __maybe_unused char buf[KSU_MAX_PACKAGE_NAME]; + struct file *fp; + char chr = 0; + loff_t pos = 0; + loff_t line_start = 0; + char buf[KSU_MAX_PACKAGE_NAME]; static bool manager_exist = false; static bool dynamic_manager_exist = false; int current_manager_uid = ksu_get_manager_uid() % 100000;