kernel: Restore the sequence of sulog logs
This commit is contained in:
@@ -450,32 +450,6 @@ static void sulog_prctl_cmd(uid_t uid, unsigned long cmd)
|
|||||||
case CMD_ADD_PENDING_ROOT: name = "prctl_add_pending_root"; break;
|
case CMD_ADD_PENDING_ROOT: name = "prctl_add_pending_root"; break;
|
||||||
#endif
|
#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;
|
default: name = "prctl_unknown"; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
107
kernel/sulog.c
107
kernel/sulog.c
@@ -18,55 +18,14 @@
|
|||||||
#include "sulog.h"
|
#include "sulog.h"
|
||||||
#include "ksu.h"
|
#include "ksu.h"
|
||||||
|
|
||||||
#define SULOG_PATH "/data/adb/ksu/log/sulog.log"
|
struct dedup_entry dedup_tbl[SULOG_COMM_LEN];
|
||||||
#define SULOG_OLD_PATH "/data/adb/ksu/log/sulog.log.old"
|
DEFINE_SPINLOCK(dedup_lock);
|
||||||
#define SULOG_MAX_SIZE (128 * 1024 * 1024) // 128MB
|
|
||||||
#define SULOG_ENTRY_MAX_LEN 512
|
|
||||||
#define SULOG_COMM_LEN 256
|
|
||||||
#define DEDUP_ENTRIES 256
|
|
||||||
#define DEDUP_SECS 60
|
|
||||||
|
|
||||||
struct dedup_key {
|
|
||||||
u32 crc;
|
|
||||||
uid_t uid;
|
|
||||||
u8 type;
|
|
||||||
u8 _pad[1];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct dedup_entry {
|
|
||||||
struct dedup_key key;
|
|
||||||
u64 ts_ns;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct dedup_entry dedup_tbl[DEDUP_ENTRIES];
|
|
||||||
static DEFINE_SPINLOCK(dedup_lock);
|
|
||||||
|
|
||||||
enum {
|
|
||||||
DEDUP_SU_GRANT = 0,
|
|
||||||
DEDUP_SU_ATTEMPT,
|
|
||||||
DEDUP_PERM_CHECK,
|
|
||||||
DEDUP_MANAGER_OP,
|
|
||||||
DEDUP_SYSCALL,
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline u32 dedup_calc_hash(const char *content, size_t len)
|
|
||||||
{
|
|
||||||
return crc32(0, content, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct sulog_entry {
|
|
||||||
struct list_head list;
|
|
||||||
char content[SULOG_ENTRY_MAX_LEN];
|
|
||||||
};
|
|
||||||
|
|
||||||
static LIST_HEAD(sulog_queue);
|
static LIST_HEAD(sulog_queue);
|
||||||
static DEFINE_MUTEX(sulog_mutex);
|
static DEFINE_MUTEX(sulog_mutex);
|
||||||
static struct workqueue_struct *sulog_workqueue;
|
static struct workqueue_struct *sulog_workqueue;
|
||||||
static struct work_struct sulog_work;
|
static struct work_struct sulog_work;
|
||||||
static bool sulog_enabled = true;
|
static bool sulog_enabled = true;
|
||||||
|
|
||||||
extern struct timezone sys_tz;
|
|
||||||
|
|
||||||
static void get_timestamp(char *buf, size_t len)
|
static void get_timestamp(char *buf, size_t len)
|
||||||
{
|
{
|
||||||
struct timespec64 ts;
|
struct timespec64 ts;
|
||||||
@@ -137,7 +96,7 @@ static bool dedup_should_print(uid_t uid, u8 type,
|
|||||||
u64 now = ktime_get_ns();
|
u64 now = ktime_get_ns();
|
||||||
u64 delta_ns = DEDUP_SECS * NSEC_PER_SEC;
|
u64 delta_ns = DEDUP_SECS * NSEC_PER_SEC;
|
||||||
|
|
||||||
u32 idx = key.crc & (DEDUP_ENTRIES - 1);
|
u32 idx = key.crc & (SULOG_COMM_LEN - 1);
|
||||||
spin_lock(&dedup_lock);
|
spin_lock(&dedup_lock);
|
||||||
|
|
||||||
struct dedup_entry *e = &dedup_tbl[idx];
|
struct dedup_entry *e = &dedup_tbl[idx];
|
||||||
@@ -265,7 +224,7 @@ void ksu_sulog_report_su_grant(uid_t uid, const char *comm, const char *method)
|
|||||||
|
|
||||||
if (!timestamp || !full_comm || !log_buf) {
|
if (!timestamp || !full_comm || !log_buf) {
|
||||||
pr_err("sulog: failed to allocate memory for su_grant log\n");
|
pr_err("sulog: failed to allocate memory for su_grant log\n");
|
||||||
goto cleanup_grant;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
get_timestamp(timestamp, 32);
|
get_timestamp(timestamp, 32);
|
||||||
@@ -283,11 +242,11 @@ void ksu_sulog_report_su_grant(uid_t uid, const char *comm, const char *method)
|
|||||||
method ? method : "unknown", current->pid);
|
method ? method : "unknown", current->pid);
|
||||||
|
|
||||||
if (!dedup_should_print(uid, DEDUP_SU_GRANT, log_buf, strlen(log_buf)))
|
if (!dedup_should_print(uid, DEDUP_SU_GRANT, log_buf, strlen(log_buf)))
|
||||||
goto cleanup_grant;
|
goto cleanup;
|
||||||
|
|
||||||
sulog_add_entry(log_buf);
|
sulog_add_entry(log_buf);
|
||||||
|
|
||||||
cleanup_grant:
|
cleanup:
|
||||||
if (timestamp) kfree(timestamp);
|
if (timestamp) kfree(timestamp);
|
||||||
if (full_comm) kfree(full_comm);
|
if (full_comm) kfree(full_comm);
|
||||||
if (log_buf) kfree(log_buf);
|
if (log_buf) kfree(log_buf);
|
||||||
@@ -306,7 +265,7 @@ void ksu_sulog_report_su_attempt(uid_t uid, const char *comm, const char *target
|
|||||||
|
|
||||||
if (!timestamp || !full_comm || !log_buf) {
|
if (!timestamp || !full_comm || !log_buf) {
|
||||||
pr_err("sulog: failed to allocate memory for su_attempt log\n");
|
pr_err("sulog: failed to allocate memory for su_attempt log\n");
|
||||||
goto cleanup_attempt;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
get_timestamp(timestamp, 32);
|
get_timestamp(timestamp, 32);
|
||||||
@@ -324,12 +283,12 @@ void ksu_sulog_report_su_attempt(uid_t uid, const char *comm, const char *target
|
|||||||
target_path ? target_path : "unknown",
|
target_path ? target_path : "unknown",
|
||||||
success ? "SUCCESS" : "DENIED", current->pid);
|
success ? "SUCCESS" : "DENIED", current->pid);
|
||||||
|
|
||||||
if (!dedup_should_print(uid, DEDUP_SU_GRANT, log_buf, strlen(log_buf)))
|
if (!dedup_should_print(uid, DEDUP_SU_ATTEMPT, log_buf, strlen(log_buf)))
|
||||||
goto cleanup_attempt;
|
goto cleanup;
|
||||||
|
|
||||||
sulog_add_entry(log_buf);
|
sulog_add_entry(log_buf);
|
||||||
|
|
||||||
cleanup_attempt:
|
cleanup:
|
||||||
if (timestamp) kfree(timestamp);
|
if (timestamp) kfree(timestamp);
|
||||||
if (full_comm) kfree(full_comm);
|
if (full_comm) kfree(full_comm);
|
||||||
if (log_buf) kfree(log_buf);
|
if (log_buf) kfree(log_buf);
|
||||||
@@ -348,7 +307,7 @@ void ksu_sulog_report_permission_check(uid_t uid, const char *comm, bool allowed
|
|||||||
|
|
||||||
if (!timestamp || !full_comm || !log_buf) {
|
if (!timestamp || !full_comm || !log_buf) {
|
||||||
pr_err("sulog: failed to allocate memory for permission_check log\n");
|
pr_err("sulog: failed to allocate memory for permission_check log\n");
|
||||||
goto cleanup_perm;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
get_timestamp(timestamp, 32);
|
get_timestamp(timestamp, 32);
|
||||||
@@ -365,12 +324,12 @@ void ksu_sulog_report_permission_check(uid_t uid, const char *comm, bool allowed
|
|||||||
timestamp, uid, full_comm,
|
timestamp, uid, full_comm,
|
||||||
allowed ? "ALLOWED" : "DENIED", current->pid);
|
allowed ? "ALLOWED" : "DENIED", current->pid);
|
||||||
|
|
||||||
if (!dedup_should_print(uid, DEDUP_SU_GRANT, log_buf, strlen(log_buf)))
|
if (!dedup_should_print(uid, DEDUP_PERM_CHECK, log_buf, strlen(log_buf)))
|
||||||
goto cleanup_perm;
|
goto cleanup;
|
||||||
|
|
||||||
sulog_add_entry(log_buf);
|
sulog_add_entry(log_buf);
|
||||||
|
|
||||||
cleanup_perm:
|
cleanup:
|
||||||
if (timestamp) kfree(timestamp);
|
if (timestamp) kfree(timestamp);
|
||||||
if (full_comm) kfree(full_comm);
|
if (full_comm) kfree(full_comm);
|
||||||
if (log_buf) kfree(log_buf);
|
if (log_buf) kfree(log_buf);
|
||||||
@@ -389,23 +348,23 @@ void ksu_sulog_report_manager_operation(const char *operation, uid_t manager_uid
|
|||||||
|
|
||||||
if (!timestamp || !full_comm || !log_buf) {
|
if (!timestamp || !full_comm || !log_buf) {
|
||||||
pr_err("sulog: failed to allocate memory for manager_operation log\n");
|
pr_err("sulog: failed to allocate memory for manager_operation log\n");
|
||||||
goto cleanup_mgr;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
get_timestamp(timestamp, 32);
|
get_timestamp(timestamp, 32);
|
||||||
get_full_comm(full_comm, SULOG_COMM_LEN);
|
get_full_comm(full_comm, SULOG_COMM_LEN);
|
||||||
|
|
||||||
snprintf(log_buf, SULOG_ENTRY_MAX_LEN,
|
snprintf(log_buf, SULOG_ENTRY_MAX_LEN,
|
||||||
"[%s] MANAGER_OP: OP=%s MANAGER_UID=%d TARGET_UID=%d PID=%d\n",
|
"[%s] MANAGER_OP: OP=%s MANAGER_UID=%d TARGET_UID=%d COMM=%s PID=%d\n",
|
||||||
timestamp, operation ? operation : "unknown",
|
timestamp, operation ? operation : "unknown",
|
||||||
manager_uid, target_uid, current->pid);
|
manager_uid, target_uid, full_comm, current->pid);
|
||||||
|
|
||||||
if (!dedup_should_print(manager_uid, DEDUP_SU_GRANT, log_buf, strlen(log_buf)))
|
if (!dedup_should_print(manager_uid, DEDUP_MANAGER_OP, log_buf, strlen(log_buf)))
|
||||||
goto cleanup_mgr;
|
goto cleanup;
|
||||||
|
|
||||||
sulog_add_entry(log_buf);
|
sulog_add_entry(log_buf);
|
||||||
|
|
||||||
cleanup_mgr:
|
cleanup:
|
||||||
if (timestamp) kfree(timestamp);
|
if (timestamp) kfree(timestamp);
|
||||||
if (full_comm) kfree(full_comm);
|
if (full_comm) kfree(full_comm);
|
||||||
if (log_buf) kfree(log_buf);
|
if (log_buf) kfree(log_buf);
|
||||||
@@ -425,11 +384,16 @@ void ksu_sulog_report_syscall(uid_t uid, const char *comm,
|
|||||||
|
|
||||||
if (!timestamp || !full_comm || !log_buf) {
|
if (!timestamp || !full_comm || !log_buf) {
|
||||||
pr_err("sulog: failed to allocate memory for syscall log\n");
|
pr_err("sulog: failed to allocate memory for syscall log\n");
|
||||||
goto cleanup_mgr;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
get_timestamp(timestamp, 32);
|
get_timestamp(timestamp, 32);
|
||||||
|
if (comm && strlen(comm) > 0) {
|
||||||
|
strncpy(full_comm, comm, SULOG_COMM_LEN - 1);
|
||||||
|
full_comm[SULOG_COMM_LEN - 1] = '\0';
|
||||||
|
} else {
|
||||||
get_full_comm(full_comm, SULOG_COMM_LEN);
|
get_full_comm(full_comm, SULOG_COMM_LEN);
|
||||||
|
}
|
||||||
|
|
||||||
snprintf(log_buf, SULOG_ENTRY_MAX_LEN,
|
snprintf(log_buf, SULOG_ENTRY_MAX_LEN,
|
||||||
"[%s] SYSCALL: UID=%d COMM=%s SYSCALL=%s ARGS=%s PID=%d\n",
|
"[%s] SYSCALL: UID=%d COMM=%s SYSCALL=%s ARGS=%s PID=%d\n",
|
||||||
@@ -438,31 +402,20 @@ void ksu_sulog_report_syscall(uid_t uid, const char *comm,
|
|||||||
args ? args : "none",
|
args ? args : "none",
|
||||||
current->pid);
|
current->pid);
|
||||||
|
|
||||||
if (!dedup_should_print(uid, DEDUP_SU_GRANT, log_buf, strlen(log_buf)))
|
if (!dedup_should_print(uid, DEDUP_SYSCALL, log_buf, strlen(log_buf)))
|
||||||
goto cleanup_mgr;
|
goto cleanup;
|
||||||
|
|
||||||
sulog_add_entry(log_buf);
|
sulog_add_entry(log_buf);
|
||||||
|
|
||||||
cleanup_mgr:
|
cleanup:
|
||||||
if (timestamp) kfree(timestamp);
|
if (timestamp) kfree(timestamp);
|
||||||
if (full_comm) kfree(full_comm);
|
if (full_comm) kfree(full_comm);
|
||||||
if (log_buf) kfree(log_buf);
|
if (log_buf) kfree(log_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ksu_sulog_set_enabled(bool enabled)
|
|
||||||
{
|
|
||||||
sulog_enabled = enabled;
|
|
||||||
pr_info("sulog: logging %s\n", enabled ? "enabled" : "disabled");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ksu_sulog_is_enabled(void)
|
|
||||||
{
|
|
||||||
return sulog_enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ksu_sulog_init(void)
|
int ksu_sulog_init(void)
|
||||||
{
|
{
|
||||||
sulog_workqueue = create_singlethread_workqueue("ksu_sulog");
|
sulog_workqueue = alloc_workqueue("ksu_sulog", WQ_UNBOUND | WQ_HIGHPRI, 1);
|
||||||
if (!sulog_workqueue) {
|
if (!sulog_workqueue) {
|
||||||
pr_err("sulog: failed to create workqueue\n");
|
pr_err("sulog: failed to create workqueue\n");
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|||||||
@@ -3,19 +3,51 @@
|
|||||||
|
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
|
||||||
|
extern struct timezone sys_tz;
|
||||||
|
|
||||||
|
#define SULOG_PATH "/data/adb/ksu/log/sulog.log"
|
||||||
|
#define SULOG_OLD_PATH "/data/adb/ksu/log/sulog.log.old"
|
||||||
|
#define SULOG_MAX_SIZE (128 * 1024 * 1024) // 128MB
|
||||||
|
#define SULOG_ENTRY_MAX_LEN 512
|
||||||
|
#define SULOG_COMM_LEN 256
|
||||||
|
#define DEDUP_SECS 10
|
||||||
|
|
||||||
|
struct dedup_key {
|
||||||
|
u32 crc;
|
||||||
|
uid_t uid;
|
||||||
|
u8 type;
|
||||||
|
u8 _pad[1];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct dedup_entry {
|
||||||
|
struct dedup_key key;
|
||||||
|
u64 ts_ns;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
DEDUP_SU_GRANT = 0,
|
||||||
|
DEDUP_SU_ATTEMPT,
|
||||||
|
DEDUP_PERM_CHECK,
|
||||||
|
DEDUP_MANAGER_OP,
|
||||||
|
DEDUP_SYSCALL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline u32 dedup_calc_hash(const char *content, size_t len)
|
||||||
|
{
|
||||||
|
return crc32(0, content, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sulog_entry {
|
||||||
|
struct list_head list;
|
||||||
|
char content[SULOG_ENTRY_MAX_LEN];
|
||||||
|
};
|
||||||
|
|
||||||
void ksu_sulog_report_su_grant(uid_t uid, const char *comm, const char *method);
|
void ksu_sulog_report_su_grant(uid_t uid, const char *comm, const char *method);
|
||||||
|
|
||||||
void ksu_sulog_report_su_attempt(uid_t uid, const char *comm, const char *target_path, bool success);
|
void ksu_sulog_report_su_attempt(uid_t uid, const char *comm, const char *target_path, bool success);
|
||||||
|
|
||||||
void ksu_sulog_report_permission_check(uid_t uid, const char *comm, bool allowed);
|
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_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_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);
|
|
||||||
|
|
||||||
int ksu_sulog_init(void);
|
int ksu_sulog_init(void);
|
||||||
void ksu_sulog_exit(void);
|
void ksu_sulog_exit(void);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user