3665b09c9b48912c1ba95a00a385b16a00faef87
[kernel/swap-modules.git] / us_manager / pf / pf_group.c
1 /*
2  *  SWAP uprobe manager
3  *  modules/us_manager/pf/pf_group.c
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18  *
19  * Copyright (C) Samsung Electronics, 2013
20  *
21  * 2013  Vyacheslav Cherkashin: SWAP us_manager implement
22  *
23  */
24
25
26 #include <linux/module.h>
27 #include <linux/slab.h>
28 #include <linux/list.h>
29 #include <linux/namei.h>
30 #include <linux/mman.h>
31 #include <linux/spinlock.h>
32 #include "pf_group.h"
33 #include "proc_filters.h"
34 #include "../sspt/sspt_filter.h"
35 #include "../us_manager_common.h"
36 #include <us_manager/img/img_proc.h>
37 #include <us_manager/img/img_file.h>
38 #include <us_manager/img/img_ip.h>
39 #include <us_manager/sspt/sspt_proc.h>
40 #include <us_manager/helper.h>
41 #include <task_ctx/task_ctx.h>
42
43
44 struct pf_group {
45         struct list_head list;
46         struct img_proc *i_proc;
47         struct proc_filter filter;
48         struct pfg_msg_cb *msg_cb;
49         atomic_t usage;
50
51         spinlock_t pl_lock;     /* for proc_list */
52         struct list_head proc_list;
53 };
54
55 struct pl_struct {
56         struct list_head list;
57         struct sspt_proc *proc;
58 };
59
60
61 static LIST_HEAD(pfg_list);
62 static DECLARE_RWSEM(pfg_list_sem);
63
64 static void pfg_list_rlock(void)
65 {
66         down_read(&pfg_list_sem);
67 }
68
69 static void pfg_list_runlock(void)
70 {
71         up_read(&pfg_list_sem);
72 }
73
74 static void pfg_list_wlock(void)
75 {
76         down_write(&pfg_list_sem);
77 }
78
79 static void pfg_list_wunlock(void)
80 {
81         up_write(&pfg_list_sem);
82 }
83
84
85 /* struct pl_struct */
86 static struct pl_struct *create_pl_struct(struct sspt_proc *proc)
87 {
88         struct pl_struct *pls = kmalloc(sizeof(*pls), GFP_ATOMIC);
89
90         if (pls) {
91                 INIT_LIST_HEAD(&pls->list);
92                 pls->proc = sspt_proc_get(proc);
93         }
94
95         return pls;
96 }
97
98 static void free_pl_struct(struct pl_struct *pls)
99 {
100         sspt_proc_put(pls->proc);
101         kfree(pls);
102 }
103 /* struct pl_struct */
104
105 static struct pf_group *pfg_create(void)
106 {
107         struct pf_group *pfg = kmalloc(sizeof(*pfg), GFP_ATOMIC);
108
109         if (pfg == NULL)
110                 return NULL;
111
112         pfg->i_proc = img_proc_create();
113         if (pfg->i_proc == NULL)
114                 goto create_pfg_fail;
115
116         INIT_LIST_HEAD(&pfg->list);
117         memset(&pfg->filter, 0, sizeof(pfg->filter));
118         spin_lock_init(&pfg->pl_lock);
119         INIT_LIST_HEAD(&pfg->proc_list);
120         pfg->msg_cb = NULL;
121         atomic_set(&pfg->usage, 1);
122
123         return pfg;
124
125 create_pfg_fail:
126
127         kfree(pfg);
128
129         return NULL;
130 }
131
132 static void pfg_free(struct pf_group *pfg)
133 {
134         struct pl_struct *pl, *n;
135
136         img_proc_free(pfg->i_proc);
137         free_pf(&pfg->filter);
138         list_for_each_entry_safe(pl, n, &pfg->proc_list, list) {
139                 sspt_proc_del_filter(pl->proc, pfg);
140                 free_pl_struct(pl);
141         }
142
143         kfree(pfg);
144 }
145
146 static int pfg_add_proc(struct pf_group *pfg, struct sspt_proc *proc)
147 {
148         struct pl_struct *pls;
149
150         pls = create_pl_struct(proc);
151         if (pls == NULL)
152                 return -ENOMEM;
153
154         spin_lock(&pfg->pl_lock);
155         list_add(&pls->list, &pfg->proc_list);
156         spin_unlock(&pfg->pl_lock);
157
158         return 0;
159 }
160
161 static int pfg_del_proc(struct pf_group *pfg, struct sspt_proc *proc)
162 {
163         struct pl_struct *pls, *pls_free = NULL;
164
165         spin_lock(&pfg->pl_lock);
166         list_for_each_entry(pls, &pfg->proc_list, list) {
167                 if (pls->proc == proc) {
168                         list_del(&pls->list);
169                         pls_free = pls;
170                         break;
171                 }
172         }
173         spin_unlock(&pfg->pl_lock);
174
175         if (pls_free)
176                 free_pl_struct(pls_free);
177
178         return !!pls_free;
179 }
180
181
182 /* called with pfg_list_lock held */
183 static void pfg_add_to_list(struct pf_group *pfg)
184 {
185         list_add(&pfg->list, &pfg_list);
186 }
187
188 /* called with pfg_list_lock held */
189 static void pfg_del_from_list(struct pf_group *pfg)
190 {
191         list_del(&pfg->list);
192 }
193
194
195 static void msg_info(struct sspt_filter *f, void *data)
196 {
197         if (f->pfg_is_inst == false) {
198                 struct pfg_msg_cb *cb;
199
200                 f->pfg_is_inst = true;
201
202                 cb = pfg_msg_cb_get(f->pfg);
203                 if (cb) {
204                         struct dentry *dentry;
205
206                         dentry = (struct dentry *)f->pfg->filter.priv;
207
208                         if (cb->msg_info)
209                                 cb->msg_info(f->proc->leader, dentry);
210
211                         if (cb->msg_status_info)
212                                 cb->msg_status_info(f->proc->leader);
213                 }
214         }
215 }
216
217 static void first_install(struct task_struct *task, struct sspt_proc *proc)
218 {
219         sspt_proc_priv_create(proc);
220
221         down_write(&task->mm->mmap_sem);
222         sspt_proc_on_each_filter(proc, msg_info, NULL);
223         sspt_proc_install(proc);
224         up_write(&task->mm->mmap_sem);
225 }
226
227 static void subsequent_install(struct task_struct *task,
228                                struct sspt_proc *proc, unsigned long page_addr)
229 {
230         down_write(&task->mm->mmap_sem);
231         sspt_proc_install_page(proc, page_addr);
232         up_write(&task->mm->mmap_sem);
233 }
234
235 /**
236  * @brief Get dentry struct by path
237  *
238  * @param path Path to file
239  * @return Pointer on dentry struct on NULL
240  */
241 struct dentry *dentry_by_path(const char *path)
242 {
243         struct dentry *dentry;
244 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 38)
245         struct path st_path;
246         if (kern_path(path, LOOKUP_FOLLOW, &st_path) != 0) {
247 #else /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 38) */
248         struct nameidata nd;
249         if (path_lookup(path, LOOKUP_FOLLOW, &nd) != 0) {
250 #endif /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 38) */
251                 printk("failed to lookup dentry for path %s!\n", path);
252                 return NULL;
253         }
254
255 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25)
256         dentry = nd.dentry;
257         path_release(&nd);
258 #elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 38)
259         dentry = nd.path.dentry;
260         path_put(&nd.path);
261 #else /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 38) */
262         dentry = st_path.dentry;
263         path_put(&st_path);
264 #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25) */
265         return dentry;
266 }
267 EXPORT_SYMBOL_GPL(dentry_by_path);
268
269
270 int pfg_msg_cb_set(struct pf_group *pfg, struct pfg_msg_cb *msg_cb)
271 {
272         if (pfg->msg_cb)
273                 return -EBUSY;
274
275         pfg->msg_cb = msg_cb;
276
277         return 0;
278 }
279 EXPORT_SYMBOL_GPL(pfg_msg_cb_set);
280
281 void pfg_msg_cb_reset(struct pf_group *pfg)
282 {
283         pfg->msg_cb = NULL;
284 }
285 EXPORT_SYMBOL_GPL(pfg_msg_cb_reset);
286
287 struct pfg_msg_cb *pfg_msg_cb_get(struct pf_group *pfg)
288 {
289         return pfg->msg_cb;
290 }
291
292 /**
293  * @brief Get pf_group struct by dentry
294  *
295  * @param dentry Dentry of file
296  * @param priv Private data
297  * @return Pointer on pf_group struct
298  */
299 struct pf_group *get_pf_group_by_dentry(struct dentry *dentry, void *priv)
300 {
301         struct pf_group *pfg;
302
303         pfg_list_wlock();
304         list_for_each_entry(pfg, &pfg_list, list) {
305                 if (check_pf_by_dentry(&pfg->filter, dentry)) {
306                         atomic_inc(&pfg->usage);
307                         goto unlock;
308                 }
309         }
310
311         pfg = pfg_create();
312         if (pfg == NULL)
313                 goto unlock;
314
315         set_pf_by_dentry(&pfg->filter, dentry, priv);
316
317         pfg_add_to_list(pfg);
318
319 unlock:
320         pfg_list_wunlock();
321         return pfg;
322 }
323 EXPORT_SYMBOL_GPL(get_pf_group_by_dentry);
324
325 /**
326  * @brief Get pf_group struct by TGID
327  *
328  * @param tgid Thread group ID
329  * @param priv Private data
330  * @return Pointer on pf_group struct
331  */
332 struct pf_group *get_pf_group_by_tgid(pid_t tgid, void *priv)
333 {
334         struct pf_group *pfg;
335
336         pfg_list_wlock();
337         list_for_each_entry(pfg, &pfg_list, list) {
338                 if (check_pf_by_tgid(&pfg->filter, tgid)) {
339                         atomic_inc(&pfg->usage);
340                         goto unlock;
341                 }
342         }
343
344         pfg = pfg_create();
345         if (pfg == NULL)
346                 goto unlock;
347
348         set_pf_by_tgid(&pfg->filter, tgid, priv);
349
350         pfg_add_to_list(pfg);
351
352 unlock:
353         pfg_list_wunlock();
354         return pfg;
355 }
356 EXPORT_SYMBOL_GPL(get_pf_group_by_tgid);
357
358 /**
359  * @brief Get pf_group struct by comm
360  *
361  * @param comm Task comm
362  * @param priv Private data
363  * @return Pointer on pf_group struct
364  */
365 struct pf_group *get_pf_group_by_comm(char *comm, void *priv)
366 {
367         int ret;
368         struct pf_group *pfg;
369
370         pfg_list_wlock();
371         list_for_each_entry(pfg, &pfg_list, list) {
372                 if (check_pf_by_comm(&pfg->filter, comm)) {
373                         atomic_inc(&pfg->usage);
374                         goto unlock;
375                 }
376         }
377
378         pfg = pfg_create();
379         if (pfg == NULL)
380                 goto unlock;
381
382         ret = set_pf_by_comm(&pfg->filter, comm, priv);
383         if (ret) {
384                 printk(KERN_ERR "ERROR: set_pf_by_comm, ret=%d\n", ret);
385                 pfg_free(pfg);
386                 pfg = NULL;
387                 goto unlock;
388         }
389
390         pfg_add_to_list(pfg);
391 unlock:
392         pfg_list_wunlock();
393         return pfg;
394 }
395 EXPORT_SYMBOL_GPL(get_pf_group_by_comm);
396
397 /**
398  * @brief Get pf_group struct for each process
399  *
400  * @param priv Private data
401  * @return Pointer on pf_group struct
402  */
403 struct pf_group *get_pf_group_dumb(void *priv)
404 {
405         struct pf_group *pfg;
406
407         pfg_list_wlock();
408         list_for_each_entry(pfg, &pfg_list, list) {
409                 if (check_pf_dumb(&pfg->filter)) {
410                         atomic_inc(&pfg->usage);
411                         goto unlock;
412                 }
413         }
414
415         pfg = pfg_create();
416         if (pfg == NULL)
417                 goto unlock;
418
419         set_pf_dumb(&pfg->filter, priv);
420
421         pfg_add_to_list(pfg);
422
423 unlock:
424         pfg_list_wunlock();
425         return pfg;
426 }
427 EXPORT_SYMBOL_GPL(get_pf_group_dumb);
428
429 /**
430  * @brief Put pf_group struct
431  *
432  * @param pfg Pointer to the pf_group struct
433  * @return Void
434  */
435 void put_pf_group(struct pf_group *pfg)
436 {
437         if (atomic_dec_and_test(&pfg->usage)) {
438                 pfg_list_wlock();
439                 pfg_del_from_list(pfg);
440                 pfg_list_wunlock();
441
442                 pfg_free(pfg);
443         }
444 }
445 EXPORT_SYMBOL_GPL(put_pf_group);
446
447 /**
448  * @brief Register prober for pf_grpup struct
449  *
450  * @param pfg Pointer to the pf_group struct
451  * @param dentry Dentry of file
452  * @param offset Function offset
453  * @param probe_info Pointer to the related probe_info struct
454  * @return Error code
455  */
456 int pf_register_probe(struct pf_group *pfg, struct dentry *dentry,
457                       unsigned long offset, struct probe_desc *pd)
458 {
459         return img_proc_add_ip(pfg->i_proc, dentry, offset, pd);
460 }
461 EXPORT_SYMBOL_GPL(pf_register_probe);
462
463 /**
464  * @brief Unregister prober from pf_grpup struct
465  *
466  * @param pfg Pointer to the pf_group struct
467  * @param dentry Dentry of file
468  * @param offset Function offset
469  * @return Error code
470  */
471 int pf_unregister_probe(struct pf_group *pfg, struct dentry *dentry,
472                         unsigned long offset, struct probe_desc *pd)
473 {
474         return img_proc_del_ip(pfg->i_proc, dentry, offset, pd);
475 }
476 EXPORT_SYMBOL_GPL(pf_unregister_probe);
477
478 static int check_task_on_filters(struct task_struct *task)
479 {
480         int ret = 0;
481         struct pf_group *pfg;
482
483         pfg_list_rlock();
484         list_for_each_entry(pfg, &pfg_list, list) {
485                 if (check_task_f(&pfg->filter, task)) {
486                         ret = 1;
487                         goto unlock;
488                 }
489         }
490
491 unlock:
492         pfg_list_runlock();
493         return ret;
494 }
495
496 enum pf_inst_flag {
497         PIF_NONE,
498         PIF_FIRST,
499         PIF_SECOND,
500         PIF_ADD_PFG
501 };
502
503 static enum pf_inst_flag pfg_check_task(struct task_struct *task)
504 {
505         struct pf_group *pfg;
506         struct sspt_proc *proc = NULL;
507         enum pf_inst_flag flag = PIF_NONE;
508
509         pfg_list_rlock();
510         list_for_each_entry(pfg, &pfg_list, list) {
511                 if (check_task_f(&pfg->filter, task) == NULL)
512                         continue;
513
514                 if (proc == NULL)
515                         proc = sspt_proc_by_task(task);
516
517                 if (proc) {
518                         flag = flag == PIF_NONE ? PIF_SECOND : flag;
519                 } else if (task->tgid == task->pid) {
520                         proc = sspt_proc_get_by_task_or_new(task);
521                         if (proc == NULL) {
522                                 printk(KERN_ERR "cannot create sspt_proc\n");
523                                 break;
524                         }
525                         flag = PIF_FIRST;
526                 }
527
528                 if (proc) {
529                         mutex_lock(&proc->filters.mtx);
530                                 if (sspt_proc_is_filter_new(proc, pfg)) {
531                                         img_proc_copy_to_sspt(pfg->i_proc, proc);
532                                         sspt_proc_add_filter(proc, pfg);
533                                         pfg_add_proc(pfg, proc);
534                                         flag = flag == PIF_FIRST ? flag : PIF_ADD_PFG;
535                         }
536                         mutex_unlock(&proc->filters.mtx);
537                 }
538         }
539         pfg_list_runlock();
540
541         return flag;
542 }
543
544 static void pfg_all_del_proc(struct sspt_proc *proc)
545 {
546         struct pf_group *pfg;
547
548         pfg_list_rlock();
549         list_for_each_entry(pfg, &pfg_list, list)
550                 pfg_del_proc(pfg, proc);
551         pfg_list_runlock();
552 }
553
554 /**
555  * @brief Check task and install probes on demand
556  *
557  * @prarm task Pointer on the task_struct struct
558  * @return Void
559  */
560 void check_task_and_install(struct task_struct *task)
561 {
562         struct sspt_proc *proc;
563         enum pf_inst_flag flag;
564
565         flag = pfg_check_task(task);
566         switch (flag) {
567         case PIF_FIRST:
568         case PIF_ADD_PFG:
569                 proc = sspt_proc_by_task(task);
570                 if (proc)
571                         first_install(task, proc);
572                 break;
573
574         case PIF_NONE:
575         case PIF_SECOND:
576                 break;
577         }
578 }
579
580 /**
581  * @brief Check task and install probes on demand
582  *
583  * @prarm task Pointer on the task_struct struct
584  * @param page_addr Page fault address
585  * @return Void
586  */
587 void call_page_fault(struct task_struct *task, unsigned long page_addr)
588 {
589         struct sspt_proc *proc;
590         enum pf_inst_flag flag;
591
592         flag = pfg_check_task(task);
593         switch (flag) {
594         case PIF_FIRST:
595         case PIF_ADD_PFG:
596                 proc = sspt_proc_by_task(task);
597                 if (proc)
598                         first_install(task, proc);
599                 break;
600
601         case PIF_SECOND:
602                 proc = sspt_proc_by_task(task);
603                 if (proc)
604                         subsequent_install(task, proc, page_addr);
605                 break;
606
607         case PIF_NONE:
608                 break;
609         }
610 }
611
612 /**
613  * @brief Uninstall probes from the sspt_proc struct
614  *
615  * @prarm proc Pointer on the sspt_proc struct
616  * @return Void
617  */
618
619 /* called with sspt_proc_write_lock() */
620 void uninstall_proc(struct sspt_proc *proc)
621 {
622         struct task_struct *task = proc->leader;
623
624         sspt_proc_uninstall(proc, task, US_UNREGS_PROBE);
625         sspt_proc_cleanup(proc);
626 }
627
628
629 static void mmr_from_exit(struct sspt_proc *proc)
630 {
631         BUG_ON(proc->leader != current);
632
633         sspt_proc_write_lock();
634         list_del(&proc->list);
635         sspt_proc_write_unlock();
636
637         uninstall_proc(proc);
638
639         pfg_all_del_proc(proc);
640         sspt_reset_proc(proc->leader);
641 }
642
643 static void mmr_from_exec(struct sspt_proc *proc)
644 {
645         BUG_ON(proc->leader != current);
646
647         if (proc->suspect.after_exec) {
648                 sspt_proc_uninstall(proc, proc->leader, US_UNREGS_PROBE);
649         } else {
650                 mmr_from_exit(proc);
651         }
652 }
653
654 /**
655  * @brief Remove probes from the task on demand
656  *
657  * @prarm task Pointer on the task_struct struct
658  * @return Void
659  */
660 void call_mm_release(struct task_struct *task)
661 {
662         struct sspt_proc *proc;
663
664         proc = sspt_proc_by_task(task);
665         if (proc) {
666                 if (task->flags & PF_EXITING)
667                         mmr_from_exit(proc);
668                 else
669                         mmr_from_exec(proc);
670         }
671 }
672
673 /**
674  * @brief Legacy code, it is need remove
675  *
676  * @param addr Page address
677  * @return Void
678  */
679 void uninstall_page(unsigned long addr)
680 {
681
682 }
683
684
685 static void install_cb(void *unused)
686 {
687         check_task_and_install(current);
688 }
689
690
691
692
693 struct task_item {
694         struct list_head list;
695         struct task_struct *task;
696 };
697
698 static void tasks_get(struct list_head *head)
699 {
700         struct task_item *item;
701         struct task_struct *task;
702
703         rcu_read_lock();
704         for_each_process(task) {
705                 if (task->flags & PF_KTHREAD)
706                         continue;
707
708                 if (sspt_proc_by_task(task))
709                         continue;
710
711                 /* TODO: get rid of GFP_ATOMIC */
712                 item = kmalloc(sizeof(*item), GFP_ATOMIC);
713                 if (item == NULL) {
714                         WARN(1, "out of memory\n");
715                         goto unlock;
716                 }
717
718                 get_task_struct(task);
719                 item->task = task;
720                 list_add(&item->list, head);
721         }
722
723 unlock:
724         rcu_read_unlock();
725 }
726
727 static void tasks_install_and_put(struct list_head *head)
728 {
729         struct task_item *item, *n;
730
731         list_for_each_entry_safe(item, n, head, list) {
732                 int ret;
733                 struct task_struct *task;
734
735                 task = item->task;
736                 if (!check_task_on_filters(task))
737                         goto put_task;
738
739                 ret = taskctx_run(task, install_cb, NULL);
740                 if (ret) {
741                         pr_err("cannot tracking task[%u %u %s] ret=%d\n",
742                                task->tgid, task->pid, task->comm, ret);
743                 }
744
745 put_task:
746                 put_task_struct(task);
747                 list_del(&item->list);
748                 kfree(item);
749         }
750 }
751
752 static void do_install_all(void)
753 {
754         LIST_HEAD(head);
755
756         tasks_get(&head);
757         tasks_install_and_put(&head);
758 }
759
760 /**
761  * @brief Install probes on running processes
762  *
763  * @return Void
764  */
765 void install_all(void)
766 {
767         int ret;
768
769         ret = taskctx_get();
770         if (!ret) {
771                 do_install_all();
772                 taskctx_put();
773         } else {
774                 pr_err("taskctx_get ret=%d\n", ret);
775         }
776 }
777
778 /**
779  * @brief Uninstall probes from all processes
780  *
781  * @return Void
782  */
783 void uninstall_all(void)
784 {
785         struct list_head *proc_list = sspt_proc_list();
786
787         sspt_proc_write_lock();
788         while (!list_empty(proc_list)) {
789                 struct sspt_proc *proc;
790                 proc = list_first_entry(proc_list, struct sspt_proc, list);
791
792                 list_del(&proc->list);
793
794                 sspt_proc_write_unlock();
795                 uninstall_proc(proc);
796                 sspt_proc_write_lock();
797         }
798         sspt_proc_write_unlock();
799 }
800
801 static void __do_get_proc(struct sspt_proc *proc, void *data)
802 {
803         struct task_struct *task = proc->leader;
804
805         get_task_struct(task);
806         proc->__task = task;
807         proc->__mm = get_task_mm(task);
808 }
809
810 static void __do_put_proc(struct sspt_proc *proc, void *data)
811 {
812         if (proc->__mm) {
813                 mmput(proc->__mm);
814                 proc->__mm = NULL;
815         }
816
817         if (proc->__task) {
818                 put_task_struct(proc->__task);
819                 proc->__task = NULL;
820         }
821 }
822
823 void get_all_procs(void)
824 {
825         sspt_proc_read_lock();
826         on_each_proc_no_lock(__do_get_proc, NULL);
827         sspt_proc_read_unlock();
828 }
829
830 void put_all_procs(void)
831 {
832         sspt_proc_read_lock();
833         on_each_proc_no_lock(__do_put_proc, NULL);
834         sspt_proc_read_unlock();
835 }
836
837 /**
838  * @brief For debug
839  *
840  * @param pfg Pointer to the pf_group struct
841  * @return Void
842  */
843
844 /* debug */
845 void pfg_print(struct pf_group *pfg)
846 {
847         img_proc_print(pfg->i_proc);
848 }
849 EXPORT_SYMBOL_GPL(pfg_print);
850 /* debug */