diff options
author | Vasiliy Ulyanov <v.ulyanov@samsung.com> | 2015-08-26 12:15:21 +0300 |
---|---|---|
committer | Dmitry Kovalenko <d.kovalenko@samsung.com> | 2015-08-27 23:35:32 -0700 |
commit | 2b54b37c9a190cb48477fd68a0e004efaf64b163 (patch) | |
tree | 651c7b7b4a8a473e7fe81e6597cd48e46a7e1837 | |
parent | 92c2d62a0f2fdfdeb4111787eab7eede6cfc16a3 (diff) | |
download | swap-modules-2b54b37c9a190cb48477fd68a0e004efaf64b163.tar.gz swap-modules-2b54b37c9a190cb48477fd68a0e004efaf64b163.tar.bz2 swap-modules-2b54b37c9a190cb48477fd68a0e004efaf64b163.zip |
[FIX] Workaround to skip page faults from Preload
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>
-rw-r--r-- | preload/preload_module.c | 5 | ||||
-rw-r--r-- | us_manager/helper.c | 8 | ||||
-rw-r--r-- | us_manager/sspt/sspt_proc.c | 4 | ||||
-rw-r--r-- | us_manager/sspt/sspt_proc.h | 1 |
4 files changed, 15 insertions, 3 deletions
diff --git a/preload/preload_module.c b/preload/preload_module.c index 547edf95..580c066d 100644 --- a/preload/preload_module.c +++ b/preload/preload_module.c @@ -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; diff --git a/us_manager/helper.c b/us_manager/helper.c index d71adf45..3ba5c4f0 100644 --- a/us_manager/helper.c +++ b/us_manager/helper.c @@ -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; } diff --git a/us_manager/sspt/sspt_proc.c b/us_manager/sspt/sspt_proc.c index 01f0353d..85d24f4e 100644 --- a/us_manager/sspt/sspt_proc.c +++ b/us_manager/sspt/sspt_proc.c @@ -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); diff --git a/us_manager/sspt/sspt_proc.h b/us_manager/sspt/sspt_proc.h index 534f1506..d82a2712 100644 --- a/us_manager/sspt/sspt_proc.h +++ b/us_manager/sspt/sspt_proc.h @@ -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 */ |