callstack context: use delimiter when stack is incomplete
[lttng-modules.git] / lttng-filter-validator.c
CommitLineData
07dfc1d0
MD
1/*
2 * lttng-filter-validator.c
3 *
4 * LTTng modules filter bytecode validator.
5 *
bbf3aef5 6 * Copyright (C) 2010-2016 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
07dfc1d0 7 *
bbf3aef5
MD
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
07dfc1d0 14 *
bbf3aef5
MD
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
07dfc1d0 17 *
bbf3aef5
MD
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 * SOFTWARE.
07dfc1d0
MD
25 */
26
499cc3f7 27#include <linux/types.h>
07dfc1d0
MD
28#include <linux/jhash.h>
29#include <linux/slab.h>
30
241ae9a8
MD
31#include <wrapper/list.h>
32#include <lttng-filter.h>
07dfc1d0
MD
33
34#define MERGE_POINT_TABLE_BITS 7
35#define MERGE_POINT_TABLE_SIZE (1U << MERGE_POINT_TABLE_BITS)
36
37/* merge point table node */
38struct mp_node {
39 struct hlist_node node;
40
41 /* Context at merge point */
42 struct vstack stack;
43 unsigned long target_pc;
44};
45
46struct mp_table {
47 struct hlist_head mp_head[MERGE_POINT_TABLE_SIZE];
48};
49
50static
51int lttng_hash_match(struct mp_node *mp_node, unsigned long key_pc)
52{
53 if (mp_node->target_pc == key_pc)
54 return 1;
55 else
56 return 0;
57}
58
59static
60int merge_points_compare(const struct vstack *stacka,
61 const struct vstack *stackb)
62{
63 int i, len;
64
65 if (stacka->top != stackb->top)
66 return 1;
67 len = stacka->top + 1;
68 WARN_ON_ONCE(len < 0);
69 for (i = 0; i < len; i++) {
70 if (stacka->e[i].type != stackb->e[i].type)
71 return 1;
72 }
73 return 0;
74}
75
76static
77int merge_point_add_check(struct mp_table *mp_table, unsigned long target_pc,
78 const struct vstack *stack)
79{
80 struct mp_node *mp_node;
81 unsigned long hash = jhash_1word(target_pc, 0);
82 struct hlist_head *head;
83 struct mp_node *lookup_node;
84 int found = 0;
85
86 dbg_printk("Filter: adding merge point at offset %lu, hash %lu\n",
87 target_pc, hash);
88 mp_node = kzalloc(sizeof(struct mp_node), GFP_KERNEL);
89 if (!mp_node)
90 return -ENOMEM;
91 mp_node->target_pc = target_pc;
92 memcpy(&mp_node->stack, stack, sizeof(mp_node->stack));
93
94 head = &mp_table->mp_head[hash & (MERGE_POINT_TABLE_SIZE - 1)];
d216ecae 95 lttng_hlist_for_each_entry(lookup_node, head, node) {
07dfc1d0
MD
96 if (lttng_hash_match(lookup_node, target_pc)) {
97 found = 1;
98 break;
99 }
100 }
101 if (found) {
102 /* Key already present */
103 dbg_printk("Filter: compare merge points for offset %lu, hash %lu\n",
104 target_pc, hash);
105 kfree(mp_node);
106 if (merge_points_compare(stack, &lookup_node->stack)) {
107 printk(KERN_WARNING "Merge points differ for offset %lu\n",
108 target_pc);
109 return -EINVAL;
110 }
5e13eb3c
MD
111 } else {
112 hlist_add_head(&mp_node->node, head);
07dfc1d0 113 }
07dfc1d0
MD
114 return 0;
115}
116
117/*
118 * Binary comparators use top of stack and top of stack -1.
119 */
120static
02aca193
PP
121int bin_op_compare_check(struct vstack *stack, const filter_opcode_t opcode,
122 const char *str)
07dfc1d0
MD
123{
124 if (unlikely(!vstack_ax(stack) || !vstack_bx(stack)))
3834b99f 125 goto error_empty;
07dfc1d0
MD
126
127 switch (vstack_ax(stack)->type) {
128 default:
129 case REG_DOUBLE:
3834b99f 130 goto error_type;
07dfc1d0
MD
131
132 case REG_STRING:
133 switch (vstack_bx(stack)->type) {
134 default:
135 case REG_DOUBLE:
3834b99f
MD
136 goto error_type;
137 case REG_TYPE_UNKNOWN:
138 goto unknown;
07dfc1d0
MD
139 case REG_STRING:
140 break;
02aca193
PP
141 case REG_STAR_GLOB_STRING:
142 if (opcode != FILTER_OP_EQ && opcode != FILTER_OP_NE) {
143 goto error_mismatch;
144 }
145 break;
146 case REG_S64:
147 goto error_mismatch;
148 }
149 break;
150 case REG_STAR_GLOB_STRING:
151 switch (vstack_bx(stack)->type) {
152 default:
153 case REG_DOUBLE:
3834b99f
MD
154 goto error_type;
155 case REG_TYPE_UNKNOWN:
156 goto unknown;
02aca193
PP
157 case REG_STRING:
158 if (opcode != FILTER_OP_EQ && opcode != FILTER_OP_NE) {
159 goto error_mismatch;
160 }
161 break;
162 case REG_STAR_GLOB_STRING:
07dfc1d0
MD
163 case REG_S64:
164 goto error_mismatch;
165 }
166 break;
167 case REG_S64:
168 switch (vstack_bx(stack)->type) {
169 default:
170 case REG_DOUBLE:
3834b99f
MD
171 goto error_type;
172 case REG_TYPE_UNKNOWN:
173 goto unknown;
07dfc1d0 174 case REG_STRING:
02aca193 175 case REG_STAR_GLOB_STRING:
07dfc1d0 176 goto error_mismatch;
07dfc1d0
MD
177 case REG_S64:
178 break;
179 }
180 break;
3834b99f
MD
181 case REG_TYPE_UNKNOWN:
182 switch (vstack_bx(stack)->type) {
183 default:
184 case REG_DOUBLE:
185 goto error_type;
186 case REG_TYPE_UNKNOWN:
187 case REG_STRING:
188 case REG_STAR_GLOB_STRING:
189 case REG_S64:
190 goto unknown;
191 }
192 break;
07dfc1d0
MD
193 }
194 return 0;
195
3834b99f
MD
196unknown:
197 return 1;
198
199error_empty:
200 printk(KERN_WARNING "empty stack for '%s' binary operator\n", str);
07dfc1d0
MD
201 return -EINVAL;
202
203error_mismatch:
204 printk(KERN_WARNING "type mismatch for '%s' binary operator\n", str);
205 return -EINVAL;
3834b99f
MD
206
207error_type:
208 printk(KERN_WARNING "unknown type for '%s' binary operator\n", str);
209 return -EINVAL;
210}
211
212/*
213 * Binary bitwise operators use top of stack and top of stack -1.
214 * Return 0 if typing is known to match, 1 if typing is dynamic
215 * (unknown), negative error value on error.
216 */
217static
218int bin_op_bitwise_check(struct vstack *stack, filter_opcode_t opcode,
219 const char *str)
220{
221 if (unlikely(!vstack_ax(stack) || !vstack_bx(stack)))
222 goto error_empty;
223
224 switch (vstack_ax(stack)->type) {
225 default:
226 case REG_DOUBLE:
227 goto error_type;
228
229 case REG_TYPE_UNKNOWN:
230 switch (vstack_bx(stack)->type) {
231 default:
232 case REG_DOUBLE:
233 goto error_type;
234 case REG_TYPE_UNKNOWN:
235 case REG_STRING:
236 case REG_STAR_GLOB_STRING:
237 case REG_S64:
238 goto unknown;
239 }
240 break;
241 case REG_S64:
242 switch (vstack_bx(stack)->type) {
243 default:
244 case REG_DOUBLE:
245 goto error_type;
246 case REG_TYPE_UNKNOWN:
247 goto unknown;
248 case REG_S64:
249 break;
250 }
251 break;
252 }
253 return 0;
254
255unknown:
256 return 1;
257
258error_empty:
259 printk(KERN_WARNING "empty stack for '%s' binary operator\n", str);
260 return -EINVAL;
261
262error_type:
263 printk(KERN_WARNING "unknown type for '%s' binary operator\n", str);
264 return -EINVAL;
265}
266
267static
268int validate_get_symbol(struct bytecode_runtime *bytecode,
269 const struct get_symbol *sym)
270{
271 const char *str, *str_limit;
272 size_t len_limit;
273
274 if (sym->offset >= bytecode->p.bc->bc.len - bytecode->p.bc->bc.reloc_offset)
275 return -EINVAL;
276
277 str = bytecode->p.bc->bc.data + bytecode->p.bc->bc.reloc_offset + sym->offset;
278 str_limit = bytecode->p.bc->bc.data + bytecode->p.bc->bc.len;
279 len_limit = str_limit - str;
280 if (strnlen(str, len_limit) == len_limit)
281 return -EINVAL;
282 return 0;
07dfc1d0
MD
283}
284
285/*
286 * Validate bytecode range overflow within the validation pass.
287 * Called for each instruction encountered.
288 */
289static
290int bytecode_validate_overflow(struct bytecode_runtime *bytecode,
7962cb86 291 char *start_pc, char *pc)
07dfc1d0
MD
292{
293 int ret = 0;
294
295 switch (*(filter_opcode_t *) pc) {
296 case FILTER_OP_UNKNOWN:
297 default:
298 {
299 printk(KERN_WARNING "unknown bytecode op %u\n",
300 (unsigned int) *(filter_opcode_t *) pc);
301 ret = -EINVAL;
302 break;
303 }
304
305 case FILTER_OP_RETURN:
57ba4b41 306 case FILTER_OP_RETURN_S64:
07dfc1d0
MD
307 {
308 if (unlikely(pc + sizeof(struct return_op)
309 > start_pc + bytecode->len)) {
310 ret = -ERANGE;
311 }
312 break;
313 }
314
315 /* binary */
316 case FILTER_OP_MUL:
317 case FILTER_OP_DIV:
318 case FILTER_OP_MOD:
319 case FILTER_OP_PLUS:
320 case FILTER_OP_MINUS:
07dfc1d0
MD
321 case FILTER_OP_EQ_DOUBLE:
322 case FILTER_OP_NE_DOUBLE:
323 case FILTER_OP_GT_DOUBLE:
324 case FILTER_OP_LT_DOUBLE:
325 case FILTER_OP_GE_DOUBLE:
326 case FILTER_OP_LE_DOUBLE:
327 /* Floating point */
328 case FILTER_OP_EQ_DOUBLE_S64:
329 case FILTER_OP_NE_DOUBLE_S64:
330 case FILTER_OP_GT_DOUBLE_S64:
331 case FILTER_OP_LT_DOUBLE_S64:
332 case FILTER_OP_GE_DOUBLE_S64:
333 case FILTER_OP_LE_DOUBLE_S64:
334 case FILTER_OP_EQ_S64_DOUBLE:
335 case FILTER_OP_NE_S64_DOUBLE:
336 case FILTER_OP_GT_S64_DOUBLE:
337 case FILTER_OP_LT_S64_DOUBLE:
338 case FILTER_OP_GE_S64_DOUBLE:
339 case FILTER_OP_LE_S64_DOUBLE:
340 case FILTER_OP_LOAD_FIELD_REF_DOUBLE:
341 case FILTER_OP_GET_CONTEXT_REF_DOUBLE:
342 case FILTER_OP_LOAD_DOUBLE:
343 case FILTER_OP_CAST_DOUBLE_TO_S64:
344 case FILTER_OP_UNARY_PLUS_DOUBLE:
345 case FILTER_OP_UNARY_MINUS_DOUBLE:
346 case FILTER_OP_UNARY_NOT_DOUBLE:
347 {
348 printk(KERN_WARNING "unsupported bytecode op %u\n",
349 (unsigned int) *(filter_opcode_t *) pc);
350 ret = -EINVAL;
351 break;
352 }
353
354 case FILTER_OP_EQ:
355 case FILTER_OP_NE:
356 case FILTER_OP_GT:
357 case FILTER_OP_LT:
358 case FILTER_OP_GE:
359 case FILTER_OP_LE:
360 case FILTER_OP_EQ_STRING:
361 case FILTER_OP_NE_STRING:
362 case FILTER_OP_GT_STRING:
363 case FILTER_OP_LT_STRING:
364 case FILTER_OP_GE_STRING:
365 case FILTER_OP_LE_STRING:
02aca193
PP
366 case FILTER_OP_EQ_STAR_GLOB_STRING:
367 case FILTER_OP_NE_STAR_GLOB_STRING:
07dfc1d0
MD
368 case FILTER_OP_EQ_S64:
369 case FILTER_OP_NE_S64:
370 case FILTER_OP_GT_S64:
371 case FILTER_OP_LT_S64:
372 case FILTER_OP_GE_S64:
373 case FILTER_OP_LE_S64:
e16c054b
MD
374 case FILTER_OP_BIT_RSHIFT:
375 case FILTER_OP_BIT_LSHIFT:
3834b99f
MD
376 case FILTER_OP_BIT_AND:
377 case FILTER_OP_BIT_OR:
378 case FILTER_OP_BIT_XOR:
07dfc1d0
MD
379 {
380 if (unlikely(pc + sizeof(struct binary_op)
381 > start_pc + bytecode->len)) {
382 ret = -ERANGE;
383 }
384 break;
385 }
386
387 /* unary */
388 case FILTER_OP_UNARY_PLUS:
389 case FILTER_OP_UNARY_MINUS:
390 case FILTER_OP_UNARY_NOT:
391 case FILTER_OP_UNARY_PLUS_S64:
392 case FILTER_OP_UNARY_MINUS_S64:
393 case FILTER_OP_UNARY_NOT_S64:
e16c054b 394 case FILTER_OP_UNARY_BIT_NOT:
07dfc1d0
MD
395 {
396 if (unlikely(pc + sizeof(struct unary_op)
397 > start_pc + bytecode->len)) {
398 ret = -ERANGE;
399 }
400 break;
401 }
402
403 /* logical */
404 case FILTER_OP_AND:
405 case FILTER_OP_OR:
406 {
407 if (unlikely(pc + sizeof(struct logical_op)
408 > start_pc + bytecode->len)) {
409 ret = -ERANGE;
410 }
411 break;
412 }
413
414 /* load field ref */
415 case FILTER_OP_LOAD_FIELD_REF:
416 {
417 printk(KERN_WARNING "Unknown field ref type\n");
418 ret = -EINVAL;
419 break;
420 }
3834b99f 421
07dfc1d0
MD
422 /* get context ref */
423 case FILTER_OP_GET_CONTEXT_REF:
424 {
425 printk(KERN_WARNING "Unknown field ref type\n");
426 ret = -EINVAL;
427 break;
428 }
429 case FILTER_OP_LOAD_FIELD_REF_STRING:
430 case FILTER_OP_LOAD_FIELD_REF_SEQUENCE:
f127e61e
MD
431 case FILTER_OP_LOAD_FIELD_REF_USER_STRING:
432 case FILTER_OP_LOAD_FIELD_REF_USER_SEQUENCE:
07dfc1d0
MD
433 case FILTER_OP_LOAD_FIELD_REF_S64:
434 case FILTER_OP_GET_CONTEXT_REF_STRING:
435 case FILTER_OP_GET_CONTEXT_REF_S64:
436 {
437 if (unlikely(pc + sizeof(struct load_op) + sizeof(struct field_ref)
438 > start_pc + bytecode->len)) {
439 ret = -ERANGE;
440 }
441 break;
442 }
443
444 /* load from immediate operand */
445 case FILTER_OP_LOAD_STRING:
02aca193 446 case FILTER_OP_LOAD_STAR_GLOB_STRING:
07dfc1d0
MD
447 {
448 struct load_op *insn = (struct load_op *) pc;
449 uint32_t str_len, maxlen;
450
451 if (unlikely(pc + sizeof(struct load_op)
452 > start_pc + bytecode->len)) {
453 ret = -ERANGE;
454 break;
455 }
456
457 maxlen = start_pc + bytecode->len - pc - sizeof(struct load_op);
458 str_len = strnlen(insn->data, maxlen);
459 if (unlikely(str_len >= maxlen)) {
460 /* Final '\0' not found within range */
461 ret = -ERANGE;
462 }
463 break;
464 }
465
466 case FILTER_OP_LOAD_S64:
467 {
468 if (unlikely(pc + sizeof(struct load_op) + sizeof(struct literal_numeric)
469 > start_pc + bytecode->len)) {
470 ret = -ERANGE;
471 }
472 break;
473 }
474
475 case FILTER_OP_CAST_TO_S64:
476 case FILTER_OP_CAST_NOP:
477 {
478 if (unlikely(pc + sizeof(struct cast_op)
479 > start_pc + bytecode->len)) {
480 ret = -ERANGE;
481 }
482 break;
483 }
484
3834b99f
MD
485 /*
486 * Instructions for recursive traversal through composed types.
487 */
488 case FILTER_OP_GET_CONTEXT_ROOT:
489 case FILTER_OP_GET_APP_CONTEXT_ROOT:
490 case FILTER_OP_GET_PAYLOAD_ROOT:
491 case FILTER_OP_LOAD_FIELD:
492 case FILTER_OP_LOAD_FIELD_S8:
493 case FILTER_OP_LOAD_FIELD_S16:
494 case FILTER_OP_LOAD_FIELD_S32:
495 case FILTER_OP_LOAD_FIELD_S64:
496 case FILTER_OP_LOAD_FIELD_U8:
497 case FILTER_OP_LOAD_FIELD_U16:
498 case FILTER_OP_LOAD_FIELD_U32:
499 case FILTER_OP_LOAD_FIELD_U64:
500 case FILTER_OP_LOAD_FIELD_STRING:
501 case FILTER_OP_LOAD_FIELD_SEQUENCE:
502 case FILTER_OP_LOAD_FIELD_DOUBLE:
503 if (unlikely(pc + sizeof(struct load_op)
504 > start_pc + bytecode->len)) {
505 ret = -ERANGE;
506 }
507 break;
508
509 case FILTER_OP_GET_SYMBOL:
510 {
511 struct load_op *insn = (struct load_op *) pc;
512 struct get_symbol *sym = (struct get_symbol *) insn->data;
513
514 if (unlikely(pc + sizeof(struct load_op) + sizeof(struct get_symbol)
515 > start_pc + bytecode->len)) {
516 ret = -ERANGE;
3aeca857 517 break;
3834b99f
MD
518 }
519 ret = validate_get_symbol(bytecode, sym);
520 break;
521 }
522
523 case FILTER_OP_GET_SYMBOL_FIELD:
524 printk(KERN_WARNING "Unexpected get symbol field\n");
525 ret = -EINVAL;
526 break;
527
528 case FILTER_OP_GET_INDEX_U16:
529 if (unlikely(pc + sizeof(struct load_op) + sizeof(struct get_index_u16)
530 > start_pc + bytecode->len)) {
531 ret = -ERANGE;
532 }
533 break;
534
535 case FILTER_OP_GET_INDEX_U64:
536 if (unlikely(pc + sizeof(struct load_op) + sizeof(struct get_index_u64)
537 > start_pc + bytecode->len)) {
538 ret = -ERANGE;
539 }
540 break;
07dfc1d0
MD
541 }
542
543 return ret;
544}
545
546static
547unsigned long delete_all_nodes(struct mp_table *mp_table)
548{
549 struct mp_node *mp_node;
550 struct hlist_node *tmp;
551 unsigned long nr_nodes = 0;
552 int i;
553
554 for (i = 0; i < MERGE_POINT_TABLE_SIZE; i++) {
555 struct hlist_head *head;
556
557 head = &mp_table->mp_head[i];
d216ecae 558 lttng_hlist_for_each_entry_safe(mp_node, tmp, head, node) {
07dfc1d0
MD
559 kfree(mp_node);
560 nr_nodes++;
561 }
562 }
563 return nr_nodes;
564}
565
566/*
567 * Return value:
3834b99f 568 * >=0: success
07dfc1d0
MD
569 * <0: error
570 */
571static
572int validate_instruction_context(struct bytecode_runtime *bytecode,
573 struct vstack *stack,
7962cb86
MD
574 char *start_pc,
575 char *pc)
07dfc1d0
MD
576{
577 int ret = 0;
02aca193 578 const filter_opcode_t opcode = *(filter_opcode_t *) pc;
07dfc1d0 579
02aca193 580 switch (opcode) {
07dfc1d0
MD
581 case FILTER_OP_UNKNOWN:
582 default:
583 {
584 printk(KERN_WARNING "unknown bytecode op %u\n",
585 (unsigned int) *(filter_opcode_t *) pc);
586 ret = -EINVAL;
587 goto end;
588 }
589
590 case FILTER_OP_RETURN:
57ba4b41 591 case FILTER_OP_RETURN_S64:
07dfc1d0
MD
592 {
593 goto end;
594 }
595
596 /* binary */
597 case FILTER_OP_MUL:
598 case FILTER_OP_DIV:
599 case FILTER_OP_MOD:
600 case FILTER_OP_PLUS:
601 case FILTER_OP_MINUS:
07dfc1d0
MD
602 /* Floating point */
603 case FILTER_OP_EQ_DOUBLE:
604 case FILTER_OP_NE_DOUBLE:
605 case FILTER_OP_GT_DOUBLE:
606 case FILTER_OP_LT_DOUBLE:
607 case FILTER_OP_GE_DOUBLE:
608 case FILTER_OP_LE_DOUBLE:
609 case FILTER_OP_EQ_DOUBLE_S64:
610 case FILTER_OP_NE_DOUBLE_S64:
611 case FILTER_OP_GT_DOUBLE_S64:
612 case FILTER_OP_LT_DOUBLE_S64:
613 case FILTER_OP_GE_DOUBLE_S64:
614 case FILTER_OP_LE_DOUBLE_S64:
615 case FILTER_OP_EQ_S64_DOUBLE:
616 case FILTER_OP_NE_S64_DOUBLE:
617 case FILTER_OP_GT_S64_DOUBLE:
618 case FILTER_OP_LT_S64_DOUBLE:
619 case FILTER_OP_GE_S64_DOUBLE:
620 case FILTER_OP_LE_S64_DOUBLE:
621 case FILTER_OP_UNARY_PLUS_DOUBLE:
622 case FILTER_OP_UNARY_MINUS_DOUBLE:
623 case FILTER_OP_UNARY_NOT_DOUBLE:
624 case FILTER_OP_LOAD_FIELD_REF_DOUBLE:
625 case FILTER_OP_LOAD_DOUBLE:
626 case FILTER_OP_CAST_DOUBLE_TO_S64:
627 case FILTER_OP_GET_CONTEXT_REF_DOUBLE:
628 {
629 printk(KERN_WARNING "unsupported bytecode op %u\n",
630 (unsigned int) *(filter_opcode_t *) pc);
631 ret = -EINVAL;
632 goto end;
633 }
634
635 case FILTER_OP_EQ:
636 {
02aca193 637 ret = bin_op_compare_check(stack, opcode, "==");
3834b99f 638 if (ret < 0)
07dfc1d0
MD
639 goto end;
640 break;
641 }
642 case FILTER_OP_NE:
643 {
02aca193 644 ret = bin_op_compare_check(stack, opcode, "!=");
3834b99f 645 if (ret < 0)
07dfc1d0
MD
646 goto end;
647 break;
648 }
649 case FILTER_OP_GT:
650 {
02aca193 651 ret = bin_op_compare_check(stack, opcode, ">");
3834b99f 652 if (ret < 0)
07dfc1d0
MD
653 goto end;
654 break;
655 }
656 case FILTER_OP_LT:
657 {
02aca193 658 ret = bin_op_compare_check(stack, opcode, "<");
3834b99f 659 if (ret < 0)
07dfc1d0
MD
660 goto end;
661 break;
662 }
663 case FILTER_OP_GE:
664 {
02aca193 665 ret = bin_op_compare_check(stack, opcode, ">=");
3834b99f 666 if (ret < 0)
07dfc1d0
MD
667 goto end;
668 break;
669 }
670 case FILTER_OP_LE:
671 {
02aca193 672 ret = bin_op_compare_check(stack, opcode, "<=");
3834b99f 673 if (ret < 0)
07dfc1d0
MD
674 goto end;
675 break;
676 }
677
678 case FILTER_OP_EQ_STRING:
679 case FILTER_OP_NE_STRING:
680 case FILTER_OP_GT_STRING:
681 case FILTER_OP_LT_STRING:
682 case FILTER_OP_GE_STRING:
683 case FILTER_OP_LE_STRING:
684 {
685 if (!vstack_ax(stack) || !vstack_bx(stack)) {
686 printk(KERN_WARNING "Empty stack\n");
687 ret = -EINVAL;
688 goto end;
689 }
690 if (vstack_ax(stack)->type != REG_STRING
691 || vstack_bx(stack)->type != REG_STRING) {
692 printk(KERN_WARNING "Unexpected register type for string comparator\n");
693 ret = -EINVAL;
694 goto end;
695 }
696 break;
697 }
698
02aca193
PP
699
700 case FILTER_OP_EQ_STAR_GLOB_STRING:
701 case FILTER_OP_NE_STAR_GLOB_STRING:
702 {
703 if (!vstack_ax(stack) || !vstack_bx(stack)) {
704 printk(KERN_WARNING "Empty stack\n");
705 ret = -EINVAL;
706 goto end;
707 }
708 if (vstack_ax(stack)->type != REG_STAR_GLOB_STRING
709 && vstack_bx(stack)->type != REG_STAR_GLOB_STRING) {
710 printk(KERN_WARNING "Unexpected register type for globbing pattern comparator\n");
711 ret = -EINVAL;
712 goto end;
713 }
714 break;
715 }
716
07dfc1d0
MD
717 case FILTER_OP_EQ_S64:
718 case FILTER_OP_NE_S64:
719 case FILTER_OP_GT_S64:
720 case FILTER_OP_LT_S64:
721 case FILTER_OP_GE_S64:
722 case FILTER_OP_LE_S64:
723 {
724 if (!vstack_ax(stack) || !vstack_bx(stack)) {
725 printk(KERN_WARNING "Empty stack\n");
726 ret = -EINVAL;
727 goto end;
728 }
729 if (vstack_ax(stack)->type != REG_S64
730 || vstack_bx(stack)->type != REG_S64) {
731 printk(KERN_WARNING "Unexpected register type for s64 comparator\n");
732 ret = -EINVAL;
733 goto end;
734 }
735 break;
736 }
737
e16c054b
MD
738 case FILTER_OP_BIT_RSHIFT:
739 ret = bin_op_bitwise_check(stack, opcode, ">>");
740 if (ret < 0)
741 goto end;
742 break;
743 case FILTER_OP_BIT_LSHIFT:
744 ret = bin_op_bitwise_check(stack, opcode, "<<");
745 if (ret < 0)
746 goto end;
747 break;
3834b99f
MD
748 case FILTER_OP_BIT_AND:
749 ret = bin_op_bitwise_check(stack, opcode, "&");
750 if (ret < 0)
751 goto end;
752 break;
753 case FILTER_OP_BIT_OR:
754 ret = bin_op_bitwise_check(stack, opcode, "|");
755 if (ret < 0)
756 goto end;
757 break;
758 case FILTER_OP_BIT_XOR:
759 ret = bin_op_bitwise_check(stack, opcode, "^");
760 if (ret < 0)
761 goto end;
762 break;
763
07dfc1d0
MD
764 /* unary */
765 case FILTER_OP_UNARY_PLUS:
766 case FILTER_OP_UNARY_MINUS:
767 case FILTER_OP_UNARY_NOT:
768 {
769 if (!vstack_ax(stack)) {
770 printk(KERN_WARNING "Empty stack\n");
771 ret = -EINVAL;
772 goto end;
773 }
774 switch (vstack_ax(stack)->type) {
775 default:
776 case REG_DOUBLE:
777 printk(KERN_WARNING "unknown register type\n");
778 ret = -EINVAL;
779 goto end;
780
781 case REG_STRING:
02aca193 782 case REG_STAR_GLOB_STRING:
07dfc1d0
MD
783 printk(KERN_WARNING "Unary op can only be applied to numeric or floating point registers\n");
784 ret = -EINVAL;
785 goto end;
786 case REG_S64:
3834b99f 787 case REG_TYPE_UNKNOWN:
07dfc1d0
MD
788 break;
789 }
790 break;
791 }
e16c054b
MD
792 case FILTER_OP_UNARY_BIT_NOT:
793 {
794 if (!vstack_ax(stack)) {
795 printk(KERN_WARNING "Empty stack\n");
796 ret = -EINVAL;
797 goto end;
798 }
799 switch (vstack_ax(stack)->type) {
800 default:
801 printk(KERN_WARNING "unknown register type\n");
802 ret = -EINVAL;
803 goto end;
804
805 case REG_STRING:
806 case REG_STAR_GLOB_STRING:
807 case REG_DOUBLE:
808 printk(KERN_WARNING "Unary bitwise op can only be applied to numeric registers\n");
809 ret = -EINVAL;
810 goto end;
811 case REG_S64:
812 break;
813 case REG_TYPE_UNKNOWN:
814 break;
815 }
816 break;
817 }
07dfc1d0
MD
818
819 case FILTER_OP_UNARY_PLUS_S64:
820 case FILTER_OP_UNARY_MINUS_S64:
821 case FILTER_OP_UNARY_NOT_S64:
822 {
823 if (!vstack_ax(stack)) {
824 printk(KERN_WARNING "Empty stack\n");
825 ret = -EINVAL;
826 goto end;
827 }
828 if (vstack_ax(stack)->type != REG_S64) {
829 printk(KERN_WARNING "Invalid register type\n");
830 ret = -EINVAL;
831 goto end;
832 }
833 break;
834 }
835
836 /* logical */
837 case FILTER_OP_AND:
838 case FILTER_OP_OR:
839 {
840 struct logical_op *insn = (struct logical_op *) pc;
841
842 if (!vstack_ax(stack)) {
843 printk(KERN_WARNING "Empty stack\n");
844 ret = -EINVAL;
845 goto end;
846 }
847 if (vstack_ax(stack)->type != REG_S64) {
848 printk(KERN_WARNING "Logical comparator expects S64 register\n");
849 ret = -EINVAL;
850 goto end;
851 }
852
853 dbg_printk("Validate jumping to bytecode offset %u\n",
854 (unsigned int) insn->skip_offset);
855 if (unlikely(start_pc + insn->skip_offset <= pc)) {
856 printk(KERN_WARNING "Loops are not allowed in bytecode\n");
857 ret = -EINVAL;
858 goto end;
859 }
860 break;
861 }
862
863 /* load field ref */
864 case FILTER_OP_LOAD_FIELD_REF:
865 {
866 printk(KERN_WARNING "Unknown field ref type\n");
867 ret = -EINVAL;
868 goto end;
869 }
870 case FILTER_OP_LOAD_FIELD_REF_STRING:
871 case FILTER_OP_LOAD_FIELD_REF_SEQUENCE:
f127e61e
MD
872 case FILTER_OP_LOAD_FIELD_REF_USER_STRING:
873 case FILTER_OP_LOAD_FIELD_REF_USER_SEQUENCE:
07dfc1d0
MD
874 {
875 struct load_op *insn = (struct load_op *) pc;
876 struct field_ref *ref = (struct field_ref *) insn->data;
877
878 dbg_printk("Validate load field ref offset %u type string\n",
879 ref->offset);
880 break;
881 }
882 case FILTER_OP_LOAD_FIELD_REF_S64:
883 {
884 struct load_op *insn = (struct load_op *) pc;
885 struct field_ref *ref = (struct field_ref *) insn->data;
886
887 dbg_printk("Validate load field ref offset %u type s64\n",
888 ref->offset);
889 break;
890 }
891
892 /* load from immediate operand */
893 case FILTER_OP_LOAD_STRING:
02aca193 894 case FILTER_OP_LOAD_STAR_GLOB_STRING:
07dfc1d0
MD
895 {
896 break;
897 }
898
899 case FILTER_OP_LOAD_S64:
900 {
901 break;
902 }
903
904 case FILTER_OP_CAST_TO_S64:
905 {
906 struct cast_op *insn = (struct cast_op *) pc;
907
908 if (!vstack_ax(stack)) {
909 printk(KERN_WARNING "Empty stack\n");
910 ret = -EINVAL;
911 goto end;
912 }
913 switch (vstack_ax(stack)->type) {
914 default:
915 case REG_DOUBLE:
916 printk(KERN_WARNING "unknown register type\n");
917 ret = -EINVAL;
918 goto end;
919
920 case REG_STRING:
02aca193 921 case REG_STAR_GLOB_STRING:
07dfc1d0
MD
922 printk(KERN_WARNING "Cast op can only be applied to numeric or floating point registers\n");
923 ret = -EINVAL;
924 goto end;
925 case REG_S64:
926 break;
927 }
928 if (insn->op == FILTER_OP_CAST_DOUBLE_TO_S64) {
929 if (vstack_ax(stack)->type != REG_DOUBLE) {
930 printk(KERN_WARNING "Cast expects double\n");
931 ret = -EINVAL;
932 goto end;
933 }
934 }
935 break;
936 }
937 case FILTER_OP_CAST_NOP:
938 {
939 break;
940 }
941
942 /* get context ref */
943 case FILTER_OP_GET_CONTEXT_REF:
944 {
945 printk(KERN_WARNING "Unknown get context ref type\n");
946 ret = -EINVAL;
947 goto end;
948 }
949 case FILTER_OP_GET_CONTEXT_REF_STRING:
950 {
951 struct load_op *insn = (struct load_op *) pc;
952 struct field_ref *ref = (struct field_ref *) insn->data;
953
954 dbg_printk("Validate get context ref offset %u type string\n",
955 ref->offset);
956 break;
957 }
958 case FILTER_OP_GET_CONTEXT_REF_S64:
959 {
960 struct load_op *insn = (struct load_op *) pc;
961 struct field_ref *ref = (struct field_ref *) insn->data;
962
963 dbg_printk("Validate get context ref offset %u type s64\n",
964 ref->offset);
965 break;
966 }
967
3834b99f
MD
968 /*
969 * Instructions for recursive traversal through composed types.
970 */
971 case FILTER_OP_GET_CONTEXT_ROOT:
972 {
973 dbg_printk("Validate get context root\n");
974 break;
975 }
976 case FILTER_OP_GET_APP_CONTEXT_ROOT:
977 {
978 dbg_printk("Validate get app context root\n");
979 break;
980 }
981 case FILTER_OP_GET_PAYLOAD_ROOT:
982 {
983 dbg_printk("Validate get payload root\n");
984 break;
985 }
986 case FILTER_OP_LOAD_FIELD:
987 {
988 /*
989 * We tolerate that field type is unknown at validation,
990 * because we are performing the load specialization in
991 * a phase after validation.
992 */
993 dbg_printk("Validate load field\n");
994 break;
995 }
996 case FILTER_OP_LOAD_FIELD_S8:
997 {
998 dbg_printk("Validate load field s8\n");
999 break;
1000 }
1001 case FILTER_OP_LOAD_FIELD_S16:
1002 {
1003 dbg_printk("Validate load field s16\n");
1004 break;
1005 }
1006 case FILTER_OP_LOAD_FIELD_S32:
1007 {
1008 dbg_printk("Validate load field s32\n");
1009 break;
1010 }
1011 case FILTER_OP_LOAD_FIELD_S64:
1012 {
1013 dbg_printk("Validate load field s64\n");
1014 break;
1015 }
1016 case FILTER_OP_LOAD_FIELD_U8:
1017 {
1018 dbg_printk("Validate load field u8\n");
1019 break;
1020 }
1021 case FILTER_OP_LOAD_FIELD_U16:
1022 {
1023 dbg_printk("Validate load field u16\n");
1024 break;
1025 }
1026 case FILTER_OP_LOAD_FIELD_U32:
1027 {
1028 dbg_printk("Validate load field u32\n");
1029 break;
1030 }
1031 case FILTER_OP_LOAD_FIELD_U64:
1032 {
1033 dbg_printk("Validate load field u64\n");
1034 break;
1035 }
1036 case FILTER_OP_LOAD_FIELD_STRING:
1037 {
1038 dbg_printk("Validate load field string\n");
1039 break;
1040 }
1041 case FILTER_OP_LOAD_FIELD_SEQUENCE:
1042 {
1043 dbg_printk("Validate load field sequence\n");
1044 break;
1045 }
1046 case FILTER_OP_LOAD_FIELD_DOUBLE:
1047 {
1048 dbg_printk("Validate load field double\n");
1049 break;
1050 }
1051
1052 case FILTER_OP_GET_SYMBOL:
1053 {
1054 struct load_op *insn = (struct load_op *) pc;
1055 struct get_symbol *sym = (struct get_symbol *) insn->data;
1056
1057 dbg_printk("Validate get symbol offset %u\n", sym->offset);
1058 break;
1059 }
1060
1061 case FILTER_OP_GET_SYMBOL_FIELD:
1062 {
1063 struct load_op *insn = (struct load_op *) pc;
1064 struct get_symbol *sym = (struct get_symbol *) insn->data;
1065
1066 dbg_printk("Validate get symbol field offset %u\n", sym->offset);
1067 break;
1068 }
1069
1070 case FILTER_OP_GET_INDEX_U16:
1071 {
1072 struct load_op *insn = (struct load_op *) pc;
1073 struct get_index_u16 *get_index = (struct get_index_u16 *) insn->data;
1074
1075 dbg_printk("Validate get index u16 index %u\n", get_index->index);
1076 break;
1077 }
1078
1079 case FILTER_OP_GET_INDEX_U64:
1080 {
1081 struct load_op *insn = (struct load_op *) pc;
1082 struct get_index_u64 *get_index = (struct get_index_u64 *) insn->data;
1083
1084 dbg_printk("Validate get index u64 index %llu\n",
1085 (unsigned long long) get_index->index);
1086 break;
1087 }
07dfc1d0
MD
1088 }
1089end:
1090 return ret;
1091}
1092
1093/*
1094 * Return value:
1095 * 0: success
1096 * <0: error
1097 */
1098static
1099int validate_instruction_all_contexts(struct bytecode_runtime *bytecode,
1100 struct mp_table *mp_table,
1101 struct vstack *stack,
7962cb86
MD
1102 char *start_pc,
1103 char *pc)
07dfc1d0
MD
1104{
1105 int ret, found = 0;
1106 unsigned long target_pc = pc - start_pc;
1107 unsigned long hash;
1108 struct hlist_head *head;
1109 struct mp_node *mp_node;
1110
1111 /* Validate the context resulting from the previous instruction */
1112 ret = validate_instruction_context(bytecode, stack, start_pc, pc);
3834b99f 1113 if (ret < 0)
07dfc1d0
MD
1114 return ret;
1115
1116 /* Validate merge points */
1117 hash = jhash_1word(target_pc, 0);
1118 head = &mp_table->mp_head[hash & (MERGE_POINT_TABLE_SIZE - 1)];
d216ecae 1119 lttng_hlist_for_each_entry(mp_node, head, node) {
07dfc1d0
MD
1120 if (lttng_hash_match(mp_node, target_pc)) {
1121 found = 1;
1122 break;
1123 }
1124 }
1125 if (found) {
1126 dbg_printk("Filter: validate merge point at offset %lu\n",
1127 target_pc);
1128 if (merge_points_compare(stack, &mp_node->stack)) {
1129 printk(KERN_WARNING "Merge points differ for offset %lu\n",
1130 target_pc);
1131 return -EINVAL;
1132 }
1133 /* Once validated, we can remove the merge point */
1134 dbg_printk("Filter: remove merge point at offset %lu\n",
1135 target_pc);
1136 hlist_del(&mp_node->node);
1137 }
1138 return 0;
1139}
1140
1141/*
1142 * Return value:
1143 * >0: going to next insn.
1144 * 0: success, stop iteration.
1145 * <0: error
1146 */
1147static
1148int exec_insn(struct bytecode_runtime *bytecode,
1149 struct mp_table *mp_table,
1150 struct vstack *stack,
7962cb86
MD
1151 char **_next_pc,
1152 char *pc)
07dfc1d0
MD
1153{
1154 int ret = 1;
7962cb86 1155 char *next_pc = *_next_pc;
07dfc1d0
MD
1156
1157 switch (*(filter_opcode_t *) pc) {
1158 case FILTER_OP_UNKNOWN:
1159 default:
1160 {
1161 printk(KERN_WARNING "unknown bytecode op %u\n",
1162 (unsigned int) *(filter_opcode_t *) pc);
1163 ret = -EINVAL;
1164 goto end;
1165 }
1166
1167 case FILTER_OP_RETURN:
1168 {
1169 if (!vstack_ax(stack)) {
1170 printk(KERN_WARNING "Empty stack\n");
1171 ret = -EINVAL;
1172 goto end;
1173 }
3834b99f
MD
1174 switch (vstack_ax(stack)->type) {
1175 case REG_S64:
1176 case REG_TYPE_UNKNOWN:
1177 break;
1178 default:
1179 printk(KERN_WARNING "Unexpected register type %d at end of bytecode\n",
1180 (int) vstack_ax(stack)->type);
1181 ret = -EINVAL;
1182 goto end;
1183 }
1184
07dfc1d0
MD
1185 ret = 0;
1186 goto end;
1187 }
1188
57ba4b41
MD
1189 case FILTER_OP_RETURN_S64:
1190 {
1191 if (!vstack_ax(stack)) {
1192 printk(KERN_WARNING "Empty stack\n");
1193 ret = -EINVAL;
1194 goto end;
1195 }
1196 switch (vstack_ax(stack)->type) {
1197 case REG_S64:
1198 break;
1199 default:
1200 case REG_TYPE_UNKNOWN:
1201 printk(KERN_WARNING "Unexpected register type %d at end of bytecode\n",
1202 (int) vstack_ax(stack)->type);
1203 ret = -EINVAL;
1204 goto end;
1205 }
1206
1207 ret = 0;
1208 goto end;
1209 }
1210
07dfc1d0
MD
1211 /* binary */
1212 case FILTER_OP_MUL:
1213 case FILTER_OP_DIV:
1214 case FILTER_OP_MOD:
1215 case FILTER_OP_PLUS:
1216 case FILTER_OP_MINUS:
07dfc1d0
MD
1217 /* Floating point */
1218 case FILTER_OP_EQ_DOUBLE:
1219 case FILTER_OP_NE_DOUBLE:
1220 case FILTER_OP_GT_DOUBLE:
1221 case FILTER_OP_LT_DOUBLE:
1222 case FILTER_OP_GE_DOUBLE:
1223 case FILTER_OP_LE_DOUBLE:
1224 case FILTER_OP_EQ_DOUBLE_S64:
1225 case FILTER_OP_NE_DOUBLE_S64:
1226 case FILTER_OP_GT_DOUBLE_S64:
1227 case FILTER_OP_LT_DOUBLE_S64:
1228 case FILTER_OP_GE_DOUBLE_S64:
1229 case FILTER_OP_LE_DOUBLE_S64:
1230 case FILTER_OP_EQ_S64_DOUBLE:
1231 case FILTER_OP_NE_S64_DOUBLE:
1232 case FILTER_OP_GT_S64_DOUBLE:
1233 case FILTER_OP_LT_S64_DOUBLE:
1234 case FILTER_OP_GE_S64_DOUBLE:
1235 case FILTER_OP_LE_S64_DOUBLE:
1236 case FILTER_OP_UNARY_PLUS_DOUBLE:
1237 case FILTER_OP_UNARY_MINUS_DOUBLE:
1238 case FILTER_OP_UNARY_NOT_DOUBLE:
1239 case FILTER_OP_LOAD_FIELD_REF_DOUBLE:
1240 case FILTER_OP_GET_CONTEXT_REF_DOUBLE:
1241 case FILTER_OP_LOAD_DOUBLE:
1242 case FILTER_OP_CAST_DOUBLE_TO_S64:
1243 {
1244 printk(KERN_WARNING "unsupported bytecode op %u\n",
1245 (unsigned int) *(filter_opcode_t *) pc);
1246 ret = -EINVAL;
1247 goto end;
1248 }
1249
1250 case FILTER_OP_EQ:
1251 case FILTER_OP_NE:
1252 case FILTER_OP_GT:
1253 case FILTER_OP_LT:
1254 case FILTER_OP_GE:
1255 case FILTER_OP_LE:
1256 case FILTER_OP_EQ_STRING:
1257 case FILTER_OP_NE_STRING:
1258 case FILTER_OP_GT_STRING:
1259 case FILTER_OP_LT_STRING:
1260 case FILTER_OP_GE_STRING:
1261 case FILTER_OP_LE_STRING:
02aca193
PP
1262 case FILTER_OP_EQ_STAR_GLOB_STRING:
1263 case FILTER_OP_NE_STAR_GLOB_STRING:
07dfc1d0
MD
1264 case FILTER_OP_EQ_S64:
1265 case FILTER_OP_NE_S64:
1266 case FILTER_OP_GT_S64:
1267 case FILTER_OP_LT_S64:
1268 case FILTER_OP_GE_S64:
1269 case FILTER_OP_LE_S64:
e16c054b
MD
1270 case FILTER_OP_BIT_RSHIFT:
1271 case FILTER_OP_BIT_LSHIFT:
3834b99f
MD
1272 case FILTER_OP_BIT_AND:
1273 case FILTER_OP_BIT_OR:
1274 case FILTER_OP_BIT_XOR:
07dfc1d0
MD
1275 {
1276 /* Pop 2, push 1 */
1277 if (vstack_pop(stack)) {
1278 ret = -EINVAL;
1279 goto end;
1280 }
1281 if (!vstack_ax(stack)) {
1282 printk(KERN_WARNING "Empty stack\n");
1283 ret = -EINVAL;
1284 goto end;
1285 }
3834b99f
MD
1286 switch (vstack_ax(stack)->type) {
1287 case REG_S64:
1288 case REG_DOUBLE:
1289 case REG_STRING:
1290 case REG_STAR_GLOB_STRING:
1291 case REG_TYPE_UNKNOWN:
1292 break;
1293 default:
1294 printk(KERN_WARNING "Unexpected register type %d for operation\n",
1295 (int) vstack_ax(stack)->type);
1296 ret = -EINVAL;
1297 goto end;
1298 }
1299
07dfc1d0
MD
1300 vstack_ax(stack)->type = REG_S64;
1301 next_pc += sizeof(struct binary_op);
1302 break;
1303 }
1304
1305 /* unary */
1306 case FILTER_OP_UNARY_PLUS:
1307 case FILTER_OP_UNARY_MINUS:
3834b99f
MD
1308 {
1309 /* Pop 1, push 1 */
1310 if (!vstack_ax(stack)) {
1311 printk(KERN_WARNING "Empty stack\n\n");
1312 ret = -EINVAL;
1313 goto end;
1314 }
1315 switch (vstack_ax(stack)->type) {
1316 case REG_S64:
1317 case REG_TYPE_UNKNOWN:
1318 break;
1319 default:
1320 printk(KERN_WARNING "Unexpected register type %d for operation\n",
1321 (int) vstack_ax(stack)->type);
1322 ret = -EINVAL;
1323 goto end;
1324 }
1325
1326 vstack_ax(stack)->type = REG_TYPE_UNKNOWN;
1327 next_pc += sizeof(struct unary_op);
1328 break;
1329 }
1330
07dfc1d0
MD
1331 case FILTER_OP_UNARY_PLUS_S64:
1332 case FILTER_OP_UNARY_MINUS_S64:
1333 case FILTER_OP_UNARY_NOT_S64:
1334 {
1335 /* Pop 1, push 1 */
1336 if (!vstack_ax(stack)) {
3834b99f
MD
1337 printk(KERN_WARNING "Empty stack\n\n");
1338 ret = -EINVAL;
1339 goto end;
1340 }
1341 switch (vstack_ax(stack)->type) {
1342 case REG_S64:
1343 break;
1344 default:
1345 printk(KERN_WARNING "Unexpected register type %d for operation\n",
1346 (int) vstack_ax(stack)->type);
1347 ret = -EINVAL;
1348 goto end;
1349 }
1350
1351 vstack_ax(stack)->type = REG_S64;
1352 next_pc += sizeof(struct unary_op);
1353 break;
1354 }
1355
1356 case FILTER_OP_UNARY_NOT:
1357 {
1358 /* Pop 1, push 1 */
1359 if (!vstack_ax(stack)) {
1360 printk(KERN_WARNING "Empty stack\n\n");
1361 ret = -EINVAL;
1362 goto end;
1363 }
1364 switch (vstack_ax(stack)->type) {
1365 case REG_S64:
1366 case REG_TYPE_UNKNOWN:
1367 break;
1368 default:
1369 printk(KERN_WARNING "Unexpected register type %d for operation\n",
e16c054b
MD
1370 (int) vstack_ax(stack)->type);
1371 ret = -EINVAL;
1372 goto end;
1373 }
1374
1375 vstack_ax(stack)->type = REG_S64;
1376 next_pc += sizeof(struct unary_op);
1377 break;
1378 }
1379
1380 case FILTER_OP_UNARY_BIT_NOT:
1381 {
1382 /* Pop 1, push 1 */
1383 if (!vstack_ax(stack)) {
1384 printk(KERN_WARNING "Empty stack\n");
1385 ret = -EINVAL;
1386 goto end;
1387 }
1388 switch (vstack_ax(stack)->type) {
1389 case REG_S64:
1390 case REG_TYPE_UNKNOWN:
1391 break;
1392 case REG_DOUBLE:
1393 default:
1394 printk(KERN_WARNING "Unexpected register type %d for operation\n",
3834b99f 1395 (int) vstack_ax(stack)->type);
07dfc1d0
MD
1396 ret = -EINVAL;
1397 goto end;
1398 }
3834b99f 1399
07dfc1d0
MD
1400 vstack_ax(stack)->type = REG_S64;
1401 next_pc += sizeof(struct unary_op);
1402 break;
1403 }
1404
1405 /* logical */
1406 case FILTER_OP_AND:
1407 case FILTER_OP_OR:
1408 {
1409 struct logical_op *insn = (struct logical_op *) pc;
1410 int merge_ret;
1411
1412 /* Add merge point to table */
1413 merge_ret = merge_point_add_check(mp_table,
1414 insn->skip_offset, stack);
1415 if (merge_ret) {
1416 ret = merge_ret;
1417 goto end;
1418 }
3834b99f
MD
1419
1420 if (!vstack_ax(stack)) {
1421 printk(KERN_WARNING "Empty stack\n\n");
1422 ret = -EINVAL;
1423 goto end;
1424 }
1425 /* There is always a cast-to-s64 operation before a or/and op. */
1426 switch (vstack_ax(stack)->type) {
1427 case REG_S64:
1428 break;
1429 default:
1430 printk(KERN_WARNING "Incorrect register type %d for operation\n",
1431 (int) vstack_ax(stack)->type);
1432 ret = -EINVAL;
1433 goto end;
1434 }
1435
07dfc1d0
MD
1436 /* Continue to next instruction */
1437 /* Pop 1 when jump not taken */
1438 if (vstack_pop(stack)) {
1439 ret = -EINVAL;
1440 goto end;
1441 }
1442 next_pc += sizeof(struct logical_op);
1443 break;
1444 }
1445
1446 /* load field ref */
1447 case FILTER_OP_LOAD_FIELD_REF:
1448 {
1449 printk(KERN_WARNING "Unknown field ref type\n");
1450 ret = -EINVAL;
1451 goto end;
1452 }
1453 /* get context ref */
1454 case FILTER_OP_GET_CONTEXT_REF:
1455 {
1456 printk(KERN_WARNING "Unknown get context ref type\n");
1457 ret = -EINVAL;
1458 goto end;
1459 }
1460 case FILTER_OP_LOAD_FIELD_REF_STRING:
1461 case FILTER_OP_LOAD_FIELD_REF_SEQUENCE:
1462 case FILTER_OP_GET_CONTEXT_REF_STRING:
f127e61e
MD
1463 case FILTER_OP_LOAD_FIELD_REF_USER_STRING:
1464 case FILTER_OP_LOAD_FIELD_REF_USER_SEQUENCE:
07dfc1d0
MD
1465 {
1466 if (vstack_push(stack)) {
1467 ret = -EINVAL;
1468 goto end;
1469 }
1470 vstack_ax(stack)->type = REG_STRING;
1471 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1472 break;
1473 }
1474 case FILTER_OP_LOAD_FIELD_REF_S64:
1475 case FILTER_OP_GET_CONTEXT_REF_S64:
1476 {
1477 if (vstack_push(stack)) {
1478 ret = -EINVAL;
1479 goto end;
1480 }
1481 vstack_ax(stack)->type = REG_S64;
1482 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1483 break;
1484 }
1485
1486 /* load from immediate operand */
1487 case FILTER_OP_LOAD_STRING:
1488 {
1489 struct load_op *insn = (struct load_op *) pc;
1490
1491 if (vstack_push(stack)) {
1492 ret = -EINVAL;
1493 goto end;
1494 }
1495 vstack_ax(stack)->type = REG_STRING;
1496 next_pc += sizeof(struct load_op) + strlen(insn->data) + 1;
02aca193
PP
1497 break;
1498 }
1499
1500 case FILTER_OP_LOAD_STAR_GLOB_STRING:
1501 {
1502 struct load_op *insn = (struct load_op *) pc;
1503
1504 if (vstack_push(stack)) {
1505 ret = -EINVAL;
1506 goto end;
1507 }
1508 vstack_ax(stack)->type = REG_STAR_GLOB_STRING;
1509 next_pc += sizeof(struct load_op) + strlen(insn->data) + 1;
07dfc1d0
MD
1510 break;
1511 }
1512
1513 case FILTER_OP_LOAD_S64:
1514 {
1515 if (vstack_push(stack)) {
1516 ret = -EINVAL;
1517 goto end;
1518 }
1519 vstack_ax(stack)->type = REG_S64;
1520 next_pc += sizeof(struct load_op)
1521 + sizeof(struct literal_numeric);
1522 break;
1523 }
1524
1525 case FILTER_OP_CAST_TO_S64:
1526 {
1527 /* Pop 1, push 1 */
1528 if (!vstack_ax(stack)) {
1529 printk(KERN_WARNING "Empty stack\n");
1530 ret = -EINVAL;
1531 goto end;
1532 }
3834b99f
MD
1533 switch (vstack_ax(stack)->type) {
1534 case REG_S64:
1535 case REG_DOUBLE:
1536 case REG_TYPE_UNKNOWN:
1537 break;
1538 default:
1539 printk(KERN_WARNING "Incorrect register type %d for cast\n",
1540 (int) vstack_ax(stack)->type);
1541 ret = -EINVAL;
1542 goto end;
1543 }
07dfc1d0
MD
1544 vstack_ax(stack)->type = REG_S64;
1545 next_pc += sizeof(struct cast_op);
1546 break;
1547 }
1548 case FILTER_OP_CAST_NOP:
1549 {
1550 next_pc += sizeof(struct cast_op);
1551 break;
1552 }
1553
3834b99f
MD
1554 /*
1555 * Instructions for recursive traversal through composed types.
1556 */
1557 case FILTER_OP_GET_CONTEXT_ROOT:
1558 case FILTER_OP_GET_APP_CONTEXT_ROOT:
1559 case FILTER_OP_GET_PAYLOAD_ROOT:
1560 {
1561 if (vstack_push(stack)) {
1562 ret = -EINVAL;
1563 goto end;
1564 }
1565 vstack_ax(stack)->type = REG_PTR;
1566 next_pc += sizeof(struct load_op);
1567 break;
1568 }
1569
1570 case FILTER_OP_LOAD_FIELD:
1571 {
1572 /* Pop 1, push 1 */
1573 if (!vstack_ax(stack)) {
1574 printk(KERN_WARNING "Empty stack\n\n");
1575 ret = -EINVAL;
1576 goto end;
1577 }
1578 if (vstack_ax(stack)->type != REG_PTR) {
1579 printk(KERN_WARNING "Expecting pointer on top of stack\n\n");
1580 ret = -EINVAL;
1581 goto end;
1582 }
1583 vstack_ax(stack)->type = REG_TYPE_UNKNOWN;
1584 next_pc += sizeof(struct load_op);
1585 break;
1586 }
1587
1588 case FILTER_OP_LOAD_FIELD_S8:
1589 case FILTER_OP_LOAD_FIELD_S16:
1590 case FILTER_OP_LOAD_FIELD_S32:
1591 case FILTER_OP_LOAD_FIELD_S64:
1592 case FILTER_OP_LOAD_FIELD_U8:
1593 case FILTER_OP_LOAD_FIELD_U16:
1594 case FILTER_OP_LOAD_FIELD_U32:
1595 case FILTER_OP_LOAD_FIELD_U64:
1596 {
1597 /* Pop 1, push 1 */
1598 if (!vstack_ax(stack)) {
1599 printk(KERN_WARNING "Empty stack\n\n");
1600 ret = -EINVAL;
1601 goto end;
1602 }
1603 if (vstack_ax(stack)->type != REG_PTR) {
1604 printk(KERN_WARNING "Expecting pointer on top of stack\n\n");
1605 ret = -EINVAL;
1606 goto end;
1607 }
1608 vstack_ax(stack)->type = REG_S64;
1609 next_pc += sizeof(struct load_op);
1610 break;
1611 }
1612
1613 case FILTER_OP_LOAD_FIELD_STRING:
1614 case FILTER_OP_LOAD_FIELD_SEQUENCE:
1615 {
1616 /* Pop 1, push 1 */
1617 if (!vstack_ax(stack)) {
1618 printk(KERN_WARNING "Empty stack\n\n");
1619 ret = -EINVAL;
1620 goto end;
1621 }
1622 if (vstack_ax(stack)->type != REG_PTR) {
1623 printk(KERN_WARNING "Expecting pointer on top of stack\n\n");
1624 ret = -EINVAL;
1625 goto end;
1626 }
1627 vstack_ax(stack)->type = REG_STRING;
1628 next_pc += sizeof(struct load_op);
1629 break;
1630 }
1631
1632 case FILTER_OP_LOAD_FIELD_DOUBLE:
1633 {
1634 /* Pop 1, push 1 */
1635 if (!vstack_ax(stack)) {
1636 printk(KERN_WARNING "Empty stack\n\n");
1637 ret = -EINVAL;
1638 goto end;
1639 }
1640 if (vstack_ax(stack)->type != REG_PTR) {
1641 printk(KERN_WARNING "Expecting pointer on top of stack\n\n");
1642 ret = -EINVAL;
1643 goto end;
1644 }
1645 vstack_ax(stack)->type = REG_DOUBLE;
1646 next_pc += sizeof(struct load_op);
1647 break;
1648 }
1649
1650 case FILTER_OP_GET_SYMBOL:
1651 case FILTER_OP_GET_SYMBOL_FIELD:
1652 {
1653 /* Pop 1, push 1 */
1654 if (!vstack_ax(stack)) {
1655 printk(KERN_WARNING "Empty stack\n\n");
1656 ret = -EINVAL;
1657 goto end;
1658 }
1659 if (vstack_ax(stack)->type != REG_PTR) {
1660 printk(KERN_WARNING "Expecting pointer on top of stack\n\n");
1661 ret = -EINVAL;
1662 goto end;
1663 }
1664 next_pc += sizeof(struct load_op) + sizeof(struct get_symbol);
1665 break;
1666 }
1667
1668 case FILTER_OP_GET_INDEX_U16:
1669 {
1670 /* Pop 1, push 1 */
1671 if (!vstack_ax(stack)) {
1672 printk(KERN_WARNING "Empty stack\n\n");
1673 ret = -EINVAL;
1674 goto end;
1675 }
1676 if (vstack_ax(stack)->type != REG_PTR) {
1677 printk(KERN_WARNING "Expecting pointer on top of stack\n\n");
1678 ret = -EINVAL;
1679 goto end;
1680 }
1681 next_pc += sizeof(struct load_op) + sizeof(struct get_index_u16);
1682 break;
1683 }
1684
1685 case FILTER_OP_GET_INDEX_U64:
1686 {
1687 /* Pop 1, push 1 */
1688 if (!vstack_ax(stack)) {
1689 printk(KERN_WARNING "Empty stack\n\n");
1690 ret = -EINVAL;
1691 goto end;
1692 }
1693 if (vstack_ax(stack)->type != REG_PTR) {
1694 printk(KERN_WARNING "Expecting pointer on top of stack\n\n");
1695 ret = -EINVAL;
1696 goto end;
1697 }
1698 next_pc += sizeof(struct load_op) + sizeof(struct get_index_u64);
1699 break;
1700 }
1701
07dfc1d0
MD
1702 }
1703end:
1704 *_next_pc = next_pc;
1705 return ret;
1706}
1707
1708/*
1709 * Never called concurrently (hash seed is shared).
1710 */
1711int lttng_filter_validate_bytecode(struct bytecode_runtime *bytecode)
1712{
1713 struct mp_table *mp_table;
7962cb86 1714 char *pc, *next_pc, *start_pc;
07dfc1d0
MD
1715 int ret = -EINVAL;
1716 struct vstack stack;
1717
1718 vstack_init(&stack);
1719
1720 mp_table = kzalloc(sizeof(*mp_table), GFP_KERNEL);
1721 if (!mp_table) {
1722 printk(KERN_WARNING "Error allocating hash table for bytecode validation\n");
1723 return -ENOMEM;
1724 }
3834b99f 1725 start_pc = &bytecode->code[0];
07dfc1d0
MD
1726 for (pc = next_pc = start_pc; pc - start_pc < bytecode->len;
1727 pc = next_pc) {
1728 ret = bytecode_validate_overflow(bytecode, start_pc, pc);
1729 if (ret != 0) {
1730 if (ret == -ERANGE)
1731 printk(KERN_WARNING "filter bytecode overflow\n");
1732 goto end;
1733 }
1734 dbg_printk("Validating op %s (%u)\n",
1735 lttng_filter_print_op((unsigned int) *(filter_opcode_t *) pc),
1736 (unsigned int) *(filter_opcode_t *) pc);
1737
1738 /*
1739 * For each instruction, validate the current context
1740 * (traversal of entire execution flow), and validate
3834b99f 1741 * all merge points targeting this instruction.
07dfc1d0
MD
1742 */
1743 ret = validate_instruction_all_contexts(bytecode, mp_table,
1744 &stack, start_pc, pc);
1745 if (ret)
1746 goto end;
1747 ret = exec_insn(bytecode, mp_table, &stack, &next_pc, pc);
1748 if (ret <= 0)
1749 goto end;
1750 }
1751end:
1752 if (delete_all_nodes(mp_table)) {
1753 if (!ret) {
1754 printk(KERN_WARNING "Unexpected merge points\n");
1755 ret = -EINVAL;
1756 }
1757 }
1758 kfree(mp_table);
1759 return ret;
1760}
This page took 0.095899 seconds and 4 git commands to generate.