Merge branch 'tizen_2.4_dev' into tizen
[kernel/swap-modules.git] / us_manager / sspt / sspt_proc.c
1 /*
2  *  Dynamic Binary Instrumentation Module based on KProbes
3  *  modules/driver/sspt/sspt_proc.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 <v.cherkashin@samsung.com>
22  *
23  */
24
25 #include "sspt.h"
26 #include "sspt_proc.h"
27 #include "sspt_page.h"
28 #include "sspt_feature.h"
29 #include "sspt_filter.h"
30 #include "../pf/proc_filters.h"
31 #include <linux/module.h>
32 #include <linux/slab.h>
33 #include <linux/list.h>
34 #include <kprobe/swap_ktd.h>
35 #include <us_manager/us_slot_manager.h>
36
37 static LIST_HEAD(proc_probes_list);
38 static DEFINE_RWLOCK(sspt_proc_rwlock);
39
40
41 struct list_head *sspt_proc_list()
42 {
43         return &proc_probes_list;
44 }
45
46 /**
47  * @brief Global read lock for sspt_proc
48  *
49  * @return Void
50  */
51 void sspt_proc_read_lock(void)
52 {
53         read_lock(&sspt_proc_rwlock);
54 }
55
56 /**
57  * @brief Global read unlock for sspt_proc
58  *
59  * @return Void
60  */
61 void sspt_proc_read_unlock(void)
62 {
63         read_unlock(&sspt_proc_rwlock);
64 }
65
66 /**
67  * @brief Global write lock for sspt_proc
68  *
69  * @return Void
70  */
71 void sspt_proc_write_lock(void)
72 {
73         write_lock(&sspt_proc_rwlock);
74 }
75
76 /**
77  * @brief Global write unlock for sspt_proc
78  *
79  * @return Void
80  */
81 void sspt_proc_write_unlock(void)
82 {
83         write_unlock(&sspt_proc_rwlock);
84 }
85
86 struct ktd_proc {
87         struct sspt_proc *proc;
88         spinlock_t lock;
89 };
90
91 static void ktd_init(struct task_struct *task, void *data)
92 {
93         struct ktd_proc *kproc = (struct ktd_proc *)data;
94
95         kproc->proc = NULL;
96         spin_lock_init(&kproc->lock);
97 }
98
99 static void ktd_exit(struct task_struct *task, void *data)
100 {
101         struct ktd_proc *kproc = (struct ktd_proc *)data;
102
103         WARN_ON(kproc->proc);
104 }
105
106 struct ktask_data ktd = {
107         .init = ktd_init,
108         .exit = ktd_exit,
109         .size = sizeof(struct ktd_proc),
110 };
111
112 static struct ktd_proc *kproc_by_task(struct task_struct *task)
113 {
114         return (struct ktd_proc *)swap_ktd(&ktd, task);
115 }
116
117 int sspt_proc_init(void)
118 {
119         return swap_ktd_reg(&ktd);
120 }
121
122 void sspt_proc_uninit(void)
123 {
124         swap_ktd_unreg(&ktd);
125 }
126
127 void sspt_change_leader(struct task_struct *prev, struct task_struct *next)
128 {
129         struct ktd_proc *prev_kproc;
130
131         prev_kproc = kproc_by_task(prev);
132         spin_lock(&prev_kproc->lock);
133         if (prev_kproc->proc) {
134                 struct ktd_proc *next_kproc;
135
136                 next_kproc = kproc_by_task(next);
137                 get_task_struct(next);
138
139                 /* Change the keeper sspt_proc */
140                 BUG_ON(next_kproc->proc);
141
142                 spin_lock(&next_kproc->lock);
143                 next_kproc->proc = prev_kproc->proc;
144                 prev_kproc->proc = NULL;
145                 spin_unlock(&next_kproc->lock);
146
147                 /* Set new the task leader to sspt_proc */
148                 next_kproc->proc->leader = next;
149
150                 put_task_struct(prev);
151         }
152         spin_unlock(&prev_kproc->lock);
153 }
154
155 static void sspt_reset_proc(struct task_struct *task)
156 {
157         struct ktd_proc *kproc;
158
159         kproc = kproc_by_task(task->group_leader);
160         spin_lock(&kproc->lock);
161         kproc->proc = NULL;
162         spin_unlock(&kproc->lock);
163 }
164
165
166
167
168
169 static struct sspt_proc *sspt_proc_create(struct task_struct *leader)
170 {
171         struct sspt_proc *proc = kzalloc(sizeof(*proc), GFP_KERNEL);
172
173         if (proc) {
174                 proc->feature = sspt_create_feature();
175                 if (proc->feature == NULL) {
176                         kfree(proc);
177                         return NULL;
178                 }
179
180                 INIT_LIST_HEAD(&proc->list);
181                 INIT_LIST_HEAD(&proc->files.head);
182                 init_rwsem(&proc->files.sem);
183                 proc->tgid = leader->tgid;
184                 proc->leader = leader;
185                 /* FIXME: change the task leader */
186                 proc->sm = create_sm_us(leader);
187                 mutex_init(&proc->filters.mtx);
188                 INIT_LIST_HEAD(&proc->filters.head);
189                 atomic_set(&proc->usage, 1);
190
191                 get_task_struct(proc->leader);
192
193                 proc->suspect.after_exec = 1;
194                 proc->suspect.after_fork = 0;
195         }
196
197         return proc;
198 }
199
200 static void sspt_proc_free(struct sspt_proc *proc)
201 {
202         put_task_struct(proc->leader);
203         free_sm_us(proc->sm);
204         sspt_destroy_feature(proc->feature);
205         kfree(proc);
206 }
207
208 /**
209  * @brief Remove sspt_proc struct
210  *
211  * @param proc remove object
212  * @return Void
213  */
214
215 /* called with sspt_proc_write_lock() */
216 void sspt_proc_cleanup(struct sspt_proc *proc)
217 {
218         struct sspt_file *file, *n;
219
220         sspt_proc_del_all_filters(proc);
221
222         down_write(&proc->files.sem);
223         list_for_each_entry_safe(file, n, &proc->files.head, list) {
224                 list_del(&file->list);
225                 sspt_file_free(file);
226         }
227         up_write(&proc->files.sem);
228
229         sspt_destroy_feature(proc->feature);
230
231         free_sm_us(proc->sm);
232         sspt_reset_proc(proc->leader);
233         sspt_proc_put(proc);
234 }
235
236 struct sspt_proc *sspt_proc_get(struct sspt_proc *proc)
237 {
238         atomic_inc(&proc->usage);
239
240         return proc;
241 }
242
243 void sspt_proc_put(struct sspt_proc *proc)
244 {
245         if (atomic_dec_and_test(&proc->usage)) {
246                 if (proc->__mm) {
247                         mmput(proc->__mm);
248                         proc->__mm = NULL;
249                 }
250                 if (proc->__task) {
251                         put_task_struct(proc->__task);
252                         proc->__task = NULL;
253                 }
254
255                 WARN_ON(kproc_by_task(proc->leader)->proc);
256
257                 put_task_struct(proc->leader);
258                 kfree(proc);
259         }
260 }
261 EXPORT_SYMBOL_GPL(sspt_proc_put);
262
263 struct sspt_proc *sspt_proc_by_task(struct task_struct *task)
264 {
265         return kproc_by_task(task->group_leader)->proc;
266 }
267 EXPORT_SYMBOL_GPL(sspt_proc_by_task);
268
269 struct sspt_proc *sspt_proc_get_by_task(struct task_struct *task)
270 {
271         struct ktd_proc *kproc = kproc_by_task(task->group_leader);
272         struct sspt_proc *proc;
273
274         spin_lock(&kproc->lock);
275         proc = kproc->proc;
276         if (proc)
277                 sspt_proc_get(proc);
278         spin_unlock(&kproc->lock);
279
280         return proc;
281 }
282 EXPORT_SYMBOL_GPL(sspt_proc_get_by_task);
283
284 /**
285  * @brief Call func() on each proc (no lock)
286  *
287  * @param func Callback
288  * @param data Data for callback
289  * @return Void
290  */
291 void on_each_proc_no_lock(void (*func)(struct sspt_proc *, void *), void *data)
292 {
293         struct sspt_proc *proc, *tmp;
294
295         list_for_each_entry_safe(proc, tmp, &proc_probes_list, list) {
296                 func(proc, data);
297         }
298 }
299
300 /**
301  * @brief Call func() on each proc
302  *
303  * @param func Callback
304  * @param data Data for callback
305  * @return Void
306  */
307 void on_each_proc(void (*func)(struct sspt_proc *, void *), void *data)
308 {
309         sspt_proc_read_lock();
310         on_each_proc_no_lock(func, data);
311         sspt_proc_read_unlock();
312 }
313 EXPORT_SYMBOL_GPL(on_each_proc);
314
315 /**
316  * @brief Get sspt_proc by task or create sspt_proc
317  *
318  * @param task Pointer on the task_struct struct
319  * @param priv Private data
320  * @return Pointer on the sspt_proc struct
321  */
322 struct sspt_proc *sspt_proc_get_by_task_or_new(struct task_struct *task)
323 {
324         static DEFINE_MUTEX(local_mutex);
325         struct ktd_proc *kproc;
326         struct sspt_proc *proc;
327         struct task_struct *leader = task->group_leader;
328
329         kproc = kproc_by_task(leader);
330         if (kproc->proc)
331                 goto out;
332
333         proc = sspt_proc_create(leader);
334
335         spin_lock(&kproc->lock);
336         if (kproc->proc == NULL) {
337                 sspt_proc_get(proc);
338                 kproc->proc = proc;
339                 proc = NULL;
340
341                 sspt_proc_write_lock();
342                 list_add(&kproc->proc->list, &proc_probes_list);
343                 sspt_proc_write_unlock();
344         }
345         spin_unlock(&kproc->lock);
346
347         if (proc)
348                 sspt_proc_free(proc);
349
350 out:
351         return kproc->proc;
352 }
353
354 /**
355  * @brief Check sspt_proc on empty
356  *
357  * @return Pointer on the sspt_proc struct
358  */
359 void sspt_proc_check_empty(void)
360 {
361         WARN_ON(!list_empty(&proc_probes_list));
362 }
363
364 static void sspt_proc_add_file(struct sspt_proc *proc, struct sspt_file *file)
365 {
366         down_write(&proc->files.sem);
367         list_add(&file->list, &proc->files.head);
368         file->proc = proc;
369         up_write(&proc->files.sem);
370 }
371
372 /**
373  * @brief Get sspt_file from sspt_proc by dentry or new
374  *
375  * @param proc Pointer on the sspt_proc struct
376  * @param dentry Dentry of file
377  * @return Pointer on the sspt_file struct
378  */
379 struct sspt_file *sspt_proc_find_file_or_new(struct sspt_proc *proc,
380                                              struct dentry *dentry)
381 {
382         struct sspt_file *file;
383
384         file = sspt_proc_find_file(proc, dentry);
385         if (file == NULL) {
386                 file = sspt_file_create(dentry, 10);
387                 if (file)
388                         sspt_proc_add_file(proc, file);
389         }
390
391         return file;
392 }
393
394 /**
395  * @brief Get sspt_file from sspt_proc by dentry
396  *
397  * @param proc Pointer on the sspt_proc struct
398  * @param dentry Dentry of file
399  * @return Pointer on the sspt_file struct
400  */
401 struct sspt_file *sspt_proc_find_file(struct sspt_proc *proc,
402                                       struct dentry *dentry)
403 {
404         struct sspt_file *file;
405
406         down_read(&proc->files.sem);
407         list_for_each_entry(file, &proc->files.head, list) {
408                 if (dentry == file->dentry)
409                         goto unlock;
410         }
411         file = NULL;
412
413 unlock:
414         up_read(&proc->files.sem);
415
416         return file;
417 }
418
419 /**
420  * @brief Install probes on the page to monitored process
421  *
422  * @param proc Pointer on the sspt_proc struct
423  * @param page_addr Page address
424  * @return Void
425  */
426 void sspt_proc_install_page(struct sspt_proc *proc, unsigned long page_addr)
427 {
428         struct mm_struct *mm = proc->leader->mm;
429         struct vm_area_struct *vma;
430
431         vma = find_vma_intersection(mm, page_addr, page_addr + 1);
432         if (vma && check_vma(vma)) {
433                 struct dentry *dentry = vma->vm_file->f_path.dentry;
434                 struct sspt_file *file = sspt_proc_find_file(proc, dentry);
435                 if (file) {
436                         struct sspt_page *page;
437
438                         sspt_file_set_mapping(file, vma);
439
440                         page = sspt_find_page_mapped(file, page_addr);
441                         if (page)
442                                 sspt_register_page(page, file);
443                 }
444         }
445 }
446
447 /**
448  * @brief Install probes to monitored process
449  *
450  * @param proc Pointer on the sspt_proc struct
451  * @return Void
452  */
453 void sspt_proc_install(struct sspt_proc *proc)
454 {
455         struct vm_area_struct *vma;
456         struct mm_struct *mm = proc->leader->mm;
457
458         proc->first_install = 1;
459
460         for (vma = mm->mmap; vma; vma = vma->vm_next) {
461                 if (check_vma(vma)) {
462                         struct dentry *dentry = vma->vm_file->f_path.dentry;
463                         struct sspt_file *file =
464                                 sspt_proc_find_file(proc, dentry);
465                         if (file) {
466                                 sspt_file_set_mapping(file, vma);
467                                 sspt_file_install(file);
468                         }
469                 }
470         }
471 }
472
473 /**
474  * @brief Uninstall probes to monitored process
475  *
476  * @param proc Pointer on the sspt_proc struct
477  * @param task Pointer on the task_struct struct
478  * @param flag Action for probes
479  * @return Error code
480  */
481 int sspt_proc_uninstall(struct sspt_proc *proc,
482                         struct task_struct *task,
483                         enum US_FLAGS flag)
484 {
485         int err = 0;
486         struct sspt_file *file;
487
488         down_read(&proc->files.sem);
489         list_for_each_entry(file, &proc->files.head, list) {
490                 err = sspt_file_uninstall(file, task, flag);
491                 if (err != 0) {
492                         printk(KERN_INFO "ERROR sspt_proc_uninstall: err=%d\n",
493                                err);
494                         break;
495                 }
496         }
497         up_read(&proc->files.sem);
498
499         return err;
500 }
501
502 static int intersection(unsigned long start_a, unsigned long end_a,
503                         unsigned long start_b, unsigned long end_b)
504 {
505         return start_a < start_b ?
506                         end_a > start_b :
507                         start_a < end_b;
508 }
509
510 /**
511  * @brief Get sspt_file list by region (remove sspt_file from sspt_proc list)
512  *
513  * @param proc Pointer on the sspt_proc struct
514  * @param head[out] Pointer on the head list
515  * @param start Region start
516  * @param len Region length
517  * @return Error code
518  */
519 int sspt_proc_get_files_by_region(struct sspt_proc *proc,
520                                   struct list_head *head,
521                                   unsigned long start, size_t len)
522 {
523         int ret = 0;
524         struct sspt_file *file, *n;
525         unsigned long end = start + len;
526
527         down_write(&proc->files.sem);
528         list_for_each_entry_safe(file, n, &proc->files.head, list) {
529                 if (intersection(file->vm_start, file->vm_end, start, end)) {
530                         ret = 1;
531                         list_move(&file->list, head);
532                 }
533         }
534         up_write(&proc->files.sem);
535
536         return ret;
537 }
538
539 /**
540  * @brief Insert sspt_file to sspt_proc list
541  *
542  * @param proc Pointer on the sspt_proc struct
543  * @param head Pointer on the head list
544  * @return Void
545  */
546 void sspt_proc_insert_files(struct sspt_proc *proc, struct list_head *head)
547 {
548         down_write(&proc->files.sem);
549         list_splice(head, &proc->files.head);
550         up_write(&proc->files.sem);
551 }
552
553 /**
554  * @brief Add sspt_filter to sspt_proc list
555  *
556  * @param proc Pointer to sspt_proc struct
557  * @param pfg Pointer to pf_group struct
558  * @return Void
559  */
560 void sspt_proc_add_filter(struct sspt_proc *proc, struct pf_group *pfg)
561 {
562         struct sspt_filter *f;
563
564         f = sspt_filter_create(proc, pfg);
565         if (f)
566                 list_add(&f->list, &proc->filters.head);
567 }
568
569 /**
570  * @brief Remove sspt_filter from sspt_proc list
571  *
572  * @param proc Pointer to sspt_proc struct
573  * @param pfg Pointer to pf_group struct
574  * @return Void
575  */
576 void sspt_proc_del_filter(struct sspt_proc *proc, struct pf_group *pfg)
577 {
578         struct sspt_filter *fl, *tmp;
579
580         mutex_lock(&proc->filters.mtx);
581         list_for_each_entry_safe(fl, tmp, &proc->filters.head, list) {
582                 if (fl->pfg == pfg) {
583                         list_del(&fl->list);
584                         sspt_filter_free(fl);
585                 }
586         }
587         mutex_unlock(&proc->filters.mtx);
588 }
589
590 /**
591  * @brief Remove all sspt_filters from sspt_proc list
592  *
593  * @param proc Pointer to sspt_proc struct
594  * @return Void
595  */
596 void sspt_proc_del_all_filters(struct sspt_proc *proc)
597 {
598         struct sspt_filter *fl, *tmp;
599
600         mutex_lock(&proc->filters.mtx);
601         list_for_each_entry_safe(fl, tmp, &proc->filters.head, list) {
602                 list_del(&fl->list);
603                 sspt_filter_free(fl);
604         }
605         mutex_unlock(&proc->filters.mtx);
606 }
607
608 /**
609  * @brief Check if sspt_filter is already in sspt_proc list
610  *
611  * @param proc Pointer to sspt_proc struct
612  * @param pfg Pointer to pf_group struct
613  * @return Boolean
614  */
615 bool sspt_proc_is_filter_new(struct sspt_proc *proc, struct pf_group *pfg)
616 {
617         struct sspt_filter *fl;
618
619         list_for_each_entry(fl, &proc->filters.head, list)
620                 if (fl->pfg == pfg)
621                         return false;
622
623         return true;
624 }
625
626 void sspt_proc_on_each_filter(struct sspt_proc *proc,
627                               void (*func)(struct sspt_filter *, void *),
628                               void *data)
629 {
630         struct sspt_filter *fl;
631
632         list_for_each_entry(fl, &proc->filters.head, list)
633                 func(fl, data);
634 }
635
636 void sspt_proc_on_each_ip(struct sspt_proc *proc,
637                           void (*func)(struct sspt_ip *, void *), void *data)
638 {
639         struct sspt_file *file;
640
641         down_read(&proc->files.sem);
642         list_for_each_entry(file, &proc->files.head, list)
643                 sspt_file_on_each_ip(file, func, data);
644         up_read(&proc->files.sem);
645 }
646
647 static void is_send_event(struct sspt_filter *f, void *data)
648 {
649         bool *is_send = (bool *)data;
650
651         if (!*is_send && f->pfg_is_inst)
652                 *is_send = !!pfg_msg_cb_get(f->pfg);
653 }
654
655 bool sspt_proc_is_send_event(struct sspt_proc *proc)
656 {
657         bool is_send = false;
658
659         /* FIXME: add read lock (deadlock in sampler) */
660         sspt_proc_on_each_filter(proc, is_send_event, (void *)&is_send);
661
662         return is_send;
663 }
664
665
666 static struct sspt_proc_cb *proc_cb;
667
668 int sspt_proc_cb_set(struct sspt_proc_cb *cb)
669 {
670         if (cb && proc_cb)
671                 return -EBUSY;
672
673         proc_cb = cb;
674
675         return 0;
676 }
677 EXPORT_SYMBOL_GPL(sspt_proc_cb_set);
678
679 void sspt_proc_priv_create(struct sspt_proc *proc)
680 {
681         if (proc_cb && proc_cb->priv_create)
682                 proc->private_data = proc_cb->priv_create(proc);
683 }
684
685 void sspt_proc_priv_destroy(struct sspt_proc *proc)
686 {
687         if (proc->first_install && proc_cb && proc_cb->priv_destroy)
688                 proc_cb->priv_destroy(proc, proc->private_data);
689 }