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 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 proc->tgid = leader->tgid;
182 proc->leader = leader;
183 /* FIXME: change the task leader */
184 proc->sm = create_sm_us(leader);
185 INIT_LIST_HEAD(&proc->file_head);
186 mutex_init(&proc->filters.mtx);
187 INIT_LIST_HEAD(&proc->filters.head);
188 atomic_set(&proc->usage, 1);
190 get_task_struct(proc->leader);
192 proc->suspect.after_exec = 1;
193 proc->suspect.after_fork = 0;
200 * @brief Remove sspt_proc struct
202 * @param proc remove object
206 /* called with sspt_proc_write_lock() */
207 void sspt_proc_cleanup(struct sspt_proc *proc)
209 struct sspt_file *file, *n;
211 sspt_proc_del_all_filters(proc);
213 list_for_each_entry_safe(file, n, &proc->file_head, list) {
214 list_del(&file->list);
215 sspt_file_free(file);
218 sspt_destroy_feature(proc->feature);
220 free_sm_us(proc->sm);
224 struct sspt_proc *sspt_proc_get(struct sspt_proc *proc)
226 atomic_inc(&proc->usage);
231 void sspt_proc_put(struct sspt_proc *proc)
233 if (atomic_dec_and_test(&proc->usage)) {
239 put_task_struct(proc->__task);
243 put_task_struct(proc->leader);
247 EXPORT_SYMBOL_GPL(sspt_proc_put);
249 struct sspt_proc *sspt_proc_by_task(struct task_struct *task)
251 return kproc_by_task(task->group_leader)->proc;
253 EXPORT_SYMBOL_GPL(sspt_proc_by_task);
255 struct sspt_proc *sspt_proc_get_by_task(struct task_struct *task)
257 struct ktd_proc *kproc = kproc_by_task(task->group_leader);
258 struct sspt_proc *proc;
260 spin_lock(&kproc->lock);
264 spin_unlock(&kproc->lock);
268 EXPORT_SYMBOL_GPL(sspt_proc_get_by_task);
271 * @brief Call func() on each proc (no lock)
273 * @param func Callback
274 * @param data Data for callback
277 void on_each_proc_no_lock(void (*func)(struct sspt_proc *, void *), void *data)
279 struct sspt_proc *proc, *tmp;
281 list_for_each_entry_safe(proc, tmp, &proc_probes_list, list) {
287 * @brief Call func() on each proc
289 * @param func Callback
290 * @param data Data for callback
293 void on_each_proc(void (*func)(struct sspt_proc *, void *), void *data)
295 sspt_proc_read_lock();
296 on_each_proc_no_lock(func, data);
297 sspt_proc_read_unlock();
299 EXPORT_SYMBOL_GPL(on_each_proc);
302 * @brief Get sspt_proc by task or create sspt_proc
304 * @param task Pointer on the task_struct struct
305 * @param priv Private data
306 * @return Pointer on the sspt_proc struct
308 struct sspt_proc *sspt_proc_get_by_task_or_new(struct task_struct *task)
310 static DEFINE_MUTEX(local_mutex);
311 struct ktd_proc *kproc;
312 struct sspt_proc *proc;
313 struct task_struct *leader = task->group_leader;
315 kproc = kproc_by_task(leader);
319 proc = sspt_proc_create(leader);
321 spin_lock(&kproc->lock);
322 if (kproc->proc == NULL) {
327 sspt_proc_write_lock();
328 list_add(&kproc->proc->list, &proc_probes_list);
329 sspt_proc_write_unlock();
331 spin_unlock(&kproc->lock);
334 sspt_proc_cleanup(proc);
341 * @brief Check sspt_proc on empty
343 * @return Pointer on the sspt_proc struct
345 void sspt_proc_check_empty(void)
347 WARN_ON(!list_empty(&proc_probes_list));
350 static void sspt_proc_add_file(struct sspt_proc *proc, struct sspt_file *file)
352 list_add(&file->list, &proc->file_head);
357 * @brief Get sspt_file from sspt_proc by dentry or new
359 * @param proc Pointer on the sspt_proc struct
360 * @param dentry Dentry of file
361 * @return Pointer on the sspt_file struct
363 struct sspt_file *sspt_proc_find_file_or_new(struct sspt_proc *proc,
364 struct dentry *dentry)
366 struct sspt_file *file;
368 file = sspt_proc_find_file(proc, dentry);
370 file = sspt_file_create(dentry, 10);
372 sspt_proc_add_file(proc, file);
379 * @brief Get sspt_file from sspt_proc by dentry
381 * @param proc Pointer on the sspt_proc struct
382 * @param dentry Dentry of file
383 * @return Pointer on the sspt_file struct
385 struct sspt_file *sspt_proc_find_file(struct sspt_proc *proc,
386 struct dentry *dentry)
388 struct sspt_file *file;
390 list_for_each_entry(file, &proc->file_head, list) {
391 if (dentry == file->dentry)
399 * @brief Install probes on the page to monitored process
401 * @param proc Pointer on the sspt_proc struct
402 * @param page_addr Page address
405 void sspt_proc_install_page(struct sspt_proc *proc, unsigned long page_addr)
407 struct mm_struct *mm = proc->leader->mm;
408 struct vm_area_struct *vma;
410 vma = find_vma_intersection(mm, page_addr, page_addr + 1);
411 if (vma && check_vma(vma)) {
412 struct dentry *dentry = vma->vm_file->f_dentry;
413 struct sspt_file *file = sspt_proc_find_file(proc, dentry);
415 struct sspt_page *page;
417 sspt_file_set_mapping(file, vma);
419 page = sspt_find_page_mapped(file, page_addr);
421 sspt_register_page(page, file);
427 * @brief Install probes to monitored process
429 * @param proc Pointer on the sspt_proc struct
432 void sspt_proc_install(struct sspt_proc *proc)
434 struct vm_area_struct *vma;
435 struct mm_struct *mm = proc->leader->mm;
437 proc->first_install = 1;
439 for (vma = mm->mmap; vma; vma = vma->vm_next) {
440 if (check_vma(vma)) {
441 struct dentry *dentry = vma->vm_file->f_dentry;
442 struct sspt_file *file =
443 sspt_proc_find_file(proc, dentry);
445 sspt_file_set_mapping(file, vma);
446 sspt_file_install(file);
453 * @brief Uninstall probes to monitored process
455 * @param proc Pointer on the sspt_proc struct
456 * @param task Pointer on the task_struct struct
457 * @param flag Action for probes
460 int sspt_proc_uninstall(struct sspt_proc *proc,
461 struct task_struct *task,
465 struct sspt_file *file;
467 list_for_each_entry_rcu(file, &proc->file_head, list) {
468 err = sspt_file_uninstall(file, task, flag);
470 printk(KERN_INFO "ERROR sspt_proc_uninstall: err=%d\n",
479 static int intersection(unsigned long start_a, unsigned long end_a,
480 unsigned long start_b, unsigned long end_b)
482 return start_a < start_b ?
488 * @brief Get sspt_file list by region (remove sspt_file from sspt_proc list)
490 * @param proc Pointer on the sspt_proc struct
491 * @param head[out] Pointer on the head list
492 * @param start Region start
493 * @param len Region length
496 int sspt_proc_get_files_by_region(struct sspt_proc *proc,
497 struct list_head *head,
498 unsigned long start, size_t len)
501 struct sspt_file *file, *n;
502 unsigned long end = start + len;
504 list_for_each_entry_safe(file, n, &proc->file_head, list) {
505 if (intersection(file->vm_start, file->vm_end, start, end)) {
507 list_move(&file->list, head);
515 * @brief Insert sspt_file to sspt_proc list
517 * @param proc Pointer on the sspt_proc struct
518 * @param head Pointer on the head list
521 void sspt_proc_insert_files(struct sspt_proc *proc, struct list_head *head)
523 list_splice(head, &proc->file_head);
527 * @brief Add sspt_filter to sspt_proc list
529 * @param proc Pointer to sspt_proc struct
530 * @param pfg Pointer to pf_group struct
533 void sspt_proc_add_filter(struct sspt_proc *proc, struct pf_group *pfg)
535 struct sspt_filter *f;
537 f = sspt_filter_create(proc, pfg);
539 list_add(&f->list, &proc->filters.head);
543 * @brief Remove sspt_filter from sspt_proc list
545 * @param proc Pointer to sspt_proc struct
546 * @param pfg Pointer to pf_group struct
549 void sspt_proc_del_filter(struct sspt_proc *proc, struct pf_group *pfg)
551 struct sspt_filter *fl, *tmp;
553 mutex_lock(&proc->filters.mtx);
554 list_for_each_entry_safe(fl, tmp, &proc->filters.head, list) {
555 if (fl->pfg == pfg) {
557 sspt_filter_free(fl);
560 mutex_unlock(&proc->filters.mtx);
564 * @brief Remove all sspt_filters from sspt_proc list
566 * @param proc Pointer to sspt_proc struct
569 void sspt_proc_del_all_filters(struct sspt_proc *proc)
571 struct sspt_filter *fl, *tmp;
573 mutex_lock(&proc->filters.mtx);
574 list_for_each_entry_safe(fl, tmp, &proc->filters.head, list) {
576 sspt_filter_free(fl);
578 mutex_unlock(&proc->filters.mtx);
582 * @brief Check if sspt_filter is already in sspt_proc list
584 * @param proc Pointer to sspt_proc struct
585 * @param pfg Pointer to pf_group struct
588 bool sspt_proc_is_filter_new(struct sspt_proc *proc, struct pf_group *pfg)
590 struct sspt_filter *fl;
592 list_for_each_entry(fl, &proc->filters.head, list)
599 void sspt_proc_on_each_filter(struct sspt_proc *proc,
600 void (*func)(struct sspt_filter *, void *),
603 struct sspt_filter *fl;
605 list_for_each_entry(fl, &proc->filters.head, list)
609 void sspt_proc_on_each_ip(struct sspt_proc *proc,
610 void (*func)(struct sspt_ip *, void *), void *data)
612 struct sspt_file *file;
614 list_for_each_entry(file, &proc->file_head, list)
615 sspt_file_on_each_ip(file, func, data);
618 static void is_send_event(struct sspt_filter *f, void *data)
620 bool *is_send = (bool *)data;
622 if (!*is_send && f->pfg_is_inst)
623 *is_send = !!pfg_msg_cb_get(f->pfg);
626 bool sspt_proc_is_send_event(struct sspt_proc *proc)
628 bool is_send = false;
630 /* FIXME: add read lock (deadlock in sampler) */
631 sspt_proc_on_each_filter(proc, is_send_event, (void *)&is_send);
637 static struct sspt_proc_cb *proc_cb;
639 int sspt_proc_cb_set(struct sspt_proc_cb *cb)
648 EXPORT_SYMBOL_GPL(sspt_proc_cb_set);
650 void sspt_proc_priv_create(struct sspt_proc *proc)
652 if (proc_cb && proc_cb->priv_create)
653 proc->private_data = proc_cb->priv_create(proc);
656 void sspt_proc_priv_destroy(struct sspt_proc *proc)
658 if (proc->first_install && proc_cb && proc_cb->priv_destroy)
659 proc_cb->priv_destroy(proc, proc->private_data);