[IMPROVE] Us_manager: implement 'dumb' filter
[kernel/swap-modules.git] / parser / us_inst.c
1 /*
2  *  SWAP Parser
3  *  modules/parser/us_inst.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: SWAP Parser implement
22  *
23  */
24
25
26 #include <linux/module.h>
27 #include <linux/version.h>
28 #include <linux/errno.h>
29 #include <linux/namei.h>
30 #include <us_manager/pf/pf_group.h>
31 #include "msg_parser.h"
32 #include "us_inst.h"
33
34 /* FIXME: create get_dentry() and put_dentry() */
35 static struct dentry *dentry_by_path(const char *path)
36 {
37         struct dentry *dentry;
38 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 38)
39         struct path st_path;
40         if (kern_path(path, LOOKUP_FOLLOW, &st_path) != 0) {
41 #else /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 38) */
42         struct nameidata nd;
43         if (path_lookup(path, LOOKUP_FOLLOW, &nd) != 0) {
44 #endif /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 38) */
45                 printk("failed to lookup dentry for path %s!\n", path);
46                 return NULL;
47         }
48
49 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25)
50         dentry = nd.dentry;
51         path_release(&nd);
52 #elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 38)
53         dentry = nd.path.dentry;
54         path_put(&nd.path);
55 #else /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 38) */
56         dentry = st_path.dentry;
57         path_put(&st_path);
58 #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25) */
59         return dentry;
60 }
61
62
63 static int mod_func_inst(struct func_inst_data *func, struct pf_group *pfg,
64                          struct dentry *dentry, enum MOD_TYPE mt)
65 {
66         int ret;
67
68         switch (mt) {
69         case MT_ADD:
70                 ret = pf_register_probe(pfg, dentry, func->addr, func->args,
71                                         func->ret_type);
72                 break;
73         case MT_DEL:
74                 ret = pf_unregister_probe(pfg, dentry, func->addr);
75                 break;
76         default:
77                 printk("ERROR: mod_type=0x%x\n", mt);
78                 ret = -EINVAL;
79         }
80
81         return ret;
82 }
83
84 static int mod_lib_inst(struct lib_inst_data *lib, struct pf_group *pfg,
85                         enum MOD_TYPE mt)
86 {
87         int ret = 0, i;
88         struct dentry *dentry;
89
90         dentry = dentry_by_path(lib->path);
91         if (dentry == NULL) {
92                 printk("Cannot get dentry by path %s\n", lib->path);
93                 return -EINVAL;
94         }
95
96         for (i = 0; i < lib->cnt_func; ++i) {
97                 ret = mod_func_inst(lib->func[i], pfg, dentry, mt);
98                 if (ret) {
99                         printk("Cannot mod func inst, ret = %d\n", ret);
100                         return ret;
101                 }
102         }
103
104         return ret;
105 }
106
107 static int get_pfg_by_app_info(struct app_info_data *app_info, struct pf_group **pfg)
108 {
109         struct dentry *dentry;
110
111         dentry = dentry_by_path(app_info->exec_path);
112         if (dentry == NULL)
113                 return -EINVAL;
114
115         switch (app_info->app_type) {
116         case AT_PID:
117                 if (app_info->tgid == 0)
118                         goto pf_dentry;
119
120                 *pfg = get_pf_group_by_tgid(app_info->tgid, dentry);
121                 break;
122         case AT_TIZEN_NATIVE_APP:
123         case AT_TIZEN_WEB_APP:
124         case AT_COMMON_EXEC:
125  pf_dentry:
126                 *pfg = get_pf_group_by_dentry(dentry, dentry);
127                 break;
128         default:
129                 printk("ERROR: app_type=0x%x\n", app_info->app_type);
130                 return -EINVAL;
131         }
132
133         return 0;
134 }
135
136 static int mod_us_app_inst(struct app_inst_data *app_inst, enum MOD_TYPE mt)
137 {
138         int ret, i;
139         struct pf_group *pfg;
140         struct dentry *dentry;
141
142         ret = get_pfg_by_app_info(app_inst->app_info, &pfg);
143         if (ret) {
144                 printk("Cannot get pfg by app info, ret = %d\n", ret);
145                 return ret;
146         }
147
148         for (i = 0; i < app_inst->cnt_func; ++i) {
149                 /* TODO: */
150                 dentry = dentry_by_path(app_inst->app_info->exec_path);
151                 if (dentry == NULL) {
152                         printk("Cannot find dentry by path %s\n",
153                                app_inst->app_info->exec_path);
154                         return -EINVAL;
155                 }
156
157                 ret = mod_func_inst(app_inst->func[i], pfg, dentry, mt);
158                 if (ret) {
159                         printk("Cannot mod func inst, ret = %d\n", ret);
160                         return ret;
161                 }
162         }
163
164         for (i = 0; i < app_inst->cnt_lib; ++i) {
165                 ret = mod_lib_inst(app_inst->lib[i], pfg, mt);
166                 if (ret) {
167                         printk("Cannot mod lib inst, ret = %d\n", ret);
168                         return ret;
169                 }
170         }
171
172         return 0;
173 }
174
175 int mod_us_inst(struct us_inst_data *us_inst, enum MOD_TYPE mt)
176 {
177         u32 i;
178         int ret;
179
180         for (i = 0; i < us_inst->cnt; ++i) {
181                 ret = mod_us_app_inst(us_inst->app_inst[i], mt);
182                 if (ret) {
183                         printk("Cannot mod us app inst, ret = %d\n", ret);
184                         return ret;
185                 }
186         }
187
188         return 0;
189 }