650e7bb9e4f79d5c80be79f86a36ed5f7241b1ff
[kernel/swap-modules.git] / preload / preload_module.c
1 #include <linux/module.h>
2 #include <linux/dcache.h>
3 #include <linux/namei.h>
4 #include <linux/mman.h>
5 #include <linux/err.h>
6 #include <linux/types.h>
7 #include <kprobe/swap_kprobes.h>
8 #include <kprobe/swap_kprobes_deps.h>
9 #include <us_manager/sspt/sspt_proc.h>
10 #include <us_manager/sspt/sspt_ip.h>
11 #include <us_manager/callbacks.h>
12 #include <writer/kernel_operations.h>
13 #include <master/swap_initializer.h>
14 #include "preload.h"
15 #include "preload_probe.h"
16 #include "preload_debugfs.h"
17 #include "preload_module.h"
18 #include "preload_storage.h"
19 #include "preload_control.h"
20 #include "preload_threads.h"
21 #include "preload_pd.h"
22
23
24 struct us_priv {
25         struct pt_regs regs;
26         unsigned long arg0;
27         unsigned long arg1;
28         unsigned long raddr;
29         unsigned long origin;
30 };
31
32 static atomic_t dentry_balance = ATOMIC_INIT(0);
33
34 enum preload_status_t {
35         SWAP_PRELOAD_NOT_READY = 0,
36         SWAP_PRELOAD_READY = 1,
37         SWAP_PRELOAD_RUNNING = 2
38 };
39
40 static enum preload_status_t __preload_status = SWAP_PRELOAD_NOT_READY;
41
42 static int __preload_cbs_start_h = -1;
43 static int __preload_cbs_stop_h = -1;
44
45
46 static struct dentry *__get_dentry(struct dentry *dentry)
47 {
48         atomic_inc(&dentry_balance);
49         return dget(dentry);
50 }
51
52
53
54 bool preload_module_is_running(void)
55 {
56         if (__preload_status == SWAP_PRELOAD_RUNNING)
57                 return true;
58
59         return false;
60 }
61
62 bool preload_module_is_ready(void)
63 {
64         if (__preload_status == SWAP_PRELOAD_READY)
65                 return true;
66
67         return false;
68 }
69
70 bool preload_module_is_not_ready(void)
71 {
72         if (__preload_status == SWAP_PRELOAD_NOT_READY)
73                 return true;
74
75         return false;
76 }
77
78 void preload_module_set_ready(void)
79 {
80         __preload_status = SWAP_PRELOAD_READY;
81 }
82
83 void preload_module_set_running(void)
84 {
85         __preload_status = SWAP_PRELOAD_RUNNING;
86 }
87
88 void preload_module_set_not_ready(void)
89 {
90         __preload_status = SWAP_PRELOAD_NOT_READY;
91 }
92
93 struct dentry *get_dentry(const char *filepath)
94 {
95         struct path path;
96         struct dentry *dentry = NULL;
97
98         if (kern_path(filepath, LOOKUP_FOLLOW, &path) == 0) {
99                 dentry = __get_dentry(path.dentry);
100                 path_put(&path);
101         }
102
103         return dentry;
104 }
105
106 void put_dentry(struct dentry *dentry)
107 {
108         atomic_dec(&dentry_balance);
109         dput(dentry);
110 }
111
112 static inline void __prepare_ujump(struct uretprobe_instance *ri,
113                                    struct pt_regs *regs,
114                                    unsigned long vaddr)
115 {
116 #ifdef CONFIG_ARM
117         ri->preload.use = true;
118         ri->preload.thumb = !!thumb_mode(regs);
119 #endif /* CONFIG_ARM */
120
121         swap_set_instr_ptr(regs, vaddr);
122 }
123
124 static inline int __push(struct pt_regs *regs, void *buf, size_t len)
125 {
126         unsigned long sp = swap_get_stack_ptr(regs) - len;
127
128         sp = PTR_ALIGN(sp, sizeof(unsigned long));
129         if (copy_to_user((void __user *)sp, buf, len))
130                 return -EIO;
131         swap_set_stack_ptr(regs, sp);
132
133         return 0;
134 }
135
136 static inline void __save_uregs(struct uretprobe_instance *ri,
137                                 struct pt_regs *regs)
138 {
139         struct us_priv *priv = (struct us_priv *)ri->data;
140
141         memcpy(ri->data, regs, sizeof(*regs));
142         priv->arg0 = swap_get_arg(regs, 0);
143         priv->arg1 = swap_get_arg(regs, 1);
144         priv->raddr = swap_get_ret_addr(regs);
145 }
146
147 static inline void __restore_uregs(struct uretprobe_instance *ri,
148                                    struct pt_regs *regs)
149 {
150         struct us_priv *priv = (struct us_priv *)ri->data;
151
152         memcpy(regs, ri->data, sizeof(*regs));
153         swap_set_arg(regs, 0, priv->arg0);
154         swap_set_arg(regs, 1, priv->arg1);
155         swap_set_ret_addr(regs, priv->raddr);
156 #ifndef CONFIG_ARM
157         /* need to do it only on x86 */
158         regs->EREG(ip) -= 1;
159 #endif /* !CONFIG_ARM */
160         /* we have just restored the registers => no need to do it in
161          * trampoline_uprobe_handler */
162         ri->ret_addr = NULL;
163 }
164
165 static inline void print_regs(const char *prefix, struct pt_regs *regs,
166                               struct uretprobe_instance *ri, struct hd_t *hd)
167 {
168         struct dentry *dentry = preload_pd_get_dentry(hd);
169
170 #ifdef CONFIG_ARM
171         printk(PRELOAD_PREFIX "%s[%d/%d] %s (%d) %s addr(%08lx), "
172                "r0(%08lx), r1(%08lx), r2(%08lx), r3(%08lx), "
173                "r4(%08lx), r5(%08lx), r6(%08lx), r7(%08lx), "
174                "sp(%08lx), lr(%08lx), pc(%08lx)\n",
175                current->comm, current->tgid, current->pid,
176                dentry != NULL ? (char *)(dentry->d_name.name) :
177                                 (char *)("NULL"),
178                (int)preload_pd_get_state(hd),
179                prefix, (unsigned long)ri->rp->up.addr,
180                regs->ARM_r0, regs->ARM_r1, regs->ARM_r2, regs->ARM_r3,
181                regs->ARM_r4, regs->ARM_r5, regs->ARM_r6, regs->ARM_r7,
182                regs->ARM_sp, regs->ARM_lr, regs->ARM_pc);
183 #else /* !CONFIG_ARM */
184         printk(PRELOAD_PREFIX "%s[%d/%d] %s (%d) %s addr(%08lx), "
185                "ip(%08lx), arg0(%08lx), arg1(%08lx), raddr(%08lx)\n",
186                current->comm, current->tgid, current->pid,
187                dentry != NULL ? (char *)(dentry->d_name.name) :
188                                 (char *)("NULL"),
189                (int)preload_pd_get_state(hd),
190                prefix, (unsigned long)ri->rp->up.addr,
191                regs->EREG(ip), swap_get_arg(regs, 0), swap_get_arg(regs, 1),
192                swap_get_ret_addr(regs));
193 #endif /* CONFIG_ARM */
194 }
195
196 static inline unsigned long __get_r_debug_off(struct vm_area_struct *linker_vma)
197 {
198         unsigned long start_addr;
199         unsigned long offset = preload_debugfs_r_debug_offset();
200
201         if (linker_vma == NULL)
202                 return 0;
203
204         start_addr = linker_vma->vm_start;
205
206         return (offset ? start_addr + offset : 0);
207 }
208
209 static struct vm_area_struct *__get_linker_vma(struct task_struct *task)
210 {
211         struct vm_area_struct *vma = NULL;
212         struct bin_info *ld_info;
213
214         ld_info = preload_storage_get_linker_info();
215         if (ld_info == NULL) {
216                 printk(PRELOAD_PREFIX "Cannot get linker info [%u %u %s]!\n",
217                        task->tgid, task->pid, task->comm);
218                 return NULL;
219         }
220
221         for (vma = task->mm->mmap; vma; vma = vma->vm_next) {
222                 if (vma->vm_file && vma->vm_flags & VM_EXEC
223                     && vma->vm_file->f_dentry == ld_info->dentry) {
224                                 preload_storage_put_linker_info(ld_info);
225                                 return vma;
226                 }
227         }
228
229         preload_storage_put_linker_info(ld_info);
230         return NULL;
231 }
232
233 static inline struct vm_area_struct *__get_vma_by_addr(struct task_struct *task,
234                                                         unsigned long caller_addr)
235 {
236         struct vm_area_struct *vma = NULL;
237
238         if (task->mm == NULL)
239                 return NULL;
240         vma = find_vma_intersection(task->mm, caller_addr, caller_addr + 1);
241
242         return vma;
243 }
244
245
246
247
248
249
250
251
252
253 static bool __is_proc_mmap_mappable(struct task_struct *task)
254 {
255         struct vm_area_struct *linker_vma = __get_linker_vma(task);
256         struct sspt_proc *proc;
257         unsigned long r_debug_addr;
258         unsigned int state;
259         enum { r_state_offset = sizeof(int) + sizeof(void *) + sizeof(long) };
260
261         if (linker_vma == NULL)
262                 return false;
263
264         r_debug_addr = __get_r_debug_off(linker_vma);
265         if (r_debug_addr == 0)
266                 return false;
267
268         r_debug_addr += r_state_offset;
269         proc = sspt_proc_by_task(task);
270         if (proc)
271                 proc->r_state_addr = r_debug_addr;
272
273         if (get_user(state, (unsigned long *)r_debug_addr))
274                 return false;
275
276         return !state;
277 }
278
279 static bool __should_we_preload_handlers(struct task_struct *task,
280                                          struct pt_regs *regs)
281 {
282         unsigned long caller_addr = get_regs_ret_func(regs);
283         struct vm_area_struct *cvma = __get_vma_by_addr(current, caller_addr);
284
285         if (!__is_proc_mmap_mappable(task) ||
286             ((cvma != NULL) && (cvma->vm_file != NULL) &&
287             (cvma->vm_file->f_path.dentry != NULL) &&
288             preload_control_check_dentry_is_ignored(cvma->vm_file->f_path.dentry)))
289                 return false;
290
291         return true;
292 }
293
294
295
296
297
298 struct mmap_priv {
299         struct dentry *dentry;
300 };
301
302 static inline bool check_prot(unsigned long prot)
303 {
304         return !!((prot & PROT_READ) && (prot & PROT_EXEC));
305 }
306
307 static int mmap_entry_handler(struct kretprobe_instance *ri,
308                               struct pt_regs *regs)
309 {
310         struct file *file = (struct file *)swap_get_karg(regs, 0);
311         unsigned long prot = swap_get_karg(regs, 3);
312         struct mmap_priv *priv = (struct mmap_priv *)ri->data;
313         struct task_struct *task = current->group_leader;
314         struct dentry *dentry, *loader_dentry;
315         struct pd_t *pd;
316         struct hd_t *hd;
317         struct sspt_proc *proc;
318
319         priv->dentry = NULL;
320         if (!check_prot(prot))
321                 return 0;
322
323         if (!file)
324                 return 0;
325
326         dentry = file->f_dentry;
327         if (dentry == NULL)
328                 return 0;
329
330         loader_dentry = preload_debugfs_get_loader_dentry();
331         if (dentry == loader_dentry) {
332                 priv->dentry = loader_dentry;
333                 return 0;
334         }
335
336         proc = sspt_proc_by_task(task);
337         if (!proc)
338                 return 0;
339
340         pd = preload_pd_get(proc);
341         if (pd == NULL) {
342                 printk(PRELOAD_PREFIX "%d: No process data! Current %d %s\n",
343                        __LINE__, current->tgid, current->comm);
344                 return 0;
345         }
346
347         hd = preload_pd_get_hd(pd, dentry);
348         if (hd != NULL)
349                 priv->dentry = preload_pd_get_dentry(hd);
350
351         return 0;
352 }
353
354 static int mmap_ret_handler(struct kretprobe_instance *ri,
355                             struct pt_regs *regs)
356 {
357         struct mmap_priv *priv = (struct mmap_priv *)ri->data;
358         struct task_struct *task = current->group_leader;
359         struct pd_t *pd;
360         struct hd_t *hd;
361         struct sspt_proc *proc;
362         struct dentry *loader_dentry;
363         unsigned long vaddr;
364
365         if (!task->mm)
366                 return 0;
367
368         if (priv->dentry == NULL)
369                 return 0;
370
371         vaddr = (unsigned long)regs_return_value(regs);
372         if (IS_ERR_VALUE(vaddr))
373                 return 0;
374
375         proc = sspt_proc_by_task(task);
376         if (!proc)
377                 return 0;
378
379         pd = preload_pd_get(proc);
380         if (pd == NULL) {
381                 printk(PRELOAD_PREFIX "%d: No process data! Current %d %s\n",
382                        __LINE__, current->tgid, current->comm);
383                 return 0;
384         }
385
386         loader_dentry = preload_debugfs_get_loader_dentry();
387         if (priv->dentry == loader_dentry)
388                 preload_pd_set_loader_base(pd, vaddr);
389
390
391         hd = preload_pd_get_hd(pd, priv->dentry);
392         if (hd != NULL)
393                 preload_pd_set_handlers_base(hd, vaddr);
394
395         return 0;
396 }
397
398 static struct kretprobe mmap_rp = {
399         .kp.symbol_name = "do_mmap_pgoff",
400         .data_size = sizeof(struct mmap_priv),
401         .entry_handler = mmap_entry_handler,
402         .handler = mmap_ret_handler
403 };
404
405 static void preload_start_cb(void)
406 {
407         int res;
408
409         res = swap_register_kretprobe(&mmap_rp);
410         if (res != 0)
411                 printk(KERN_ERR PRELOAD_PREFIX "Registering do_mmap_pgoff probe failed\n");
412 }
413
414 static void preload_stop_cb(void)
415 {
416         swap_unregister_kretprobe(&mmap_rp);
417 }
418
419 static unsigned long __not_loaded_entry(struct uretprobe_instance *ri,
420                                         struct pt_regs *regs,
421                                         struct pd_t *pd, struct hd_t *hd)
422 {
423         char __user *path = NULL;
424         unsigned long vaddr = 0;
425         unsigned long base;
426
427         /* if linker is still doing its work, we do nothing */
428         if (!__should_we_preload_handlers(current, regs))
429                 return 0;
430
431         base = preload_pd_get_loader_base(pd);
432         if (base == 0)
433                 return 0;   /* loader isn't mapped */
434
435         /* jump to loader code if ready */
436         vaddr = base + preload_debugfs_get_loader_offset();
437         if (vaddr) {
438                 /* save original regs state */
439                 __save_uregs(ri, regs);
440                 print_regs("ORIG", regs, ri, hd);
441
442                 path = preload_pd_get_path(pd, hd);
443
444                 /* set dlopen args: filename, flags */
445                 swap_set_arg(regs, 0, (unsigned long)path/*swap_get_stack_ptr(regs)*/);
446                 swap_set_arg(regs, 1, 2 /* RTLD_NOW */);
447
448                 /* do the jump to dlopen */
449                 __prepare_ujump(ri, regs, vaddr);
450                 /* set new state */
451                 preload_pd_set_state(hd, LOADING);
452         }
453
454         return vaddr;
455 }
456
457 static void __loading_ret(struct uretprobe_instance *ri, struct pt_regs *regs,
458                           struct pd_t *pd, struct hd_t *hd)
459 {
460         struct us_priv *priv = (struct us_priv *)ri->data;
461         unsigned long vaddr = 0;
462
463         /* check if preloading has been completed */
464         vaddr = preload_pd_get_loader_base(pd) +
465                 preload_debugfs_get_loader_offset();
466         if (vaddr && (priv->origin == vaddr)) {
467                 preload_pd_set_handle(hd,
468                                       (void __user *)regs_return_value(regs));
469
470                 /* restore original regs state */
471                 __restore_uregs(ri, regs);
472                 print_regs("REST", regs, ri, hd);
473                 /* check if preloading done */
474
475                 if (preload_pd_get_handle(hd)) {
476                         preload_pd_set_state(hd, LOADED);
477                 } else {
478                         preload_pd_dec_attempts(hd);
479                         preload_pd_set_state(hd, FAILED);
480                 }
481         }
482 }
483
484 static void __failed_ret(struct uretprobe_instance *ri, struct pt_regs *regs,
485                          struct pd_t *pd, struct hd_t *hd)
486 {
487         if (preload_pd_get_attempts(hd))
488                 preload_pd_set_state(hd, NOT_LOADED);
489 }
490
491
492
493 unsigned long preload_not_loaded_entry(struct uretprobe_instance *ri,
494                                        struct pt_regs *regs, struct pd_t *pd,
495                                        struct hd_t *hd)
496 {
497         return __not_loaded_entry(ri, regs, pd, hd);
498 }
499
500 void preload_loading_ret(struct uretprobe_instance *ri, struct pt_regs *regs,
501                          struct pd_t *pd, struct hd_t *hd)
502 {
503         __loading_ret(ri, regs, pd, hd);
504 }
505
506 void preload_failed_ret(struct uretprobe_instance *ri, struct pt_regs *regs,
507                         struct pd_t *pd, struct hd_t *hd)
508 {
509         __failed_ret(ri, regs, pd, hd);
510 }
511
512 void preload_module_prepare_ujump(struct uretprobe_instance *ri,
513                                   struct pt_regs *regs, unsigned long addr)
514 {
515         __prepare_ujump(ri, regs, addr);
516 }
517
518 void preload_set_rp_data_size(struct uretprobe *rp)
519 {
520         rp->data_size = sizeof(struct us_priv);
521 }
522
523 void preload_set_priv_origin(struct uretprobe_instance *ri, unsigned long addr)
524 {
525         struct us_priv *priv = (struct us_priv *)ri->data;
526
527         priv->origin = addr;
528 }
529
530 unsigned long preload_get_priv_origin(struct uretprobe_instance *ri)
531 {
532         struct us_priv *priv = (struct us_priv *)ri->data;
533
534     return priv->origin;
535 }
536
537
538 int preload_set(void)
539 {
540         if (preload_module_is_running())
541                 return -EBUSY;
542
543         return 0;
544 }
545
546 void preload_unset(void)
547 {
548         swap_unregister_kretprobe(&mmap_rp);
549         /*module_put(THIS_MODULE);*/
550         preload_module_set_not_ready();
551
552 }
553
554
555 static int preload_module_init(void)
556 {
557         int ret;
558
559         ret = preload_debugfs_init();
560         if (ret)
561                 goto out_err;
562
563         ret = preload_storage_init();
564         if (ret)
565                 goto exit_debugfs;
566
567         ret = preload_pd_init();
568         if (ret)
569                 goto exit_storage;
570
571         /* TODO do not forget to remove set (it is just for debugging) */
572         ret = preload_set();
573         if (ret)
574                 goto exit_pd;
575
576         ret = preload_control_init();
577         if (ret)
578                 goto exit_set;
579
580         ret = preload_threads_init();
581         if (ret)
582                 goto exit_control;
583
584         ret = register_preload_probes();
585         if (ret)
586                 goto exit_threads;
587
588         __preload_cbs_start_h = us_manager_reg_cb(START_CB, preload_start_cb);
589         if (__preload_cbs_start_h < 0)
590                 goto exit_start_cb;
591
592         __preload_cbs_stop_h = us_manager_reg_cb(STOP_CB, preload_stop_cb);
593         if (__preload_cbs_stop_h < 0)
594                 goto exit_stop_cb;
595
596         return 0;
597
598 exit_stop_cb:
599         us_manager_unreg_cb(__preload_cbs_start_h);
600
601 exit_start_cb:
602         unregister_preload_probes();
603
604 exit_threads:
605         preload_threads_exit();
606
607 exit_control:
608         preload_control_exit();
609
610 exit_set:
611         preload_unset();
612
613 exit_pd:
614         preload_pd_uninit();
615
616 exit_storage:
617         preload_storage_exit();
618
619 exit_debugfs:
620         preload_debugfs_exit();
621
622 out_err:
623         return ret;
624 }
625
626 static void preload_module_exit(void)
627 {
628         int balance;
629
630         us_manager_unreg_cb(__preload_cbs_start_h);
631         us_manager_unreg_cb(__preload_cbs_stop_h);
632         unregister_preload_probes();
633         preload_threads_exit();
634         preload_control_exit();
635         preload_unset();
636         preload_pd_uninit();
637         preload_storage_exit();
638         preload_debugfs_exit();
639
640         balance = atomic_read(&dentry_balance);
641         atomic_set(&dentry_balance, 0);
642
643         WARN(balance, "Bad GET/PUT dentry balance: %d\n", balance);
644 }
645
646 SWAP_LIGHT_INIT_MODULE(NULL, preload_module_init, preload_module_exit,
647                        NULL, NULL);
648
649 MODULE_LICENSE("GPL");
650 MODULE_DESCRIPTION("SWAP Preload Module");
651 MODULE_AUTHOR("Vasiliy Ulyanov <v.ulyanov@samsung.com>"
652               "Alexander Aksenov <a.aksenov@samsung.com>");