2 * Dynamic Binary Instrumentation Module based on KProbes
3 * modules/driver/sspt/sspt_proc.c
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.
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.
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.
19 * Copyright (C) Samsung Electronics, 2013
21 * 2013 Vyacheslav Cherkashin <v.cherkashin@samsung.com>
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>
37 static LIST_HEAD(proc_probes_list);
38 static DEFINE_RWLOCK(sspt_proc_rwlock);
41 struct list_head *sspt_proc_list()
43 return &proc_probes_list;
47 * @brief Global read lock for sspt_proc
51 void sspt_proc_read_lock(void)
53 read_lock(&sspt_proc_rwlock);
57 * @brief Global read unlock for sspt_proc
61 void sspt_proc_read_unlock(void)
63 read_unlock(&sspt_proc_rwlock);
67 * @brief Global write lock for sspt_proc
71 void sspt_proc_write_lock(void)
73 write_lock(&sspt_proc_rwlock);
77 * @brief Global write unlock for sspt_proc
81 void sspt_proc_write_unlock(void)
83 write_unlock(&sspt_proc_rwlock);
87 struct sspt_proc *proc;
91 static void ktd_init(struct task_struct *task, void *data)
93 struct ktd_proc *kproc = (struct ktd_proc *)data;
96 spin_lock_init(&kproc->lock);
99 static void ktd_exit(struct task_struct *task, void *data)
101 struct ktd_proc *kproc = (struct ktd_proc *)data;
103 WARN_ON(kproc->proc);
106 struct ktask_data ktd = {
109 .size = sizeof(struct ktd_proc),
112 static struct ktd_proc *kproc_by_task(struct task_struct *task)
114 return (struct ktd_proc *)swap_ktd(&ktd, task);
117 int sspt_proc_init(void)
119 return swap_ktd_reg(&ktd);
122 void sspt_proc_uninit(void)
124 swap_ktd_unreg(&ktd);
127 void sspt_change_leader(struct task_struct *prev, struct task_struct *next)
129 struct ktd_proc *prev_kproc;
131 prev_kproc = kproc_by_task(prev);
132 spin_lock(&prev_kproc->lock);
133 if (prev_kproc->proc) {
134 struct ktd_proc *next_kproc;
136 next_kproc = kproc_by_task(next);
137 get_task_struct(next);
139 /* Change the keeper sspt_proc */
140 BUG_ON(next_kproc->proc);
142 spin_lock(&next_kproc->lock);
143 next_kproc->proc = prev_kproc->proc;
144 prev_kproc->proc = NULL;
145 spin_unlock(&next_kproc->lock);
147 /* Set new the task leader to sspt_proc */
148 next_kproc->proc->leader = next;
150 put_task_struct(prev);
152 spin_unlock(&prev_kproc->lock);
155 static void sspt_reset_proc(struct task_struct *task)
157 struct ktd_proc *kproc;
159 kproc = kproc_by_task(task->group_leader);
160 spin_lock(&kproc->lock);
162 spin_unlock(&kproc->lock);
169 static struct sspt_proc *sspt_proc_create(struct task_struct *leader)
171 struct sspt_proc *proc = kzalloc(sizeof(*proc), GFP_KERNEL);
174 proc->feature = sspt_create_feature();
175 if (proc->feature == NULL) {
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);
191 get_task_struct(proc->leader);
193 proc->suspect.after_exec = 1;
194 proc->suspect.after_fork = 0;
200 static void sspt_proc_free(struct sspt_proc *proc)
202 put_task_struct(proc->leader);
203 free_sm_us(proc->sm);
204 sspt_destroy_feature(proc->feature);
209 * @brief Remove sspt_proc struct
211 * @param proc remove object
215 /* called with sspt_proc_write_lock() */
216 void sspt_proc_cleanup(struct sspt_proc *proc)
218 struct sspt_file *file, *n;
220 sspt_proc_del_all_filters(proc);
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);
227 up_write(&proc->files.sem);
229 sspt_destroy_feature(proc->feature);
231 free_sm_us(proc->sm);
232 sspt_reset_proc(proc->leader);
236 struct sspt_proc *sspt_proc_get(struct sspt_proc *proc)
238 atomic_inc(&proc->usage);
243 void sspt_proc_put(struct sspt_proc *proc)
245 if (atomic_dec_and_test(&proc->usage)) {
251 put_task_struct(proc->__task);
255 WARN_ON(kproc_by_task(proc->leader)->proc);
257 put_task_struct(proc->leader);
261 EXPORT_SYMBOL_GPL(sspt_proc_put);
263 struct sspt_proc *sspt_proc_by_task(struct task_struct *task)
265 return kproc_by_task(task->group_leader)->proc;
267 EXPORT_SYMBOL_GPL(sspt_proc_by_task);
269 struct sspt_proc *sspt_proc_get_by_task(struct task_struct *task)
271 struct ktd_proc *kproc = kproc_by_task(task->group_leader);
272 struct sspt_proc *proc;
274 spin_lock(&kproc->lock);
278 spin_unlock(&kproc->lock);
282 EXPORT_SYMBOL_GPL(sspt_proc_get_by_task);
285 * @brief Call func() on each proc (no lock)
287 * @param func Callback
288 * @param data Data for callback
291 void on_each_proc_no_lock(void (*func)(struct sspt_proc *, void *), void *data)
293 struct sspt_proc *proc, *tmp;
295 list_for_each_entry_safe(proc, tmp, &proc_probes_list, list) {
301 * @brief Call func() on each proc
303 * @param func Callback
304 * @param data Data for callback
307 void on_each_proc(void (*func)(struct sspt_proc *, void *), void *data)
309 sspt_proc_read_lock();
310 on_each_proc_no_lock(func, data);
311 sspt_proc_read_unlock();
313 EXPORT_SYMBOL_GPL(on_each_proc);
316 * @brief Get sspt_proc by task or create sspt_proc
318 * @param task Pointer on the task_struct struct
319 * @param priv Private data
320 * @return Pointer on the sspt_proc struct
322 struct sspt_proc *sspt_proc_get_by_task_or_new(struct task_struct *task)
324 static DEFINE_MUTEX(local_mutex);
325 struct ktd_proc *kproc;
326 struct sspt_proc *proc;
327 struct task_struct *leader = task->group_leader;
329 kproc = kproc_by_task(leader);
333 proc = sspt_proc_create(leader);
335 spin_lock(&kproc->lock);
336 if (kproc->proc == NULL) {
341 sspt_proc_write_lock();
342 list_add(&kproc->proc->list, &proc_probes_list);
343 sspt_proc_write_unlock();
345 spin_unlock(&kproc->lock);
348 sspt_proc_free(proc);
355 * @brief Check sspt_proc on empty
357 * @return Pointer on the sspt_proc struct
359 void sspt_proc_check_empty(void)
361 WARN_ON(!list_empty(&proc_probes_list));
364 static void sspt_proc_add_file(struct sspt_proc *proc, struct sspt_file *file)
366 down_write(&proc->files.sem);
367 list_add(&file->list, &proc->files.head);
369 up_write(&proc->files.sem);
373 * @brief Get sspt_file from sspt_proc by dentry or new
375 * @param proc Pointer on the sspt_proc struct
376 * @param dentry Dentry of file
377 * @return Pointer on the sspt_file struct
379 struct sspt_file *sspt_proc_find_file_or_new(struct sspt_proc *proc,
380 struct dentry *dentry)
382 struct sspt_file *file;
384 file = sspt_proc_find_file(proc, dentry);
386 file = sspt_file_create(dentry, 10);
388 sspt_proc_add_file(proc, file);
395 * @brief Get sspt_file from sspt_proc by dentry
397 * @param proc Pointer on the sspt_proc struct
398 * @param dentry Dentry of file
399 * @return Pointer on the sspt_file struct
401 struct sspt_file *sspt_proc_find_file(struct sspt_proc *proc,
402 struct dentry *dentry)
404 struct sspt_file *file;
406 down_read(&proc->files.sem);
407 list_for_each_entry(file, &proc->files.head, list) {
408 if (dentry == file->dentry)
414 up_read(&proc->files.sem);
420 * @brief Install probes on the page to monitored process
422 * @param proc Pointer on the sspt_proc struct
423 * @param page_addr Page address
426 void sspt_proc_install_page(struct sspt_proc *proc, unsigned long page_addr)
428 struct mm_struct *mm = proc->leader->mm;
429 struct vm_area_struct *vma;
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);
436 struct sspt_page *page;
438 sspt_file_set_mapping(file, vma);
440 page = sspt_find_page_mapped(file, page_addr);
442 sspt_register_page(page, file);
448 * @brief Install probes to monitored process
450 * @param proc Pointer on the sspt_proc struct
453 void sspt_proc_install(struct sspt_proc *proc)
455 struct vm_area_struct *vma;
456 struct mm_struct *mm = proc->leader->mm;
458 proc->first_install = 1;
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);
466 sspt_file_set_mapping(file, vma);
467 sspt_file_install(file);
474 * @brief Uninstall probes to monitored process
476 * @param proc Pointer on the sspt_proc struct
477 * @param task Pointer on the task_struct struct
478 * @param flag Action for probes
481 int sspt_proc_uninstall(struct sspt_proc *proc,
482 struct task_struct *task,
486 struct sspt_file *file;
488 down_read(&proc->files.sem);
489 list_for_each_entry(file, &proc->files.head, list) {
490 err = sspt_file_uninstall(file, task, flag);
492 printk(KERN_INFO "ERROR sspt_proc_uninstall: err=%d\n",
497 up_read(&proc->files.sem);
502 static int intersection(unsigned long start_a, unsigned long end_a,
503 unsigned long start_b, unsigned long end_b)
505 return start_a < start_b ?
511 * @brief Get sspt_file list by region (remove sspt_file from sspt_proc list)
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
519 int sspt_proc_get_files_by_region(struct sspt_proc *proc,
520 struct list_head *head,
521 unsigned long start, size_t len)
524 struct sspt_file *file, *n;
525 unsigned long end = start + len;
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)) {
531 list_move(&file->list, head);
534 up_write(&proc->files.sem);
540 * @brief Insert sspt_file to sspt_proc list
542 * @param proc Pointer on the sspt_proc struct
543 * @param head Pointer on the head list
546 void sspt_proc_insert_files(struct sspt_proc *proc, struct list_head *head)
548 down_write(&proc->files.sem);
549 list_splice(head, &proc->files.head);
550 up_write(&proc->files.sem);
554 * @brief Add sspt_filter to sspt_proc list
556 * @param proc Pointer to sspt_proc struct
557 * @param pfg Pointer to pf_group struct
560 void sspt_proc_add_filter(struct sspt_proc *proc, struct pf_group *pfg)
562 struct sspt_filter *f;
564 f = sspt_filter_create(proc, pfg);
566 list_add(&f->list, &proc->filters.head);
570 * @brief Remove sspt_filter from sspt_proc list
572 * @param proc Pointer to sspt_proc struct
573 * @param pfg Pointer to pf_group struct
576 void sspt_proc_del_filter(struct sspt_proc *proc, struct pf_group *pfg)
578 struct sspt_filter *fl, *tmp;
580 mutex_lock(&proc->filters.mtx);
581 list_for_each_entry_safe(fl, tmp, &proc->filters.head, list) {
582 if (fl->pfg == pfg) {
584 sspt_filter_free(fl);
587 mutex_unlock(&proc->filters.mtx);
591 * @brief Remove all sspt_filters from sspt_proc list
593 * @param proc Pointer to sspt_proc struct
596 void sspt_proc_del_all_filters(struct sspt_proc *proc)
598 struct sspt_filter *fl, *tmp;
600 mutex_lock(&proc->filters.mtx);
601 list_for_each_entry_safe(fl, tmp, &proc->filters.head, list) {
603 sspt_filter_free(fl);
605 mutex_unlock(&proc->filters.mtx);
609 * @brief Check if sspt_filter is already in sspt_proc list
611 * @param proc Pointer to sspt_proc struct
612 * @param pfg Pointer to pf_group struct
615 bool sspt_proc_is_filter_new(struct sspt_proc *proc, struct pf_group *pfg)
617 struct sspt_filter *fl;
619 list_for_each_entry(fl, &proc->filters.head, list)
626 void sspt_proc_on_each_filter(struct sspt_proc *proc,
627 void (*func)(struct sspt_filter *, void *),
630 struct sspt_filter *fl;
632 list_for_each_entry(fl, &proc->filters.head, list)
636 void sspt_proc_on_each_ip(struct sspt_proc *proc,
637 void (*func)(struct sspt_ip *, void *), void *data)
639 struct sspt_file *file;
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);
647 static void is_send_event(struct sspt_filter *f, void *data)
649 bool *is_send = (bool *)data;
651 if (!*is_send && f->pfg_is_inst)
652 *is_send = !!pfg_msg_cb_get(f->pfg);
655 bool sspt_proc_is_send_event(struct sspt_proc *proc)
657 bool is_send = false;
659 /* FIXME: add read lock (deadlock in sampler) */
660 sspt_proc_on_each_filter(proc, is_send_event, (void *)&is_send);
666 static struct sspt_proc_cb *proc_cb;
668 int sspt_proc_cb_set(struct sspt_proc_cb *cb)
677 EXPORT_SYMBOL_GPL(sspt_proc_cb_set);
679 void sspt_proc_priv_create(struct sspt_proc *proc)
681 if (proc_cb && proc_cb->priv_create)
682 proc->private_data = proc_cb->priv_create(proc);
685 void sspt_proc_priv_destroy(struct sspt_proc *proc)
687 if (proc->first_install && proc_cb && proc_cb->priv_destroy)
688 proc_cb->priv_destroy(proc, proc->private_data);