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