0f70788033bf79c0c3b60fa03c85919834342c01
[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
87 static void ktd_init(struct task_struct *task, void *data)
88 {
89         struct sspt_proc **pproc = (struct sspt_proc **)data;
90
91         *pproc = NULL;
92 }
93
94 static void ktd_exit(struct task_struct *task, void *data)
95 {
96         struct sspt_proc **pproc = (struct sspt_proc **)data;
97
98         WARN_ON(*pproc);
99 }
100
101 struct ktask_data ktd = {
102         .init = ktd_init,
103         .exit = ktd_exit,
104         .size = sizeof(struct sspt_proc *),
105 };
106
107 static struct sspt_proc **pproc_by_task(struct task_struct *task)
108 {
109         return (struct sspt_proc **)swap_ktd(&ktd, task);
110 }
111
112 int sspt_proc_init(void)
113 {
114         return swap_ktd_reg(&ktd);
115 }
116
117 void sspt_proc_uninit(void)
118 {
119         swap_ktd_unreg(&ktd);
120 }
121
122 void sspt_change_leader(struct task_struct *prev, struct task_struct *next)
123 {
124         struct sspt_proc **prev_pproc;
125
126         prev_pproc = pproc_by_task(prev);
127         if (*prev_pproc) {
128                 struct sspt_proc **next_pproc;
129
130                 next_pproc = pproc_by_task(next);
131                 get_task_struct(next);
132
133                 /* Change the keeper sspt_proc */
134                 BUG_ON(*next_pproc);
135                 *next_pproc = *prev_pproc;
136                 *prev_pproc = NULL;
137
138                 /* Set new the task leader to sspt_proc */
139                 (*next_pproc)->leader = next;
140
141                 put_task_struct(prev);
142         }
143 }
144
145 void sspt_reset_proc(struct task_struct *task)
146 {
147         struct sspt_proc **pproc;
148
149         pproc = pproc_by_task(task->group_leader);
150         *pproc = NULL;
151 }
152
153
154
155
156
157 static struct sspt_proc *sspt_proc_create(struct task_struct *leader)
158 {
159         struct sspt_proc *proc = kzalloc(sizeof(*proc), GFP_KERNEL);
160
161         if (proc) {
162                 proc->feature = sspt_create_feature();
163                 if (proc->feature == NULL) {
164                         kfree(proc);
165                         return NULL;
166                 }
167
168                 INIT_LIST_HEAD(&proc->list);
169                 proc->tgid = leader->tgid;
170                 proc->leader = leader;
171                 /* FIXME: change the task leader */
172                 proc->sm = create_sm_us(leader);
173                 INIT_LIST_HEAD(&proc->file_head);
174                 mutex_init(&proc->filters.mtx);
175                 INIT_LIST_HEAD(&proc->filters.head);
176                 atomic_set(&proc->usage, 1);
177
178                 get_task_struct(proc->leader);
179
180                 proc->suspect.after_exec = 1;
181                 proc->suspect.after_fork = 0;
182         }
183
184         return proc;
185 }
186
187 /**
188  * @brief Remove sspt_proc struct
189  *
190  * @param proc remove object
191  * @return Void
192  */
193
194 /* called with sspt_proc_write_lock() */
195 void sspt_proc_cleanup(struct sspt_proc *proc)
196 {
197         struct sspt_file *file, *n;
198
199         sspt_proc_del_all_filters(proc);
200
201         list_for_each_entry_safe(file, n, &proc->file_head, list) {
202                 list_del(&file->list);
203                 sspt_file_free(file);
204         }
205
206         sspt_destroy_feature(proc->feature);
207
208         free_sm_us(proc->sm);
209         sspt_proc_put(proc);
210 }
211
212 struct sspt_proc *sspt_proc_get(struct sspt_proc *proc)
213 {
214         atomic_inc(&proc->usage);
215
216         return proc;
217 }
218
219 void sspt_proc_put(struct sspt_proc *proc)
220 {
221         if (atomic_dec_and_test(&proc->usage)) {
222                 if (proc->__mm) {
223                         mmput(proc->__mm);
224                         proc->__mm = NULL;
225                 }
226                 if (proc->__task) {
227                         put_task_struct(proc->__task);
228                         proc->__task = NULL;
229                 }
230
231                 put_task_struct(proc->leader);
232                 kfree(proc);
233         }
234 }
235
236 struct sspt_proc *sspt_proc_by_task(struct task_struct *task)
237 {
238         return *pproc_by_task(task->group_leader);
239 }
240 EXPORT_SYMBOL_GPL(sspt_proc_by_task);
241
242 /**
243  * @brief Call func() on each proc (no lock)
244  *
245  * @param func Callback
246  * @param data Data for callback
247  * @return Void
248  */
249 void on_each_proc_no_lock(void (*func)(struct sspt_proc *, void *), void *data)
250 {
251         struct sspt_proc *proc, *tmp;
252
253         list_for_each_entry_safe(proc, tmp, &proc_probes_list, list) {
254                 func(proc, data);
255         }
256 }
257
258 /**
259  * @brief Call func() on each proc
260  *
261  * @param func Callback
262  * @param data Data for callback
263  * @return Void
264  */
265 void on_each_proc(void (*func)(struct sspt_proc *, void *), void *data)
266 {
267         sspt_proc_read_lock();
268         on_each_proc_no_lock(func, data);
269         sspt_proc_read_unlock();
270 }
271 EXPORT_SYMBOL_GPL(on_each_proc);
272
273 /**
274  * @brief Get sspt_proc by task or create sspt_proc
275  *
276  * @param task Pointer on the task_struct struct
277  * @param priv Private data
278  * @return Pointer on the sspt_proc struct
279  */
280 struct sspt_proc *sspt_proc_get_by_task_or_new(struct task_struct *task)
281 {
282         static DEFINE_MUTEX(local_mutex);
283         struct sspt_proc **pproc;
284         struct task_struct *leader = task->group_leader;
285
286         pproc = pproc_by_task(leader);
287         if (*pproc)
288                 goto out;
289
290         /* This lock for synchronizing to create sspt_proc */
291         mutex_lock(&local_mutex);
292         pproc = pproc_by_task(leader);
293         if (*pproc == NULL) {
294                 *pproc = sspt_proc_create(leader);
295                 if (*pproc) {
296                         sspt_proc_write_lock();
297                         list_add(&(*pproc)->list, &proc_probes_list);
298                         sspt_proc_write_unlock();
299                 }
300         }
301         mutex_unlock(&local_mutex);
302
303 out:
304         return *pproc;
305 }
306
307 /**
308  * @brief Free all sspt_proc
309  *
310  * @return Pointer on the sspt_proc struct
311  */
312 void sspt_proc_free_all(void)
313 {
314         struct sspt_proc *proc, *n;
315
316         list_for_each_entry_safe(proc, n, &proc_probes_list, list) {
317                 list_del(&proc->list);
318                 sspt_proc_cleanup(proc);
319         }
320 }
321
322 static void sspt_proc_add_file(struct sspt_proc *proc, struct sspt_file *file)
323 {
324         list_add(&file->list, &proc->file_head);
325         file->proc = proc;
326 }
327
328 /**
329  * @brief Get sspt_file from sspt_proc by dentry or new
330  *
331  * @param proc Pointer on the sspt_proc struct
332  * @param dentry Dentry of file
333  * @return Pointer on the sspt_file struct
334  */
335 struct sspt_file *sspt_proc_find_file_or_new(struct sspt_proc *proc,
336                                              struct dentry *dentry)
337 {
338         struct sspt_file *file;
339
340         file = sspt_proc_find_file(proc, dentry);
341         if (file == NULL) {
342                 file = sspt_file_create(dentry, 10);
343                 if (file)
344                         sspt_proc_add_file(proc, file);
345         }
346
347         return file;
348 }
349
350 /**
351  * @brief Get sspt_file from sspt_proc by dentry
352  *
353  * @param proc Pointer on the sspt_proc struct
354  * @param dentry Dentry of file
355  * @return Pointer on the sspt_file struct
356  */
357 struct sspt_file *sspt_proc_find_file(struct sspt_proc *proc,
358                                       struct dentry *dentry)
359 {
360         struct sspt_file *file;
361
362         list_for_each_entry(file, &proc->file_head, list) {
363                 if (dentry == file->dentry)
364                         return file;
365         }
366
367         return NULL;
368 }
369
370 /**
371  * @brief Install probes on the page to monitored process
372  *
373  * @param proc Pointer on the sspt_proc struct
374  * @param page_addr Page address
375  * @return Void
376  */
377 void sspt_proc_install_page(struct sspt_proc *proc, unsigned long page_addr)
378 {
379         struct mm_struct *mm = proc->leader->mm;
380         struct vm_area_struct *vma;
381
382         vma = find_vma_intersection(mm, page_addr, page_addr + 1);
383         if (vma && check_vma(vma)) {
384                 struct dentry *dentry = vma->vm_file->f_dentry;
385                 struct sspt_file *file = sspt_proc_find_file(proc, dentry);
386                 if (file) {
387                         struct sspt_page *page;
388
389                         sspt_file_set_mapping(file, vma);
390
391                         page = sspt_find_page_mapped(file, page_addr);
392                         if (page)
393                                 sspt_register_page(page, file);
394                 }
395         }
396 }
397
398 /**
399  * @brief Install probes to monitored process
400  *
401  * @param proc Pointer on the sspt_proc struct
402  * @return Void
403  */
404 void sspt_proc_install(struct sspt_proc *proc)
405 {
406         struct vm_area_struct *vma;
407         struct mm_struct *mm = proc->leader->mm;
408
409         proc->first_install = 1;
410
411         for (vma = mm->mmap; vma; vma = vma->vm_next) {
412                 if (check_vma(vma)) {
413                         struct dentry *dentry = vma->vm_file->f_dentry;
414                         struct sspt_file *file =
415                                 sspt_proc_find_file(proc, dentry);
416                         if (file) {
417                                 sspt_file_set_mapping(file, vma);
418                                 sspt_file_install(file);
419                         }
420                 }
421         }
422 }
423
424 /**
425  * @brief Uninstall probes to monitored process
426  *
427  * @param proc Pointer on the sspt_proc struct
428  * @param task Pointer on the task_struct struct
429  * @param flag Action for probes
430  * @return Error code
431  */
432 int sspt_proc_uninstall(struct sspt_proc *proc,
433                         struct task_struct *task,
434                         enum US_FLAGS flag)
435 {
436         int err = 0;
437         struct sspt_file *file;
438
439         list_for_each_entry_rcu(file, &proc->file_head, list) {
440                 err = sspt_file_uninstall(file, task, flag);
441                 if (err != 0) {
442                         printk(KERN_INFO "ERROR sspt_proc_uninstall: err=%d\n",
443                                err);
444                         return err;
445                 }
446         }
447
448         return err;
449 }
450
451 static int intersection(unsigned long start_a, unsigned long end_a,
452                         unsigned long start_b, unsigned long end_b)
453 {
454         return start_a < start_b ?
455                         end_a > start_b :
456                         start_a < end_b;
457 }
458
459 /**
460  * @brief Get sspt_file list by region (remove sspt_file from sspt_proc list)
461  *
462  * @param proc Pointer on the sspt_proc struct
463  * @param head[out] Pointer on the head list
464  * @param start Region start
465  * @param len Region length
466  * @return Error code
467  */
468 int sspt_proc_get_files_by_region(struct sspt_proc *proc,
469                                   struct list_head *head,
470                                   unsigned long start, size_t len)
471 {
472         int ret = 0;
473         struct sspt_file *file, *n;
474         unsigned long end = start + len;
475
476         list_for_each_entry_safe(file, n, &proc->file_head, list) {
477                 if (intersection(file->vm_start, file->vm_end, start, end)) {
478                         ret = 1;
479                         list_move(&file->list, head);
480                 }
481         }
482
483         return ret;
484 }
485
486 /**
487  * @brief Insert sspt_file to sspt_proc list
488  *
489  * @param proc Pointer on the sspt_proc struct
490  * @param head Pointer on the head list
491  * @return Void
492  */
493 void sspt_proc_insert_files(struct sspt_proc *proc, struct list_head *head)
494 {
495         list_splice(head, &proc->file_head);
496 }
497
498 /**
499  * @brief Add sspt_filter to sspt_proc list
500  *
501  * @param proc Pointer to sspt_proc struct
502  * @param pfg Pointer to pf_group struct
503  * @return Void
504  */
505 void sspt_proc_add_filter(struct sspt_proc *proc, struct pf_group *pfg)
506 {
507         struct sspt_filter *f;
508
509         f = sspt_filter_create(proc, pfg);
510         if (f)
511                 list_add(&f->list, &proc->filters.head);
512 }
513
514 /**
515  * @brief Remove sspt_filter from sspt_proc list
516  *
517  * @param proc Pointer to sspt_proc struct
518  * @param pfg Pointer to pf_group struct
519  * @return Void
520  */
521 void sspt_proc_del_filter(struct sspt_proc *proc, struct pf_group *pfg)
522 {
523         struct sspt_filter *fl, *tmp;
524
525         mutex_lock(&proc->filters.mtx);
526         list_for_each_entry_safe(fl, tmp, &proc->filters.head, list) {
527                 if (fl->pfg == pfg) {
528                         list_del(&fl->list);
529                         sspt_filter_free(fl);
530                 }
531         }
532         mutex_unlock(&proc->filters.mtx);
533 }
534
535 /**
536  * @brief Remove all sspt_filters from sspt_proc list
537  *
538  * @param proc Pointer to sspt_proc struct
539  * @return Void
540  */
541 void sspt_proc_del_all_filters(struct sspt_proc *proc)
542 {
543         struct sspt_filter *fl, *tmp;
544
545         mutex_lock(&proc->filters.mtx);
546         list_for_each_entry_safe(fl, tmp, &proc->filters.head, list) {
547                 list_del(&fl->list);
548                 sspt_filter_free(fl);
549         }
550         mutex_unlock(&proc->filters.mtx);
551 }
552
553 /**
554  * @brief Check if sspt_filter is already in sspt_proc list
555  *
556  * @param proc Pointer to sspt_proc struct
557  * @param pfg Pointer to pf_group struct
558  * @return Boolean
559  */
560 bool sspt_proc_is_filter_new(struct sspt_proc *proc, struct pf_group *pfg)
561 {
562         struct sspt_filter *fl;
563
564         list_for_each_entry(fl, &proc->filters.head, list)
565                 if (fl->pfg == pfg)
566                         return false;
567
568         return true;
569 }
570
571 void sspt_proc_on_each_filter(struct sspt_proc *proc,
572                               void (*func)(struct sspt_filter *, void *),
573                               void *data)
574 {
575         struct sspt_filter *fl;
576
577         list_for_each_entry(fl, &proc->filters.head, list)
578                 func(fl, data);
579 }
580
581 void sspt_proc_on_each_ip(struct sspt_proc *proc,
582                           void (*func)(struct sspt_ip *, void *), void *data)
583 {
584         struct sspt_file *file;
585
586         list_for_each_entry(file, &proc->file_head, list)
587                 sspt_file_on_each_ip(file, func, data);
588 }
589
590 static void is_send_event(struct sspt_filter *f, void *data)
591 {
592         bool *is_send = (bool *)data;
593
594         if (!*is_send && f->pfg_is_inst)
595                 *is_send = !!pfg_msg_cb_get(f->pfg);
596 }
597
598 bool sspt_proc_is_send_event(struct sspt_proc *proc)
599 {
600         bool is_send = false;
601
602         /* FIXME: add read lock (deadlock in sampler) */
603         sspt_proc_on_each_filter(proc, is_send_event, (void *)&is_send);
604
605         return is_send;
606 }
607
608
609 static struct sspt_proc_cb *proc_cb;
610
611 int sspt_proc_cb_set(struct sspt_proc_cb *cb)
612 {
613         if (cb && proc_cb)
614                 return -EBUSY;
615
616         proc_cb = cb;
617
618         return 0;
619 }
620 EXPORT_SYMBOL_GPL(sspt_proc_cb_set);
621
622 void sspt_proc_priv_create(struct sspt_proc *proc)
623 {
624         if (proc_cb && proc_cb->priv_create)
625                 proc->private_data = proc_cb->priv_create(proc);
626 }
627
628 void sspt_proc_priv_destroy(struct sspt_proc *proc)
629 {
630         if (proc->first_install && proc_cb && proc_cb->priv_destroy)
631                 proc_cb->priv_destroy(proc, proc->private_data);
632 }