[FIX] Workaround to skip page faults from Preload 55/46855/4
authorVasiliy Ulyanov <v.ulyanov@samsung.com>
Wed, 26 Aug 2015 09:15:21 +0000 (12:15 +0300)
committerDmitry Kovalenko <d.kovalenko@samsung.com>
Fri, 28 Aug 2015 06:35:32 +0000 (23:35 -0700)
Attempts to read userspace stuff from probe handlers (e.g. like we
do in Preload) may lead to crashes.

Change-Id: I00009bb9dc19ba003740d078b9a36dee2f75c3f5
Signed-off-by: Vyacheslav Cherkashin <v.cherkashin@samsung.com>
preload/preload_module.c
us_manager/helper.c
us_manager/sspt/sspt_proc.c
us_manager/sspt/sspt_proc.h

index 547edf9..580c066 100644 (file)
@@ -374,6 +374,7 @@ static inline int __msg_sanitization(char *user_msg, size_t len,
 static bool __is_proc_mmap_mappable(struct task_struct *task)
 {
        struct vm_area_struct *linker_vma = __get_linker_vma(task);
+       struct sspt_proc *proc;
        unsigned long r_debug_addr;
        unsigned int state;
        enum { r_state_offset = sizeof(int) + sizeof(void *) + sizeof(long) };
@@ -386,6 +387,10 @@ static bool __is_proc_mmap_mappable(struct task_struct *task)
                return false;
 
        r_debug_addr += r_state_offset;
+       proc = sspt_proc_get_by_task(task);
+       if (proc)
+               proc->r_state_addr = r_debug_addr;
+
        if (get_user(state, (unsigned long *)r_debug_addr))
                return false;
 
index d71adf4..3ba5c4f 100644 (file)
@@ -68,6 +68,14 @@ static int entry_handler_pf(struct kretprobe_instance *ri, struct pt_regs *regs)
        #error "this architecture is not supported"
 #endif /* CONFIG_arch */
 
+       if (data->addr) {
+               struct sspt_proc * proc = sspt_proc_get_by_task(current);
+
+               if (proc && (proc->r_state_addr == data->addr))
+                       /* skip ret_handler_pf() for current task */
+                       return 1;
+       }
+
        return 0;
 }
 
index 01f0353..85d24f4 100644 (file)
@@ -88,7 +88,7 @@ void sspt_proc_write_unlock(void)
  */
 struct sspt_proc *sspt_proc_create(struct task_struct *task)
 {
-       struct sspt_proc *proc = kmalloc(sizeof(*proc), GFP_ATOMIC);
+       struct sspt_proc *proc = kzalloc(sizeof(*proc), GFP_ATOMIC);
 
        if (proc) {
                proc->feature = sspt_create_feature();
@@ -101,8 +101,6 @@ struct sspt_proc *sspt_proc_create(struct task_struct *task)
                proc->tgid = task->tgid;
                proc->task = task->group_leader;
                proc->sm = create_sm_us(task);
-               proc->first_install = 0;
-               proc->private_data = NULL;
                INIT_LIST_HEAD(&proc->file_list);
                INIT_LIST_HEAD(&proc->filter_list);
                atomic_set(&proc->usage, 1);
index 534f150..d82a271 100644 (file)
@@ -48,6 +48,7 @@ struct sspt_proc {
        struct list_head list;          /**< For global process list */
        pid_t tgid;                     /**< Thread group ID */
        struct task_struct *task;       /**< Ptr to the task */
+       unsigned long r_state_addr;     /**< address of r_state */
        struct slot_manager *sm;        /**< Ptr to the manager slot */
        struct list_head file_list;     /**< For sspt_file */
        struct list_head filter_list;   /**< Filter list */