Loading drivers/platform/msm/seemp_core/seemp_logk.c +89 −0 Original line number Diff line number Diff line Loading @@ -13,6 +13,11 @@ #define pr_fmt(fmt) "seemp: %s: " fmt, __func__ #include <linux/delay.h> #include <linux/kthread.h> #include <linux/seemp_instrumentation.h> #include <soc/qcom/scm.h> #include "seemp_logk.h" #include "seemp_ringbuf.h" Loading @@ -24,6 +29,8 @@ #define FOUR_MB 4 #define YEAR_BASE 1900 #define EL2_SCM_ID 0x02001902 static struct seemp_logk_dev *slogk_dev; static unsigned int ring_sz = FOUR_MB; Loading @@ -49,11 +56,15 @@ static rwlock_t filter_lock; static struct seemp_source_mask *pmask; static unsigned int num_sources; static void *el2_shared_mem; static struct task_struct *rtic_thread; static long seemp_logk_reserve_rdblks( struct seemp_logk_dev *sdev, unsigned long arg); static long seemp_logk_set_mask(unsigned long arg); static long seemp_logk_set_mapping(unsigned long arg); static long seemp_logk_check_filter(unsigned long arg); static int seemp_logk_rtic_thread(void *data); void* (*seemp_logk_kernel_begin)(char **buf); Loading Loading @@ -569,6 +580,15 @@ static int seemp_logk_mmap(struct file *filp, } } if (!rtic_thread && el2_shared_mem) { rtic_thread = kthread_run(seemp_logk_rtic_thread, NULL, "seemp_logk_rtic_thread"); if (IS_ERR(rtic_thread)) { pr_err("rtic_thread creation failed"); rtic_thread = NULL; } } return 0; } Loading @@ -580,10 +600,59 @@ static const struct file_operations seemp_logk_fops = { .mmap = seemp_logk_mmap, }; static int seemp_logk_rtic_thread(void *data) { struct el2_report_header_t *header; __u64 last_sequence_number = 0; int last_pos = -1; int i; int num_entries = (PAGE_SIZE - sizeof(struct el2_report_header_t)) / sizeof(struct el2_report_data_t); header = (struct el2_report_header_t *) el2_shared_mem; while (!kthread_should_stop()) { for (i = 1; i < num_entries + 1; i++) { struct el2_report_data_t *report; int cur_pos = last_pos + i; if (cur_pos >= num_entries) cur_pos -= num_entries; report = el2_shared_mem + sizeof(struct el2_report_header_t) + cur_pos * sizeof(struct el2_report_data_t); /* determine legitimacy of report */ if (report->report_valid && report->sequence_number <= header->num_incidents && (last_sequence_number == 0 || report->sequence_number > last_sequence_number)) { seemp_logk_rtic(report->report_type, report->report.incident.actor, report->report.incident.asset_id, report->report.incident.asset_category, report->report.incident.response); last_sequence_number = report->sequence_number; } else { last_pos = cur_pos - 1; break; } } /* periodically check el2 report every second */ ssleep(1); } return 0; } __init int seemp_logk_init(void) { int ret; int devno = 0; struct scm_desc desc = {0}; num_sources = 0; kmalloc_flag = 0; Loading Loading @@ -650,6 +719,21 @@ __init int seemp_logk_init(void) init_waitqueue_head(&slogk_dev->readers_wq); init_waitqueue_head(&slogk_dev->writers_wq); rwlock_init(&filter_lock); el2_shared_mem = (void *) __get_free_page(GFP_KERNEL); if (el2_shared_mem) { desc.arginfo = SCM_ARGS(2, SCM_RW, SCM_VAL); desc.args[0] = (uint64_t) virt_to_phys(el2_shared_mem); desc.args[1] = PAGE_SIZE; ret = scm_call2(EL2_SCM_ID, &desc); if (ret || desc.ret[0] || desc.ret[1]) { pr_err("SCM call failed with ret val = %d %d %d", ret, (int)desc.ret[0], (int)desc.ret[1]); free_page((unsigned long) el2_shared_mem); el2_shared_mem = NULL; } } return 0; class_destroy_fail: class_destroy(cl); Loading @@ -666,6 +750,11 @@ __exit void seemp_logk_cleanup(void) { dev_t devno = MKDEV(slogk_dev->major, slogk_dev->minor); if (rtic_thread) { kthread_stop(rtic_thread); rtic_thread = NULL; } seemp_logk_detach(); cdev_del(&slogk_dev->cdev); Loading drivers/platform/msm/seemp_core/seemp_logk.h +41 −0 Original line number Diff line number Diff line Loading @@ -158,4 +158,45 @@ struct seemp_source_mask { __u32 hash; bool isOn; }; /* report region header */ struct el2_report_header_t { __u64 report_version; /* Version of the EL2 report */ __u64 mp_catalog_version; /* Version of MP catalogue used for kernel protection */ __u8 protection_enabled; /* Kernel Assets protected by EL2 */ __u8 pad1; __u8 pad2; __u8 pad3; __u32 pad4; __u64 num_incidents; /* Number of Incidents Observed by EL2 */ }; /* individual report contents */ union el2_report { struct { __u8 asset_id[0x20]; /* Asset Identifier */ __u64 actor; /* Actor that caused the Incident. */ __u8 asset_category; /* Asset Category */ __u8 response; /* Response From EL2 */ __u16 pad1; __u32 pad2; } incident; struct { __u64 reserved; /* TBD */ } info; }; /* individual report */ struct el2_report_data_t { __u8 report_valid; /* Flag to indicate whether report instance is valid */ __u8 report_type; /* Report Type */ __u8 pad1; __u8 pad2; __u64 sequence_number; /* Sequence number of the report */ union el2_report report; /* Report Contents */ }; #endif include/linux/seemp_instrumentation.h +24 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,8 @@ #ifdef CONFIG_SEEMP_CORE #include <linux/kernel.h> #include <linux/seemp_api.h> #include <linux/socket.h> #define MAX_BUF_SIZE 188 Loading Loading @@ -66,11 +68,33 @@ static inline void seemp_logk_sendto(int fd, void __user *buff, size_t len, seemp_logk_kernel_end(blck); } static inline void seemp_logk_rtic(__u8 type, __u64 actor, __u8 asset_id[0x20], __u8 asset_category, __u8 response) { char *buf = NULL; void *blck = NULL; blck = seemp_setup_buf(&buf); if (!blck) return; SEEMP_LOGK_RECORD(SEEMP_API_kernel__rtic, "app_pid=%llu,rtic_type=%u,asset_id=%s,asset_category=%u,response=%u", actor, type, asset_id, asset_category, response); seemp_logk_kernel_end(blck); } #else static inline void seemp_logk_sendto(int fd, void __user *buff, size_t len, unsigned int flags, struct sockaddr __user *addr, int addr_len) { } static inline void seemp_logk_rtic(__u8 type, __u64 actor, __u8 asset_id[0x20], __u8 asset_category, __u8 response) { } #endif #endif include/uapi/linux/seemp_api.h +2 −0 Original line number Diff line number Diff line #ifndef _SEEMP_API_H_ #define _SEEMP_API_H_ #define SEEMP_API_kernel__rtic 100000 #define SEEMP_API_kernel__oom_adjust_write 0 #define SEEMP_API_kernel__sendto 1 #define SEEMP_API_kernel__recvfrom 2 Loading include/uapi/linux/seemp_param_id.h +25 −1 Original line number Diff line number Diff line Loading @@ -15,7 +15,11 @@ #define PARAM_ID_SENSOR 8 #define PARAM_ID_WINDOW_TYPE 9 #define PARAM_ID_WINDOW_FLAG 10 #define NUM_PARAM_IDS 11 #define PARAM_ID_RTIC_TYPE 11 #define PARAM_ID_RTIC_ASSET_ID 12 #define PARAM_ID_RTIC_ASSET_CATEGORY 13 #define PARAM_ID_RTIC_RESPONSE 14 #define NUM_PARAM_IDS 15 static inline int param_id_index(const char *param, const char *end) { Loading Loading @@ -44,6 +48,14 @@ static inline int param_id_index(const char *param, const char *end) id = 9; else if ((len == 11) && !memcmp(param, "window_flag", 11)) id = 10; else if ((len == 9) && !memcmp(param, "rtic_type", 9)) id = 11; else if ((len == 8) && !memcmp(param, "asset_id", 8)) id = 12; else if ((len == 14) && !memcmp(param, "asset_category", 14)) id = 13; else if ((len == 8) && !memcmp(param, "response", 8)) id = 14; return id; } Loading Loading @@ -86,6 +98,18 @@ static inline const char *get_param_id_name(int id) case 10: name = "window_flag"; break; case 11: name = "rtic_type"; break; case 12: name = "asset_id"; break; case 13: name = "asset_category"; break; case 14: name = "response"; break; } return name; } Loading Loading
drivers/platform/msm/seemp_core/seemp_logk.c +89 −0 Original line number Diff line number Diff line Loading @@ -13,6 +13,11 @@ #define pr_fmt(fmt) "seemp: %s: " fmt, __func__ #include <linux/delay.h> #include <linux/kthread.h> #include <linux/seemp_instrumentation.h> #include <soc/qcom/scm.h> #include "seemp_logk.h" #include "seemp_ringbuf.h" Loading @@ -24,6 +29,8 @@ #define FOUR_MB 4 #define YEAR_BASE 1900 #define EL2_SCM_ID 0x02001902 static struct seemp_logk_dev *slogk_dev; static unsigned int ring_sz = FOUR_MB; Loading @@ -49,11 +56,15 @@ static rwlock_t filter_lock; static struct seemp_source_mask *pmask; static unsigned int num_sources; static void *el2_shared_mem; static struct task_struct *rtic_thread; static long seemp_logk_reserve_rdblks( struct seemp_logk_dev *sdev, unsigned long arg); static long seemp_logk_set_mask(unsigned long arg); static long seemp_logk_set_mapping(unsigned long arg); static long seemp_logk_check_filter(unsigned long arg); static int seemp_logk_rtic_thread(void *data); void* (*seemp_logk_kernel_begin)(char **buf); Loading Loading @@ -569,6 +580,15 @@ static int seemp_logk_mmap(struct file *filp, } } if (!rtic_thread && el2_shared_mem) { rtic_thread = kthread_run(seemp_logk_rtic_thread, NULL, "seemp_logk_rtic_thread"); if (IS_ERR(rtic_thread)) { pr_err("rtic_thread creation failed"); rtic_thread = NULL; } } return 0; } Loading @@ -580,10 +600,59 @@ static const struct file_operations seemp_logk_fops = { .mmap = seemp_logk_mmap, }; static int seemp_logk_rtic_thread(void *data) { struct el2_report_header_t *header; __u64 last_sequence_number = 0; int last_pos = -1; int i; int num_entries = (PAGE_SIZE - sizeof(struct el2_report_header_t)) / sizeof(struct el2_report_data_t); header = (struct el2_report_header_t *) el2_shared_mem; while (!kthread_should_stop()) { for (i = 1; i < num_entries + 1; i++) { struct el2_report_data_t *report; int cur_pos = last_pos + i; if (cur_pos >= num_entries) cur_pos -= num_entries; report = el2_shared_mem + sizeof(struct el2_report_header_t) + cur_pos * sizeof(struct el2_report_data_t); /* determine legitimacy of report */ if (report->report_valid && report->sequence_number <= header->num_incidents && (last_sequence_number == 0 || report->sequence_number > last_sequence_number)) { seemp_logk_rtic(report->report_type, report->report.incident.actor, report->report.incident.asset_id, report->report.incident.asset_category, report->report.incident.response); last_sequence_number = report->sequence_number; } else { last_pos = cur_pos - 1; break; } } /* periodically check el2 report every second */ ssleep(1); } return 0; } __init int seemp_logk_init(void) { int ret; int devno = 0; struct scm_desc desc = {0}; num_sources = 0; kmalloc_flag = 0; Loading Loading @@ -650,6 +719,21 @@ __init int seemp_logk_init(void) init_waitqueue_head(&slogk_dev->readers_wq); init_waitqueue_head(&slogk_dev->writers_wq); rwlock_init(&filter_lock); el2_shared_mem = (void *) __get_free_page(GFP_KERNEL); if (el2_shared_mem) { desc.arginfo = SCM_ARGS(2, SCM_RW, SCM_VAL); desc.args[0] = (uint64_t) virt_to_phys(el2_shared_mem); desc.args[1] = PAGE_SIZE; ret = scm_call2(EL2_SCM_ID, &desc); if (ret || desc.ret[0] || desc.ret[1]) { pr_err("SCM call failed with ret val = %d %d %d", ret, (int)desc.ret[0], (int)desc.ret[1]); free_page((unsigned long) el2_shared_mem); el2_shared_mem = NULL; } } return 0; class_destroy_fail: class_destroy(cl); Loading @@ -666,6 +750,11 @@ __exit void seemp_logk_cleanup(void) { dev_t devno = MKDEV(slogk_dev->major, slogk_dev->minor); if (rtic_thread) { kthread_stop(rtic_thread); rtic_thread = NULL; } seemp_logk_detach(); cdev_del(&slogk_dev->cdev); Loading
drivers/platform/msm/seemp_core/seemp_logk.h +41 −0 Original line number Diff line number Diff line Loading @@ -158,4 +158,45 @@ struct seemp_source_mask { __u32 hash; bool isOn; }; /* report region header */ struct el2_report_header_t { __u64 report_version; /* Version of the EL2 report */ __u64 mp_catalog_version; /* Version of MP catalogue used for kernel protection */ __u8 protection_enabled; /* Kernel Assets protected by EL2 */ __u8 pad1; __u8 pad2; __u8 pad3; __u32 pad4; __u64 num_incidents; /* Number of Incidents Observed by EL2 */ }; /* individual report contents */ union el2_report { struct { __u8 asset_id[0x20]; /* Asset Identifier */ __u64 actor; /* Actor that caused the Incident. */ __u8 asset_category; /* Asset Category */ __u8 response; /* Response From EL2 */ __u16 pad1; __u32 pad2; } incident; struct { __u64 reserved; /* TBD */ } info; }; /* individual report */ struct el2_report_data_t { __u8 report_valid; /* Flag to indicate whether report instance is valid */ __u8 report_type; /* Report Type */ __u8 pad1; __u8 pad2; __u64 sequence_number; /* Sequence number of the report */ union el2_report report; /* Report Contents */ }; #endif
include/linux/seemp_instrumentation.h +24 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,8 @@ #ifdef CONFIG_SEEMP_CORE #include <linux/kernel.h> #include <linux/seemp_api.h> #include <linux/socket.h> #define MAX_BUF_SIZE 188 Loading Loading @@ -66,11 +68,33 @@ static inline void seemp_logk_sendto(int fd, void __user *buff, size_t len, seemp_logk_kernel_end(blck); } static inline void seemp_logk_rtic(__u8 type, __u64 actor, __u8 asset_id[0x20], __u8 asset_category, __u8 response) { char *buf = NULL; void *blck = NULL; blck = seemp_setup_buf(&buf); if (!blck) return; SEEMP_LOGK_RECORD(SEEMP_API_kernel__rtic, "app_pid=%llu,rtic_type=%u,asset_id=%s,asset_category=%u,response=%u", actor, type, asset_id, asset_category, response); seemp_logk_kernel_end(blck); } #else static inline void seemp_logk_sendto(int fd, void __user *buff, size_t len, unsigned int flags, struct sockaddr __user *addr, int addr_len) { } static inline void seemp_logk_rtic(__u8 type, __u64 actor, __u8 asset_id[0x20], __u8 asset_category, __u8 response) { } #endif #endif
include/uapi/linux/seemp_api.h +2 −0 Original line number Diff line number Diff line #ifndef _SEEMP_API_H_ #define _SEEMP_API_H_ #define SEEMP_API_kernel__rtic 100000 #define SEEMP_API_kernel__oom_adjust_write 0 #define SEEMP_API_kernel__sendto 1 #define SEEMP_API_kernel__recvfrom 2 Loading
include/uapi/linux/seemp_param_id.h +25 −1 Original line number Diff line number Diff line Loading @@ -15,7 +15,11 @@ #define PARAM_ID_SENSOR 8 #define PARAM_ID_WINDOW_TYPE 9 #define PARAM_ID_WINDOW_FLAG 10 #define NUM_PARAM_IDS 11 #define PARAM_ID_RTIC_TYPE 11 #define PARAM_ID_RTIC_ASSET_ID 12 #define PARAM_ID_RTIC_ASSET_CATEGORY 13 #define PARAM_ID_RTIC_RESPONSE 14 #define NUM_PARAM_IDS 15 static inline int param_id_index(const char *param, const char *end) { Loading Loading @@ -44,6 +48,14 @@ static inline int param_id_index(const char *param, const char *end) id = 9; else if ((len == 11) && !memcmp(param, "window_flag", 11)) id = 10; else if ((len == 9) && !memcmp(param, "rtic_type", 9)) id = 11; else if ((len == 8) && !memcmp(param, "asset_id", 8)) id = 12; else if ((len == 14) && !memcmp(param, "asset_category", 14)) id = 13; else if ((len == 8) && !memcmp(param, "response", 8)) id = 14; return id; } Loading Loading @@ -86,6 +98,18 @@ static inline const char *get_param_id_name(int id) case 10: name = "window_flag"; break; case 11: name = "rtic_type"; break; case 12: name = "asset_id"; break; case 13: name = "asset_category"; break; case 14: name = "response"; break; } return name; } Loading