kernel: Remove prctl; use netlink communication to control manual_su
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
119
kernel/ksu_netlink.c
Normal file
119
kernel/ksu_netlink.c
Normal file
@@ -0,0 +1,119 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/netlink.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <net/sock.h>
|
||||
#include <linux/slab.h>
|
||||
#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");
|
||||
}
|
||||
}
|
||||
23
kernel/ksu_netlink.h
Normal file
23
kernel/ksu_netlink.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef __KSU_NETLINK_H
|
||||
#define __KSU_NETLINK_H
|
||||
|
||||
#include <linux/netlink.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <net/sock.h>
|
||||
|
||||
#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
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user