obj-m := swap_us_manager.o
swap_us_manager-y := us_manager.o us_slot_manager.o helper.o debugfs_us_manager.o \
sspt/ip.o sspt/sspt_page.o sspt/sspt_file.o sspt/sspt_proc.o \
- sspt/sspt_feature.o \
+ sspt/sspt_feature.o sspt/sspt_filter.o \
pf/proc_filters.o pf/pf_group.o \
img/img_proc.o img/img_file.o img/img_ip.o
proc = sspt_proc_get_by_task_or_new(task, pfg->filter.priv);
copy_proc_form_img_to_sspt(pfg->i_proc, proc);
+ sspt_proc_add_filter(proc, pfg);
pls = create_pl_struct(proc);
add_pl_struct(pfg, pls);
static void free_pfg(struct pf_group *pfg)
{
+ struct pl_struct *pl;
+
free_img_proc(pfg->i_proc);
+ list_for_each_entry(pl, &pfg->proc_list, list)
+ sspt_proc_del_filter(pl->proc, pfg);
kfree(pfg);
}
continue;
proc = get_proc_by_pfg(pfg, task);
- if (proc)
+ if (proc) {
+ if (sspt_proc_is_filter_new(proc, pfg)) {
+ copy_proc_form_img_to_sspt(pfg->i_proc, proc);
+ sspt_proc_add_filter(proc, pfg);
+ }
break;
+ }
if (task->tgid == task->pid) {
proc = new_proc_by_pfg(pfg, task);
sspt_proc_uninstall(proc, task, US_UNREGS_PROBE);
task_unlock(task);
+ sspt_proc_del_all_filters(proc);
sspt_proc_free(proc);
}
--- /dev/null
+#include <linux/list.h>
+#include <linux/slab.h>
+#include "sspt_filter.h"
+#include "sspt_proc.h"
+
+struct sspt_filter *sspt_filter_create(struct pf_group *pfg)
+{
+ struct sspt_filter *fl;
+
+ fl = kmalloc(sizeof(*fl), GFP_KERNEL);
+ if (fl == NULL)
+ return NULL;
+
+ INIT_LIST_HEAD(&fl->list);
+ fl->pfg = pfg;
+
+ return fl;
+}
+
+void sspt_filter_free(struct sspt_filter *fl)
+{
+ kfree(fl);
+}
--- /dev/null
+#ifndef __SSPT_FILTER_H__
+#define __SSPT_FILTER_H__
+
+struct pf_group;
+
+struct sspt_filter {
+ struct list_head list;
+ struct pf_group *pfg;
+};
+
+struct sspt_filter *sspt_filter_create(struct pf_group *pfg);
+void sspt_filter_free(struct sspt_filter *fl);
+
+#endif /* __SSPT_FILTER_H__ */
#include "sspt_proc.h"
#include "sspt_page.h"
#include "sspt_feature.h"
+#include "sspt_filter.h"
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/list.h>
static LIST_HEAD(proc_probes_list);
static DEFINE_RWLOCK(sspt_proc_rwlock);
+void sspt_proc_del_all_filters(struct sspt_proc *proc);
+
/**
* @brief Global read lock for sspt_proc
*
proc->sm = create_sm_us(task);
proc->first_install = 0;
INIT_LIST_HEAD(&proc->file_list);
+ INIT_LIST_HEAD(&proc->filter_list);
/* add to list */
list_add(&proc->list, &proc_probes_list);
{
struct sspt_proc *proc, *n;
list_for_each_entry_safe(proc, n, &proc_probes_list, list) {
+ sspt_proc_del_all_filters(proc);
sspt_proc_free(proc);
}
}
{
list_splice(head, &proc->file_list);
}
+
+/**
+ * @brief Add sspt_filter to sspt_proc list
+ *
+ * @param proc Pointer to sspt_proc struct
+ * @param pfg Pointer to pf_group struct
+ * @return Void
+ */
+void sspt_proc_add_filter(struct sspt_proc *proc, struct pf_group *pfg)
+{
+ struct sspt_filter *fl;
+
+ fl = sspt_filter_create(pfg);
+ if (fl == NULL)
+ return;
+
+ list_add(&fl->list, &proc->filter_list);
+}
+
+/**
+ * @brief Remove sspt_filter from sspt_proc list
+ *
+ * @param proc Pointer to sspt_proc struct
+ * @param pfg Pointer to pf_group struct
+ * @return Void
+ */
+void sspt_proc_del_filter(struct sspt_proc *proc, struct pf_group *pfg)
+{
+ struct sspt_filter *fl, *tmp;
+
+ list_for_each_entry_safe(fl, tmp, &proc->filter_list, list) {
+ if (fl->pfg == pfg) {
+ list_del(&fl->list);
+ sspt_filter_free(fl);
+ }
+ }
+}
+
+/**
+ * @brief Remove all sspt_filters from sspt_proc list
+ *
+ * @param proc Pointer to sspt_proc struct
+ * @return Void
+ */
+void sspt_proc_del_all_filters(struct sspt_proc *proc)
+{
+ struct sspt_filter *fl, *tmp;
+
+ list_for_each_entry_safe(fl, tmp, &proc->filter_list, list) {
+ list_del(&fl->list);
+ sspt_filter_free(fl);
+ }
+}
+
+/**
+ * @brief Check if sspt_filter is already in sspt_proc list
+ *
+ * @param proc Pointer to sspt_proc struct
+ * @param pfg Pointer to pf_group struct
+ * @return Boolean
+ */
+int sspt_proc_is_filter_new(struct sspt_proc *proc, struct pf_group *pfg)
+{
+ struct sspt_filter *fl;
+
+ list_for_each_entry(fl, &proc->filter_list, list)
+ if (fl->pfg == pfg)
+ return 0;
+
+ return 1;
+}
struct slot_manager;
struct task_struct;
+struct pf_group;
/** Flags for sspt_*_uninstall() */
enum US_FLAGS {
struct task_struct *task; /**< Ptr to the task */
struct slot_manager *sm; /**< Ptr to the manager slot */
struct list_head file_list; /**< For sspt_file */
+ struct list_head filter_list; /**< Filter list */
unsigned first_install:1; /**< Install flag */
struct sspt_feature *feature; /**< Ptr to the feature */
};
void sspt_proc_write_lock(void);
void sspt_proc_write_unlock(void);
+void sspt_proc_add_filter(struct sspt_proc *proc, struct pf_group *pfg);
+void sspt_proc_del_filter(struct sspt_proc *proc, struct pf_group *pfg);
+void sspt_proc_del_all_filters(struct sspt_proc *proc);
+int sspt_proc_is_filter_new(struct sspt_proc *proc, struct pf_group *pfg);
#endif /* __SSPT_PROC__ */