summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVasiliy Ulyanov <v.ulyanov@samsung.com>2015-08-26 12:15:21 +0300
committerDmitry Kovalenko <d.kovalenko@samsung.com>2015-08-27 23:35:32 -0700
commit2b54b37c9a190cb48477fd68a0e004efaf64b163 (patch)
tree651c7b7b4a8a473e7fe81e6597cd48e46a7e1837
parent92c2d62a0f2fdfdeb4111787eab7eede6cfc16a3 (diff)
downloadswap-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.c5
-rw-r--r--us_manager/helper.c8
-rw-r--r--us_manager/sspt/sspt_proc.c4
-rw-r--r--us_manager/sspt/sspt_proc.h1
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 */