From: Vyacheslav Cherkashin Date: Wed, 14 May 2014 13:55:49 +0000 (+0400) Subject: [PROTO] add task->comm monitoring functionality X-Git-Tag: Tizen_SDK_2.3~62 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3d1d6bb2c67a8415331899a431b5dc501cdfacd3;p=kernel%2Fswap-modules.git [PROTO] add task->comm monitoring functionality Change-Id: Ie6197b2f38e6b98d9bb58d82ac85399a1f65ee60 Signed-off-by: Vyacheslav Cherkashin --- diff --git a/us_manager/helper.c b/us_manager/helper.c index eae924c..a268cad 100644 --- a/us_manager/helper.c +++ b/us_manager/helper.c @@ -484,16 +484,85 @@ static void unregister_mmap(void) +/* + ****************************************************************************** + * set_task_comm() * + ****************************************************************************** + */ +struct comm_data { + struct task_struct *task; +}; + +static int entry_handler_comm(struct kretprobe_instance *ri, struct pt_regs *regs) +{ + struct comm_data *data = (struct comm_data *)ri->data; + + data->task = (struct task_struct *)swap_get_karg(regs, 0); + + return 0; +} + +static int ret_handler_comm(struct kretprobe_instance *ri, struct pt_regs *regs) +{ + struct task_struct *task; + + if (is_kthread(current)) + return 0; + + task = ((struct comm_data *)ri->data)->task; + if (sspt_proc_get_by_task(task) == NULL) + return 0; + + proc_comm_msg(task); + + return 0; +} + +static struct kretprobe comm_kretprobe = { + .entry_handler = entry_handler_comm, + .handler = ret_handler_comm, + .data_size = sizeof(struct comm_data) +}; + +static int register_comm(void) +{ + int ret; + + ret = swap_register_kretprobe(&comm_kretprobe); + if (ret) + printk("swap_register_kretprobe(set_task_comm) ret=%d!\n", + ret); + + return ret; +} + +static void unregister_comm(void) +{ + swap_unregister_kretprobe(&comm_kretprobe); +} + + + + + int register_helper(void) { int ret = 0; atomic_set(&stop_flag, 0); + /* + * install probe on 'set_task_comm' to detect when field comm struct + * task_struct changes + */ + ret = register_comm(); + if (ret) + return ret; + /* install probe on 'do_munmap' to detect when for remove US probes */ ret = register_unmap(); if (ret) - return ret; + goto unreg_comm; /* install probe on 'mm_release' to detect when for remove US probes */ ret = register_mr(); @@ -544,6 +613,9 @@ unreg_mr: unreg_unmap: unregister_unmap(); +unreg_comm: + unregister_comm(); + return ret; } @@ -562,6 +634,7 @@ void unregister_helper_bottom(void) unregister_cp(); unregister_mr(); unregister_unmap(); + unregister_comm(); } int init_helper(void) @@ -608,6 +681,13 @@ int init_helper(void) } mmap_kretprobe.kp.addr = (kprobe_opcode_t *)addr; + addr = swap_ksyms("set_task_comm"); + if (addr == 0) { + printk("Cannot find address for set_task_comm function!\n"); + return -EINVAL; + } + comm_kretprobe.kp.addr = (kprobe_opcode_t *)addr; + #ifdef CONFIG_ARM addr = swap_ksyms("ret_to_user"); if (addr == 0) { diff --git a/writer/swap_writer_module.c b/writer/swap_writer_module.c index c4e864e..33a92d5 100644 --- a/writer/swap_writer_module.c +++ b/writer/swap_writer_module.c @@ -57,7 +57,8 @@ enum MSG_ID { MSG_CONTEXT_SWITCH_ENTRY = 0x0010, MSG_CONTEXT_SWITCH_EXIT = 0x0011, MSG_PROC_MAP = 0x0012, - MSG_PROC_UNMAP = 0x0013 + MSG_PROC_UNMAP = 0x0013, + MSG_PROC_COMM = 0x0014 }; static char *cpu_buf[NR_CPUS]; @@ -195,8 +196,12 @@ static char* pack_basic_msg_fmt(char *buf, enum MSG_ID id) * ============================================================================ */ -struct proc_info { +struct proc_info_top { u32 pid; + char comm[0]; +} __attribute__((packed)); + +struct proc_info_bottom { u32 ppid; u32 start_sec; u32 start_nsec; @@ -326,10 +331,26 @@ static char *pack_proc_info_part(char *end_path, struct mm_struct *mm) return lib_obj; } -static char *pack_proc_info(char *payload, struct task_struct *task, - struct dentry *dentry) +static char *pack_comm(char *buf, struct task_struct *task) +{ + get_task_comm(buf, task); + + return buf + strlen(buf) + 1; +} + +static char *pack_proc_info_top(char *data, struct task_struct *task) +{ + struct proc_info_top *pit = (struct proc_info_top *)data; + + pit->pid = task->tgid; + + return pack_comm(pit->comm, task); +} + +static char *pack_proc_info_bottom(char *data, struct task_struct *task, + struct dentry *dentry) { - struct proc_info *pi = (struct proc_info *)payload; + struct proc_info_bottom *pib = (struct proc_info_bottom *)data; struct vm_area_struct *vma = find_vma_exe_by_dentry(task->mm, dentry); struct timespec boot_time; struct timespec start_time; @@ -338,23 +359,29 @@ static char *pack_proc_info(char *payload, struct task_struct *task, getboottime(&boot_time); start_time = timespec_add(boot_time, task->real_start_time); - pi->pid = task->tgid; - pi->ppid = task->real_parent->tgid; - pi->start_sec = (u32)start_time.tv_sec; - pi->start_nsec = (u32)start_time.tv_nsec; + pib->ppid = task->real_parent->tgid; + pib->start_sec = (u32)start_time.tv_sec; + pib->start_nsec = (u32)start_time.tv_nsec; if (vma) { - pi->low_addr = vma->vm_start; - pi->high_addr = vma->vm_end; - end_path = pack_path(pi->bin_path, vma->vm_file); + pib->low_addr = vma->vm_start; + pib->high_addr = vma->vm_end; + end_path = pack_path(pib->bin_path, vma->vm_file); } else { - pi->low_addr = 0; - pi->high_addr = 0; - end_path = pack_path(pi->bin_path, NULL); + pib->low_addr = 0; + pib->high_addr = 0; + end_path = pack_path(pib->bin_path, NULL); } return pack_proc_info_part(end_path, task->mm); } +static char *pack_proc_info(char *payload, struct task_struct *task, + struct dentry *dentry) +{ + payload = pack_proc_info_top(payload, task); + return pack_proc_info_bottom(payload, task, dentry); +} + /* called with down\up\_read(&task->mm->mmap_sem) */ int proc_info_msg(struct task_struct *task, struct dentry *dentry) { @@ -497,6 +524,43 @@ EXPORT_SYMBOL_GPL(proc_unmap_msg); /* ============================================================================ + * = PROCESS COMM = + * ============================================================================ + */ +struct proc_comm { + u32 pid; + char comm[0]; +} __attribute__((packed)); + +static char *pack_proc_comm(char *data, struct task_struct *task) +{ + struct proc_comm *pcomm= (struct proc_comm *)data; + + pcomm->pid = task->tgid; + + return pack_comm(pcomm->comm, task); +} + +void proc_comm_msg(struct task_struct *task) +{ + char *buf, *payload, *buf_end; + + buf = get_current_buf(); + payload = pack_basic_msg_fmt(buf, MSG_PROC_COMM); + buf_end = pack_proc_comm(payload, task); + + set_len_msg(buf, buf_end); + + write_to_buffer(buf); + put_current_buf(); +} +EXPORT_SYMBOL_GPL(proc_comm_msg); + + + + + +/* ============================================================================ * = SAMPLE = * ============================================================================ */ diff --git a/writer/swap_writer_module.h b/writer/swap_writer_module.h index e932a93..c74b832 100644 --- a/writer/swap_writer_module.h +++ b/writer/swap_writer_module.h @@ -59,6 +59,7 @@ int proc_info_msg(struct task_struct *task, struct dentry *dentry); void terminate_msg(struct task_struct *task); void pcoc_map_msg(struct vm_area_struct *vma); void proc_unmap_msg(unsigned long start, unsigned long end); +void proc_comm_msg(struct task_struct *task); int sample_msg(struct pt_regs *regs); int entry_event(const char *fmt, unsigned long func_addr, struct pt_regs *regs,