1 /**************************************************************************
3 xserver-xorg-video-exynos
5 Copyright 2010 - 2011 Samsung Electronics co., Ltd. All Rights Reserved.
7 Contact: Boram Park <boram1288.park@samsung.com>
9 Permission is hereby granted, free of charge, to any person obtaining a
10 copy of this software and associated documentation files (the
11 "Software"), to deal in the Software without restriction, including
12 without limitation the rights to use, copy, modify, merge, publish,
13 distribute, sub license, and/or sell copies of the Software, and to
14 permit persons to whom the Software is furnished to do so, subject to
15 the following conditions:
17 The above copyright notice and this permission notice (including the
18 next paragraph) shall be included in all copies or substantial portions
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
24 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
25 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
26 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
27 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 **************************************************************************/
36 #include "bool_exp_parser.h"
37 #include "bool_exp_rule_checker.h"
64 static int print_func (BINARY_TREE tree, BINARY_TREE_NODE node, BINARY_TREE_NODE parent, void * arg)
67 char ** string = (char **)arg;
68 char * operators[] = { "==", "<", ">", "<=", ">=", "!=" };
70 PARSE_DATA data = bintree_get_node_data (node);
72 if (data->node_type == ALL)
74 len = sprintf (*string, "ALL");
77 else if (data->node_type == AND)
79 len = sprintf (*string, " and ");
82 else if (data->node_type == OR)
84 len = sprintf (*string, " or ");
87 else // data->node_type == DATA
89 if (node == bintree_get_left_child (parent))
95 len = sprintf (*string, "%s %s ", data->variable_name, operators[data->compare]);
97 if (data->value_type == INTEGER)
98 len = sprintf (*string, "%d", data->value.integer);
100 len = sprintf (*string, "%s", data->value.string);
103 if (node == bintree_get_right_child (parent))
113 static int compare_string (COMPARER compare, char * str2, char * str1)
115 int result = strcasecmp (str2, str1);
135 static int compare_int (COMPARER compare, int int2, int int1)
156 static int validate_func (BINARY_TREE tree, BINARY_TREE_NODE node, BINARY_TREE_NODE parent, void * arg)
158 VAL_ARGUMENTS * args = (VAL_ARGUMENTS*)arg;
159 BINARY_TREE_NODE left, right;
161 PARSE_DATA left_data = NULL, right_data = NULL;
162 PARSE_DATA data = bintree_get_node_data (node);
164 data->result = BEP_UNKNOWN;
166 if (data->node_type == AND || data->node_type == OR)
168 left = bintree_get_left_child (node);
169 right = bintree_get_right_child (node);
170 if (left == NULL || right == NULL)
172 printf ("Node error\n");
176 left_data = bintree_get_node_data (left);
177 right_data = bintree_get_node_data (right);
180 if (data->node_type == ALL)
182 data->result = BEP_TRUE;
184 else if (data->node_type == DATA)
190 minor = index (args->name, ':');
193 strncpy (major, args->name, minor - args->name);
194 major[minor - args->name] = '\0';
197 if (!strcasecmp (data->variable_name, "TYPE"))
200 if (args->type == 0) // EVENT
201 type_string = "EVENT";
202 else if (args->type == 1)
203 type_string = "REQUEST";
204 else if (args->type == 2)
205 type_string = "REPLY";
206 else if (args->type == 3)
207 type_string = "FLUSH";
210 fprintf (stderr, "Invalid type %d\n", args->type);
214 if (compare_string (data->compare, data->value.string, type_string))
215 data->result = BEP_TRUE;
217 data->result = BEP_FALSE;
219 else if (!strcasecmp (data->variable_name, "MAJOR"))
221 if (minor && compare_string (data->compare, data->value.string, major))
222 data->result = BEP_TRUE;
224 data->result = BEP_FALSE;
226 else if (!strcasecmp (data->variable_name, "MINOR"))
228 if (minor && compare_string (data->compare, data->value.string, minor))
229 data->result = BEP_TRUE;
231 data->result = BEP_FALSE;
233 else if (!strcasecmp (data->variable_name, "PID"))
235 if (compare_int (data->compare, data->value.integer, args->pid))
236 data->result = BEP_TRUE;
238 data->result = BEP_FALSE;
240 else if (!strcasecmp (data->variable_name, "CMD") || !strcasecmp (data->variable_name, "COMMAND"))
242 if (args->cmd && compare_string (data->compare, data->value.string, args->cmd))
243 data->result = BEP_TRUE;
245 data->result = BEP_FALSE;
248 else if (data->node_type == AND)
250 if (left_data->result == BEP_TRUE && right_data->result == BEP_TRUE)
251 data->result = BEP_TRUE;
253 data->result = BEP_FALSE;
255 else if (data->node_type == OR)
257 if (left_data->result == BEP_TRUE || right_data->result == BEP_TRUE)
258 data->result = BEP_TRUE;
260 data->result = BEP_FALSE;
269 RULE_CHECKER rulechecker_init()
271 RULE_CHECKER rc = calloc (sizeof (struct _RULE_CHECKER), 1);
280 void rulechecker_destroy (RULE_CHECKER rc)
283 for (i=rc->count - 1; i>=0; i--)
284 rulechecker_remove_rule (rc, i);
289 RC_RESULT_TYPE rulechecker_add_rule (RULE_CHECKER rc, POLICY_TYPE policy, const char * rule_string)
291 if (rc->count == MAX_RULE)
292 return RC_ERR_TOO_MANY_RULES;
294 rc->rules[rc->count].tree = bool_exp_parse (rule_string);
295 if (rc->rules[rc->count].tree == NULL)
296 return RC_ERR_PARSE_ERROR;
297 rc->rules[rc->count].policy = policy;
304 RC_RESULT_TYPE rulechecker_remove_rule (RULE_CHECKER rc, int index)
306 if (index < 0 || index >= rc->count)
307 return RC_ERR_NO_RULE;
309 bintree_destroy_tree (rc->rules[index].tree);
312 if (index != rc->count)
313 memmove (&rc->rules[index], &rc->rules[index + 1], sizeof (RULE) * (rc->count - index));
318 void rulechecker_print_rule (RULE_CHECKER rc, char * rules_buf)
320 char * rules_print = rules_buf;
325 len = sprintf (rules_print, " ---------------- Evlog Rules ----------------\n");
328 for (i=0; i<rc->count; i++)
330 len = sprintf (rules_print, " [Rule %d] [%s] \"", i, rc->rules[i].policy == ALLOW ? "ALLOW" : "DENY");
332 bintree_inorder_traverse (rc->rules[i].tree, print_func, (void*)&rules_print);
341 const char * rulechecker_print_usage()
344 "######################################################################\n"
345 "### RuleChecker 1.0 for XDBG EvLog filtering. ###\n"
346 "### Designed and developed by ###\n"
347 "### Boram Park <boram1288.park@samsung.com> ###\n"
348 "######################################################################\n"
350 "-----------------------------------------------------------------\n"
351 "How to read evlog messages :\n"
352 " Client(pid: [PID]| [CMD]) <====== [TYPE]( [MAJOR]: [MINOR]) ===== XServer\n"
355 " Client(pid:00345| xdbg) <====== Event ( X11:SendEvent) ===== XServer\n"
356 " ==> type = event && pid = 345 && cmd = xdbg && major = X11 && minor = SendEvent\n"
357 " Client(pid:00111| xeyes) ===== Request( SHM:ShmAttach) ======> XServer\n"
358 " ==> type = request && pid = 111 && cmd = xeyes && major = SHM && minor = ShmAttach\n"
360 "-----------------------------------------------------------------\n"
361 "Usage : xdbg evlog_rule add [POLICY] [RULE]\n"
362 " xdbg evlog_rule remove [INDEX]\n"
363 " xdbg evlog_rule help /print\n"
364 " [POLICY] : allow / deny \n"
365 " [RULE] : C Language-style boolean expression syntax. [VARIABLE] [COMPAROTOR] [VALUE]\n"
366 " [VARIABLE] : type / major / minor / command / cmd / pid\n"
367 " [COMPARATOR] : & / && / and / | / || / or / = / == / != / > / >= / < / <=\n"
368 " [VALUE] : string / number \n"
371 " xdbg evlog_rule add allow \"(type=request) && (major == X11 and (minor = SendEvent or minor = ReceiveEvent))\"\n"
372 " xdbg evlog_rule add deny cmd!=ls\n"
373 " xdbg evlog_rule remove 1\n"
377 int rulechecker_validate_rule (RULE_CHECKER rc, int type, int reqID, const char * name, int pid, char * cmd)
379 VAL_ARGUMENTS args = { type, reqID, name, pid, cmd };
380 BINARY_TREE_NODE node;
383 // set default value here
384 POLICY_TYPE default_policy = DENY;
386 for (i=rc->count - 1; i >= 0; i--)
388 bintree_postorder_traverse (rc->rules[i].tree, validate_func, &args);
389 node = bintree_get_head (rc->rules[i].tree);
390 data = bintree_get_node_data (node);
392 if (data->result == BEP_TRUE)
394 return rc->rules[i].policy == ALLOW;
398 return default_policy == ALLOW;