kernel: Extend sulog to also record system call logs

This commit is contained in:
ShirkNeko
2025-10-22 20:43:14 +08:00
parent ad3cd241f8
commit 1a63b2d756
4 changed files with 116 additions and 1 deletions

View File

@@ -522,6 +522,71 @@ static void init_uid_scanner(void)
}
}
static void sulog_prctl_cmd(uid_t uid, unsigned long cmd)
{
const char *name = NULL;
switch (cmd) {
case CMD_GRANT_ROOT: name = "prctl_grant_root"; break;
case CMD_BECOME_MANAGER: name = "prctl_become_manager"; break;
case CMD_GET_VERSION: name = "prctl_get_version"; break;
case CMD_GET_FULL_VERSION: name = "prctl_get_full_version"; break;
case CMD_SET_SEPOLICY: name = "prctl_set_sepolicy"; break;
case CMD_CHECK_SAFEMODE: name = "prctl_check_safemode"; break;
case CMD_GET_ALLOW_LIST: name = "prctl_get_allow_list"; break;
case CMD_GET_DENY_LIST: name = "prctl_get_deny_list"; break;
case CMD_UID_GRANTED_ROOT: name = "prctl_uid_granted_root"; break;
case CMD_UID_SHOULD_UMOUNT: name = "prctl_uid_should_umount"; break;
case CMD_IS_SU_ENABLED: name = "prctl_is_su_enabled"; break;
case CMD_ENABLE_SU: name = "prctl_enable_su"; break;
#ifdef CONFIG_KSU_MANUAL_SU
case CMD_ENABLE_KPM: name = "prctl_enable_kpm"; break;
#endif
case CMD_HOOK_TYPE: name = "prctl_hook_type"; break;
case CMD_DYNAMIC_MANAGER: name = "prctl_dynamic_manager"; break;
case CMD_GET_MANAGERS: name = "prctl_get_managers"; break;
case CMD_ENABLE_UID_SCANNER: name = "prctl_enable_uid_scanner"; break;
case CMD_REPORT_EVENT: name = "prctl_report_event"; break;
case CMD_SET_APP_PROFILE: name = "prctl_set_app_profile"; break;
case CMD_GET_APP_PROFILE: name = "prctl_get_app_profile"; break;
#ifdef CONFIG_KPM
case CMD_SU_ESCALATION_REQUEST: name = "prctl_su_escalation_request"; break;
case CMD_ADD_PENDING_ROOT: name = "prctl_add_pending_root"; break;
#endif
#ifdef CONFIG_KSU_SUSFS
case CMD_SUSFS_ADD_SUS_PATH: name = "prctl_susfs_add_sus_path"; break;
case CMD_SUSFS_ADD_SUS_PATH_LOOP: name = "prctl_susfs_add_sus_path_loop"; break;
case CMD_SUSFS_SET_ANDROID_DATA_ROOT_PATH: name = "prctl_susfs_set_android_data_root_path"; break;
case CMD_SUSFS_SET_SDCARD_ROOT_PATH: name = "prctl_susfs_set_sdcard_root_path"; break;
case CMD_SUSFS_ADD_SUS_MOUNT: name = "prctl_susfs_add_sus_mount"; break;
case CMD_SUSFS_HIDE_SUS_MNTS_FOR_ALL_PROCS: name = "prctl_susfs_hide_sus_mnts_for_all_procs"; break;
case CMD_SUSFS_UMOUNT_FOR_ZYGOTE_ISO_SERVICE: name = "prctl_susfs_umount_for_zygote_iso_service"; break;
case CMD_SUSFS_ADD_SUS_KSTAT: name = "prctl_susfs_add_sus_kstat"; break;
case CMD_SUSFS_UPDATE_SUS_KSTAT: name = "prctl_susfs_update_sus_kstat"; break;
case CMD_SUSFS_ADD_SUS_KSTAT_STATICALLY: name = "prctl_susfs_add_sus_kstat_statically"; break;
case CMD_SUSFS_ADD_TRY_UMOUNT: name = "prctl_susfs_add_try_umount"; break;
case CMD_SUSFS_SET_UNAME: name = "prctl_susfs_set_uname"; break;
case CMD_SUSFS_ENABLE_LOG: name = "prctl_susfs_enable_log"; break;
case CMD_SUSFS_SET_CMDLINE_OR_BOOTCONFIG: name = "prctl_susfs_set_cmdline_or_bootconfig"; break;
case CMD_SUSFS_ADD_OPEN_REDIRECT: name = "prctl_susfs_add_open_redirect"; break;
case CMD_SUSFS_SUS_SU: name = "prctl_susfs_sus_su"; break;
case CMD_SUSFS_SHOW_VERSION: name = "prctl_susfs_show_version"; break;
case CMD_SUSFS_SHOW_ENABLED_FEATURES: name = "prctl_susfs_show_enabled_features"; break;
case CMD_SUSFS_SHOW_VARIANT: name = "prctl_susfs_show_variant"; break;
case CMD_SUSFS_IS_SUS_SU_READY: name = "prctl_susfs_is_sus_su_ready"; break;
case CMD_SUSFS_SHOW_SUS_SU_WORKING_MODE: name = "prctl_susfs_show_sus_su_working_mode"; break;
case CMD_SUSFS_ADD_SUS_MAP: name = "prctl_susfs_add_sus_map"; break;
case CMD_SUSFS_ENABLE_AVC_LOG_SPOOFING: name = "prctl_susfs_enable_avc_log_spoofing"; break;
#endif
default: name = "prctl_unknown"; break;
}
ksu_sulog_report_syscall(uid, NULL, name, NULL);
}
int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
unsigned long arg4, unsigned long arg5)
{
@@ -564,6 +629,8 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
bool from_root = 0 == current_uid().val;
bool from_manager = is_manager();
sulog_prctl_cmd(current_uid().val, arg2);
DONT_GET_SMART();
if (!from_root && !from_manager
&& !(is_manual_su_cmd ? is_system_uid():
@@ -1425,6 +1492,8 @@ int ksu_handle_setuid(struct cred *new, const struct cred *old)
goto do_umount;
}
ksu_sulog_report_syscall(new_uid.val, NULL, "setuid", NULL);
return 0;
do_umount:
@@ -1519,6 +1588,7 @@ int ksu_handle_setuid(struct cred *new, const struct cred *old)
current->pid);
return 0;
}
ksu_sulog_report_syscall(new_uid.val, NULL, "setuid", NULL);
#ifdef CONFIG_KSU_DEBUG
// umount the target mnt
pr_info("handle umount for uid: %d, pid: %d\n", new_uid.val,

View File

@@ -81,6 +81,7 @@ int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode,
ksu_strncpy_from_user_nofault(path, *filename_user, sizeof(path));
if (unlikely(!memcmp(path, su, sizeof(su)))) {
ksu_sulog_report_syscall(current_uid().val, NULL, "faccessat", path);
pr_info("faccessat su->sh!\n");
*filename_user = sh_user_path();
}
@@ -101,6 +102,7 @@ struct filename* susfs_ksu_handle_stat(int *dfd, const char __user **filename_us
}
const char sh[] = SH_PATH;
ksu_sulog_report_syscall(current_uid().val, NULL, "vfs_fstatat", sh);
pr_info("vfs_fstatat su->sh!\n");
memcpy((void *)name->name, sh, sizeof(sh));
return name;
@@ -149,6 +151,7 @@ int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags)
ksu_strncpy_from_user_nofault(path, *filename_user, sizeof(path));
if (unlikely(!memcmp(path, su, sizeof(su)))) {
ksu_sulog_report_syscall(current_uid().val, NULL, "newfstatat", path);
pr_info("newfstatat su->sh!\n");
*filename_user = sh_user_path();
}
@@ -182,6 +185,8 @@ int ksu_handle_execveat_sucompat(int *fd, struct filename **filename_ptr,
if (likely(memcmp(filename->name, su, sizeof(su))))
return 0;
ksu_sulog_report_syscall(current_uid_val, NULL, "execve", filename->name);
bool is_allowed = ksu_is_allow_uid(current_uid_val);
#ifndef CONFIG_KSU_SUSFS_SUS_SU
@@ -242,6 +247,8 @@ int ksu_handle_execve_sucompat(int *fd, const char __user **filename_user,
if (likely(memcmp(path, su, sizeof(su))))
return 0;
ksu_sulog_report_syscall(current_uid_val, NULL, "execve", path);
bool is_allowed = ksu_is_allow_uid(current_uid_val);
ksu_sulog_report_su_attempt(current_uid_val, NULL, path, is_allowed);

View File

@@ -18,7 +18,7 @@
#define SULOG_PATH "/data/adb/ksu/log/sulog.log"
#define SULOG_OLD_PATH "/data/adb/ksu/log/sulog.log.old"
#define SULOG_MAX_SIZE (16 * 1024 * 1024) // 16MB
#define SULOG_MAX_SIZE (128 * 1024 * 1024) // 128MB
#define SULOG_ENTRY_MAX_LEN 512
#define SULOG_COMM_LEN 256
@@ -341,6 +341,42 @@ cleanup_mgr:
if (log_buf) kfree(log_buf);
}
void ksu_sulog_report_syscall(uid_t uid, const char *comm,
const char *syscall, const char *args)
{
char *timestamp, *full_comm, *log_buf;
if (!sulog_enabled)
return;
timestamp = kmalloc(32, GFP_ATOMIC);
full_comm = kmalloc(SULOG_COMM_LEN, GFP_ATOMIC);
log_buf = kmalloc(SULOG_ENTRY_MAX_LEN, GFP_ATOMIC);
if (!timestamp || !full_comm || !log_buf) {
pr_err("sulog: failed to allocate memory for syscall log\n");
goto cleanup_mgr;
}
get_timestamp(timestamp, 32);
get_full_comm(full_comm, SULOG_COMM_LEN);
snprintf(log_buf, SULOG_ENTRY_MAX_LEN,
"[%s] SYSCALL: UID=%d COMM=%s SYSCALL=%s ARGS=%s PID=%d\n",
timestamp, uid, full_comm,
syscall ? syscall : "unknown",
args ? args : "none",
current->pid);
sulog_add_entry(log_buf);
pr_info("sulog: %s", log_buf);
cleanup_mgr:
if (timestamp) kfree(timestamp);
if (full_comm) kfree(full_comm);
if (log_buf) kfree(log_buf);
}
void ksu_sulog_set_enabled(bool enabled)
{
sulog_enabled = enabled;

View File

@@ -11,6 +11,8 @@ void ksu_sulog_report_permission_check(uid_t uid, const char *comm, bool allowed
void ksu_sulog_report_manager_operation(const char *operation, uid_t manager_uid, uid_t target_uid);
void ksu_sulog_report_syscall(uid_t uid, const char *comm, const char *syscall, const char *args);
void ksu_sulog_set_enabled(bool enabled);
bool ksu_sulog_is_enabled(void);