kernel: Enable macro protection for sulog

- Only enabled on kernel versions greater than 5.10.245
This commit is contained in:
ShirkNeko
2025-10-25 00:45:43 +08:00
parent b9a84a15bc
commit 64ee09fd12
4 changed files with 66 additions and 17 deletions

View File

@@ -149,7 +149,6 @@ static void disable_seccomp()
void escape_to_root(void) void escape_to_root(void)
{ {
struct cred *cred; struct cred *cred;
uid_t original_uid = current_euid().val;
cred = prepare_creds(); cred = prepare_creds();
if (!cred) { if (!cred) {
@@ -159,7 +158,7 @@ void escape_to_root(void)
if (cred->euid.val == 0) { if (cred->euid.val == 0) {
pr_warn("Already root, don't escape!\n"); pr_warn("Already root, don't escape!\n");
ksu_sulog_report_su_grant(original_uid, NULL, "escape_to_root_failed"); ksu_sulog_report_su_grant(current_euid().val, NULL, "escape_to_root_failed");
abort_creds(cred); abort_creds(cred);
return; return;
} }
@@ -203,8 +202,9 @@ void escape_to_root(void)
spin_unlock_irq(&current->sighand->siglock); spin_unlock_irq(&current->sighand->siglock);
setup_selinux(profile->selinux_domain); setup_selinux(profile->selinux_domain);
#if __SULOG_GATE
ksu_sulog_report_su_grant(original_uid, NULL, "escape_to_root"); ksu_sulog_report_su_grant(current_euid().val, NULL, "escape_to_root");
#endif
} }
#ifdef CONFIG_KSU_MANUAL_SU #ifdef CONFIG_KSU_MANUAL_SU
@@ -247,7 +247,9 @@ void escape_to_root_for_cmd_su(uid_t target_uid, pid_t target_pid)
if (!target_task) { if (!target_task) {
rcu_read_unlock(); rcu_read_unlock();
pr_err("cmd_su: target task not found for PID: %d\n", target_pid); pr_err("cmd_su: target task not found for PID: %d\n", target_pid);
#if __SULOG_GATE
ksu_sulog_report_su_grant(target_uid, "cmd_su", "target_not_found"); ksu_sulog_report_su_grant(target_uid, "cmd_su", "target_not_found");
#endif
return; return;
} }
get_task_struct(target_task); get_task_struct(target_task);
@@ -262,7 +264,9 @@ void escape_to_root_for_cmd_su(uid_t target_uid, pid_t target_pid)
newcreds = prepare_kernel_cred(target_task); newcreds = prepare_kernel_cred(target_task);
if (newcreds == NULL) { if (newcreds == NULL) {
pr_err("cmd_su: failed to allocate new cred for PID: %d\n", target_pid); pr_err("cmd_su: failed to allocate new cred for PID: %d\n", target_pid);
#if __SULOG_GATE
ksu_sulog_report_su_grant(target_uid, "cmd_su", "cred_alloc_failed"); ksu_sulog_report_su_grant(target_uid, "cmd_su", "cred_alloc_failed");
#endif
put_task_struct(target_task); put_task_struct(target_task);
return; return;
} }
@@ -312,8 +316,9 @@ void escape_to_root_for_cmd_su(uid_t target_uid, pid_t target_pid)
} }
put_task_struct(target_task); put_task_struct(target_task);
#if __SULOG_GATE
ksu_sulog_report_su_grant(target_uid, "cmd_su", "manual_escalation"); ksu_sulog_report_su_grant(target_uid, "cmd_su", "manual_escalation");
#endif
pr_info("cmd_su: privilege escalation completed for UID: %d, PID: %d\n", target_uid, target_pid); pr_info("cmd_su: privilege escalation completed for UID: %d, PID: %d\n", target_uid, target_pid);
} }
#endif #endif
@@ -417,6 +422,7 @@ static void init_uid_scanner(void)
} }
} }
#if __SULOG_GATE
static void sulog_prctl_cmd(uid_t uid, unsigned long cmd) static void sulog_prctl_cmd(uid_t uid, unsigned long cmd)
{ {
const char *name = NULL; const char *name = NULL;
@@ -455,6 +461,7 @@ static void sulog_prctl_cmd(uid_t uid, unsigned long cmd)
ksu_sulog_report_syscall(uid, NULL, name, NULL); ksu_sulog_report_syscall(uid, NULL, name, NULL);
} }
#endif
int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3, int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
unsigned long arg4, unsigned long arg5) unsigned long arg4, unsigned long arg5)
@@ -495,8 +502,10 @@ skip_check:
// just continue old logic // just continue old logic
bool from_root = !current_uid().val; bool from_root = !current_uid().val;
bool from_manager = is_manager(); bool from_manager = is_manager();
#if __SULOG_GATE
sulog_prctl_cmd(current_uid().val, arg2); sulog_prctl_cmd(current_uid().val, arg2);
#endif
if (!from_root && !from_manager if (!from_root && !from_manager
&& !(is_manual_su_cmd ? is_system_uid(): && !(is_manual_su_cmd ? is_system_uid():
@@ -520,10 +529,13 @@ skip_check:
} }
if (arg2 == CMD_GRANT_ROOT) { if (arg2 == CMD_GRANT_ROOT) {
#if __SULOG_GATE
bool is_allowed = is_allow_su(); bool is_allowed = is_allow_su();
ksu_sulog_report_permission_check(current_uid().val, current->comm, is_allowed); ksu_sulog_report_permission_check(current_uid().val, current->comm, is_allowed);
if (is_allowed) { if (is_allowed) {
#else
if (is_allow_su()) {
#endif
pr_info("allow root for: %d\n", current_uid().val); pr_info("allow root for: %d\n", current_uid().val);
escape_to_root(); escape_to_root();
if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) { if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) {
@@ -627,7 +639,9 @@ skip_check:
post_fs_data_lock = true; post_fs_data_lock = true;
pr_info("post-fs-data triggered\n"); pr_info("post-fs-data triggered\n");
on_post_fs_data(); on_post_fs_data();
#if __SULOG_GATE
ksu_sulog_init(); ksu_sulog_init();
#endif
// Initialize UID scanner if enabled // Initialize UID scanner if enabled
init_uid_scanner(); init_uid_scanner();
// Initializing Dynamic Signatures // Initializing Dynamic Signatures
@@ -863,8 +877,10 @@ skip_check:
// todo: validate the params // todo: validate the params
if (ksu_set_app_profile(&profile, true)) { if (ksu_set_app_profile(&profile, true)) {
#if __SULOG_GATE
ksu_sulog_report_manager_operation("SET_APP_PROFILE", ksu_sulog_report_manager_operation("SET_APP_PROFILE",
current_uid().val, profile.current_uid); current_uid().val, profile.current_uid);
#endif
if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) { if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) {
pr_err("prctl reply error, cmd: %lu\n", arg2); pr_err("prctl reply error, cmd: %lu\n", arg2);
@@ -1046,7 +1062,9 @@ int ksu_handle_setuid(struct cred *new, const struct cred *old)
current->pid); current->pid);
return 0; return 0;
} }
#if __SULOG_GATE
ksu_sulog_report_syscall(new_uid.val, NULL, "setuid", NULL); ksu_sulog_report_syscall(new_uid.val, NULL, "setuid", NULL);
#endif
#ifdef CONFIG_KSU_DEBUG #ifdef CONFIG_KSU_DEBUG
// umount the target mnt // umount the target mnt
pr_info("handle umount for uid: %d, pid: %d\n", new_uid.val, pr_info("handle umount for uid: %d, pid: %d\n", new_uid.val,
@@ -1430,7 +1448,11 @@ void ksu_core_exit(void)
{ {
ksu_uid_exit(); ksu_uid_exit();
ksu_throne_comm_exit(); ksu_throne_comm_exit();
#if __SULOG_GATE
ksu_sulog_exit(); ksu_sulog_exit();
#endif
#ifdef CONFIG_KPROBE #ifdef CONFIG_KPROBE
pr_info("ksu_core_kprobe_exit\n"); pr_info("ksu_core_kprobe_exit\n");
// we dont use this now // we dont use this now

View File

@@ -70,7 +70,9 @@ int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode,
ksu_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 (unlikely(!memcmp(path, su, sizeof(su)))) {
#if __SULOG_GATE
ksu_sulog_report_syscall(current_uid().val, NULL, "faccessat", path); ksu_sulog_report_syscall(current_uid().val, NULL, "faccessat", path);
#endif
pr_info("faccessat su->sh!\n"); pr_info("faccessat su->sh!\n");
*filename_user = sh_user_path(); *filename_user = sh_user_path();
} }
@@ -115,7 +117,9 @@ int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags)
ksu_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 (unlikely(!memcmp(path, su, sizeof(su)))) {
#if __SULOG_GATE
ksu_sulog_report_syscall(current_uid().val, NULL, "newfstatat", path); ksu_sulog_report_syscall(current_uid().val, NULL, "newfstatat", path);
#endif
pr_info("newfstatat su->sh!\n"); pr_info("newfstatat su->sh!\n");
*filename_user = sh_user_path(); *filename_user = sh_user_path();
} }
@@ -136,8 +140,6 @@ int ksu_handle_execveat_sucompat(int *fd, struct filename **filename_ptr,
int *__never_use_flags) int *__never_use_flags)
{ {
struct filename *filename; struct filename *filename;
uid_t current_uid_val = current_uid().val;
bool is_allowed = ksu_is_allow_uid(current_uid_val);
const char sh[] = KSUD_PATH; const char sh[] = KSUD_PATH;
const char su[] = SU_PATH; const char su[] = SU_PATH;
@@ -157,13 +159,21 @@ int ksu_handle_execveat_sucompat(int *fd, struct filename **filename_ptr,
if (likely(memcmp(filename->name, su, sizeof(su)))) if (likely(memcmp(filename->name, su, sizeof(su))))
return 0; return 0;
ksu_sulog_report_syscall(current_uid_val, NULL, "execve", filename->name); #if __SULOG_GATE
ksu_sulog_report_su_attempt(current_uid_val, NULL, filename->name, is_allowed); bool is_allowed = ksu_is_allow_uid(current_uid().val);
ksu_sulog_report_syscall(current_uid().val, NULL, "execve", filename->name);
if (!is_allowed) { if (!is_allowed) {
return 0; return 0;
} }
ksu_sulog_report_su_attempt(current_uid().val, NULL, filename->name, is_allowed);
#else
if (!ksu_is_allow_uid(current_uid().val)) {
return 0;
}
#endif
pr_info("do_execveat_common su found\n"); pr_info("do_execveat_common su found\n");
memcpy((void *)filename->name, sh, sizeof(sh)); memcpy((void *)filename->name, sh, sizeof(sh));
@@ -176,8 +186,6 @@ int ksu_handle_execve_sucompat(int *fd, const char __user **filename_user,
void *__never_use_argv, void *__never_use_envp, void *__never_use_argv, void *__never_use_envp,
int *__never_use_flags) int *__never_use_flags)
{ {
uid_t current_uid_val = current_uid().val;
bool is_allowed = ksu_is_allow_uid(current_uid_val);
const char su[] = SU_PATH; const char su[] = SU_PATH;
char path[sizeof(su) + 1]; char path[sizeof(su) + 1];
@@ -194,13 +202,21 @@ int ksu_handle_execve_sucompat(int *fd, const char __user **filename_user,
if (likely(memcmp(path, su, sizeof(su)))) if (likely(memcmp(path, su, sizeof(su))))
return 0; return 0;
ksu_sulog_report_syscall(current_uid_val, NULL, "execve", path);
ksu_sulog_report_su_attempt(current_uid_val, NULL, path, is_allowed);
#if __SULOG_GATE
bool is_allowed = ksu_is_allow_uid(current_uid().val);
ksu_sulog_report_syscall(current_uid().val, NULL, "execve", path);
if (!is_allowed) if (!is_allowed)
return 0; return 0;
ksu_sulog_report_su_attempt(current_uid().val, NULL, path, is_allowed);
#else
if (!ksu_is_allow_uid(current_uid().val)) {
return 0;
}
#endif
pr_info("sys_execve su found\n"); pr_info("sys_execve su found\n");
*filename_user = ksud_user_path(); *filename_user = ksud_user_path();

View File

@@ -18,6 +18,7 @@
#include "sulog.h" #include "sulog.h"
#include "ksu.h" #include "ksu.h"
#if __SULOG_GATE
struct dedup_entry dedup_tbl[SULOG_COMM_LEN]; struct dedup_entry dedup_tbl[SULOG_COMM_LEN];
DEFINE_SPINLOCK(dedup_lock); DEFINE_SPINLOCK(dedup_lock);
static LIST_HEAD(sulog_queue); static LIST_HEAD(sulog_queue);
@@ -418,4 +419,5 @@ void ksu_sulog_exit(void)
mutex_unlock(&sulog_mutex); mutex_unlock(&sulog_mutex);
pr_info("sulog: cleaned up successfully\n"); pr_info("sulog: cleaned up successfully\n");
} }
#endif // __SULOG_GATE

View File

@@ -2,7 +2,15 @@
#define __KSU_SULOG_H #define __KSU_SULOG_H
#include <linux/types.h> #include <linux/types.h>
#include <linux/version.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 245)
#define __SULOG_GATE 1
#else
#define __SULOG_GATE 0
#endif
#if __SULOG_GATE
extern struct timezone sys_tz; extern struct timezone sys_tz;
#define SULOG_PATH "/data/adb/ksu/log/sulog.log" #define SULOG_PATH "/data/adb/ksu/log/sulog.log"
@@ -49,5 +57,6 @@ void ksu_sulog_report_syscall(uid_t uid, const char *comm, const char *syscall,
int ksu_sulog_init(void); int ksu_sulog_init(void);
void ksu_sulog_exit(void); void ksu_sulog_exit(void);
#endif // __SULOG_GATE
#endif /* __KSU_SULOG_H */ #endif /* __KSU_SULOG_H */