[PROTO] add task->comm monitoring functionality 28/21028/2
authorVyacheslav Cherkashin <v.cherkashin@samsung.com>
Wed, 14 May 2014 13:55:49 +0000 (17:55 +0400)
committerDmitry Kovalenko <d.kovalenko@samsung.com>
Tue, 27 May 2014 07:28:44 +0000 (00:28 -0700)
Change-Id: Ie6197b2f38e6b98d9bb58d82ac85399a1f65ee60
Signed-off-by: Vyacheslav Cherkashin <v.cherkashin@samsung.com>
us_manager/helper.c
writer/swap_writer_module.c
writer/swap_writer_module.h

index eae924c..a268cad 100644 (file)
@@ -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) {
index c4e864e..33a92d5 100644 (file)
@@ -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                                   =
  * ============================================================================
  */
index e932a93..c74b832 100644 (file)
@@ -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,