2 * lttng-filter-validator.c
4 * LTTng UST filter bytecode validator.
6 * Copyright (C) 2010-2016 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
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:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
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
30 #include "lttng-filter.h"
32 #include <urcu/rculfhash.h>
33 #include "lttng-hash-helper.h"
34 #include "string-utils.h"
37 * Number of merge points for hash table size. Hash table initialized to
38 * that size, and we do not resize, because we do not want to trigger
39 * RCU worker thread execution: fall-back on linear traversal if number
40 * of merge points exceeds this value.
42 #define DEFAULT_NR_MERGE_POINTS 128
43 #define MIN_NR_BUCKETS 128
44 #define MAX_NR_BUCKETS 128
46 /* merge point table node */
48 struct cds_lfht_node node
;
50 /* Context at merge point */
52 unsigned long target_pc
;
55 static unsigned long lttng_hash_seed
;
56 static unsigned int lttng_hash_seed_ready
;
59 int lttng_hash_match(struct cds_lfht_node
*node
, const void *key
)
61 struct lfht_mp_node
*mp_node
=
62 caa_container_of(node
, struct lfht_mp_node
, node
);
63 unsigned long key_pc
= (unsigned long) key
;
65 if (mp_node
->target_pc
== key_pc
)
72 int merge_points_compare(const struct vstack
*stacka
,
73 const struct vstack
*stackb
)
77 if (stacka
->top
!= stackb
->top
)
79 len
= stacka
->top
+ 1;
81 for (i
= 0; i
< len
; i
++) {
82 if (stacka
->e
[i
].type
!= REG_UNKNOWN
83 && stackb
->e
[i
].type
!= REG_UNKNOWN
84 && stacka
->e
[i
].type
!= stackb
->e
[i
].type
)
91 int merge_point_add_check(struct cds_lfht
*ht
, unsigned long target_pc
,
92 const struct vstack
*stack
)
94 struct lfht_mp_node
*node
;
95 unsigned long hash
= lttng_hash_mix((const char *) target_pc
,
98 struct cds_lfht_node
*ret
;
100 dbg_printf("Filter: adding merge point at offset %lu, hash %lu\n",
102 node
= zmalloc(sizeof(struct lfht_mp_node
));
105 node
->target_pc
= target_pc
;
106 memcpy(&node
->stack
, stack
, sizeof(node
->stack
));
107 ret
= cds_lfht_add_unique(ht
, hash
, lttng_hash_match
,
108 (const char *) target_pc
, &node
->node
);
109 if (ret
!= &node
->node
) {
110 struct lfht_mp_node
*ret_mp
=
111 caa_container_of(ret
, struct lfht_mp_node
, node
);
113 /* Key already present */
114 dbg_printf("Filter: compare merge points for offset %lu, hash %lu\n",
117 if (merge_points_compare(stack
, &ret_mp
->stack
)) {
118 ERR("Merge points differ for offset %lu\n",
127 * Binary comparators use top of stack and top of stack -1.
128 * Return 0 if typing is known to match, 1 if typing is dynamic
129 * (unknown), negative error value on error.
132 int bin_op_compare_check(struct vstack
*stack
, filter_opcode_t opcode
,
135 if (unlikely(!vstack_ax(stack
) || !vstack_bx(stack
)))
138 switch (vstack_ax(stack
)->type
) {
145 switch (vstack_bx(stack
)->type
) {
153 case REG_STAR_GLOB_STRING
:
154 if (opcode
!= FILTER_OP_EQ
&& opcode
!= FILTER_OP_NE
) {
163 case REG_STAR_GLOB_STRING
:
164 switch (vstack_bx(stack
)->type
) {
171 if (opcode
!= FILTER_OP_EQ
&& opcode
!= FILTER_OP_NE
) {
175 case REG_STAR_GLOB_STRING
:
183 switch (vstack_bx(stack
)->type
) {
190 case REG_STAR_GLOB_STRING
:
204 ERR("type mismatch for '%s' binary operator\n", str
);
208 ERR("empty stack for '%s' binary operator\n", str
);
212 ERR("unknown type for '%s' binary operator\n", str
);
217 * Binary bitwise operators use top of stack and top of stack -1.
218 * Return 0 if typing is known to match, 1 if typing is dynamic
219 * (unknown), negative error value on error.
222 int bin_op_bitwise_check(struct vstack
*stack
, filter_opcode_t opcode
,
225 if (unlikely(!vstack_ax(stack
) || !vstack_bx(stack
)))
228 switch (vstack_ax(stack
)->type
) {
235 switch (vstack_bx(stack
)->type
) {
252 ERR("empty stack for '%s' binary operator\n", str
);
256 ERR("unknown type for '%s' binary operator\n", str
);
261 int validate_get_symbol(struct bytecode_runtime
*bytecode
,
262 const struct get_symbol
*sym
)
264 const char *str
, *str_limit
;
267 if (sym
->offset
>= bytecode
->p
.bc
->bc
.len
- bytecode
->p
.bc
->bc
.reloc_offset
)
270 str
= bytecode
->p
.bc
->bc
.data
+ bytecode
->p
.bc
->bc
.reloc_offset
+ sym
->offset
;
271 str_limit
= bytecode
->p
.bc
->bc
.data
+ bytecode
->p
.bc
->bc
.len
;
272 len_limit
= str_limit
- str
;
273 if (strnlen(str
, len_limit
) == len_limit
)
279 * Validate bytecode range overflow within the validation pass.
280 * Called for each instruction encountered.
283 int bytecode_validate_overflow(struct bytecode_runtime
*bytecode
,
284 char *start_pc
, char *pc
)
288 switch (*(filter_opcode_t
*) pc
) {
289 case FILTER_OP_UNKNOWN
:
292 ERR("unknown bytecode op %u\n",
293 (unsigned int) *(filter_opcode_t
*) pc
);
298 case FILTER_OP_RETURN
:
299 case FILTER_OP_RETURN_S64
:
301 if (unlikely(pc
+ sizeof(struct return_op
)
302 > start_pc
+ bytecode
->len
)) {
313 case FILTER_OP_MINUS
:
315 ERR("unsupported bytecode op %u\n",
316 (unsigned int) *(filter_opcode_t
*) pc
);
327 case FILTER_OP_EQ_STRING
:
328 case FILTER_OP_NE_STRING
:
329 case FILTER_OP_GT_STRING
:
330 case FILTER_OP_LT_STRING
:
331 case FILTER_OP_GE_STRING
:
332 case FILTER_OP_LE_STRING
:
333 case FILTER_OP_EQ_STAR_GLOB_STRING
:
334 case FILTER_OP_NE_STAR_GLOB_STRING
:
335 case FILTER_OP_EQ_S64
:
336 case FILTER_OP_NE_S64
:
337 case FILTER_OP_GT_S64
:
338 case FILTER_OP_LT_S64
:
339 case FILTER_OP_GE_S64
:
340 case FILTER_OP_LE_S64
:
341 case FILTER_OP_EQ_DOUBLE
:
342 case FILTER_OP_NE_DOUBLE
:
343 case FILTER_OP_GT_DOUBLE
:
344 case FILTER_OP_LT_DOUBLE
:
345 case FILTER_OP_GE_DOUBLE
:
346 case FILTER_OP_LE_DOUBLE
:
347 case FILTER_OP_EQ_DOUBLE_S64
:
348 case FILTER_OP_NE_DOUBLE_S64
:
349 case FILTER_OP_GT_DOUBLE_S64
:
350 case FILTER_OP_LT_DOUBLE_S64
:
351 case FILTER_OP_GE_DOUBLE_S64
:
352 case FILTER_OP_LE_DOUBLE_S64
:
353 case FILTER_OP_EQ_S64_DOUBLE
:
354 case FILTER_OP_NE_S64_DOUBLE
:
355 case FILTER_OP_GT_S64_DOUBLE
:
356 case FILTER_OP_LT_S64_DOUBLE
:
357 case FILTER_OP_GE_S64_DOUBLE
:
358 case FILTER_OP_LE_S64_DOUBLE
:
359 case FILTER_OP_BIT_RSHIFT
:
360 case FILTER_OP_BIT_LSHIFT
:
361 case FILTER_OP_BIT_AND
:
362 case FILTER_OP_BIT_OR
:
363 case FILTER_OP_BIT_XOR
:
365 if (unlikely(pc
+ sizeof(struct binary_op
)
366 > start_pc
+ bytecode
->len
)) {
373 case FILTER_OP_UNARY_PLUS
:
374 case FILTER_OP_UNARY_MINUS
:
375 case FILTER_OP_UNARY_NOT
:
376 case FILTER_OP_UNARY_PLUS_S64
:
377 case FILTER_OP_UNARY_MINUS_S64
:
378 case FILTER_OP_UNARY_NOT_S64
:
379 case FILTER_OP_UNARY_PLUS_DOUBLE
:
380 case FILTER_OP_UNARY_MINUS_DOUBLE
:
381 case FILTER_OP_UNARY_NOT_DOUBLE
:
382 case FILTER_OP_UNARY_BIT_NOT
:
384 if (unlikely(pc
+ sizeof(struct unary_op
)
385 > start_pc
+ bytecode
->len
)) {
395 if (unlikely(pc
+ sizeof(struct logical_op
)
396 > start_pc
+ bytecode
->len
)) {
403 case FILTER_OP_LOAD_FIELD_REF
:
405 ERR("Unknown field ref type\n");
410 /* get context ref */
411 case FILTER_OP_GET_CONTEXT_REF
:
412 case FILTER_OP_LOAD_FIELD_REF_STRING
:
413 case FILTER_OP_LOAD_FIELD_REF_SEQUENCE
:
414 case FILTER_OP_LOAD_FIELD_REF_S64
:
415 case FILTER_OP_LOAD_FIELD_REF_DOUBLE
:
416 case FILTER_OP_GET_CONTEXT_REF_STRING
:
417 case FILTER_OP_GET_CONTEXT_REF_S64
:
418 case FILTER_OP_GET_CONTEXT_REF_DOUBLE
:
420 if (unlikely(pc
+ sizeof(struct load_op
) + sizeof(struct field_ref
)
421 > start_pc
+ bytecode
->len
)) {
427 /* load from immediate operand */
428 case FILTER_OP_LOAD_STRING
:
429 case FILTER_OP_LOAD_STAR_GLOB_STRING
:
431 struct load_op
*insn
= (struct load_op
*) pc
;
432 uint32_t str_len
, maxlen
;
434 if (unlikely(pc
+ sizeof(struct load_op
)
435 > start_pc
+ bytecode
->len
)) {
440 maxlen
= start_pc
+ bytecode
->len
- pc
- sizeof(struct load_op
);
441 str_len
= strnlen(insn
->data
, maxlen
);
442 if (unlikely(str_len
>= maxlen
)) {
443 /* Final '\0' not found within range */
449 case FILTER_OP_LOAD_S64
:
451 if (unlikely(pc
+ sizeof(struct load_op
) + sizeof(struct literal_numeric
)
452 > start_pc
+ bytecode
->len
)) {
458 case FILTER_OP_LOAD_DOUBLE
:
460 if (unlikely(pc
+ sizeof(struct load_op
) + sizeof(struct literal_double
)
461 > start_pc
+ bytecode
->len
)) {
467 case FILTER_OP_CAST_TO_S64
:
468 case FILTER_OP_CAST_DOUBLE_TO_S64
:
469 case FILTER_OP_CAST_NOP
:
471 if (unlikely(pc
+ sizeof(struct cast_op
)
472 > start_pc
+ bytecode
->len
)) {
479 * Instructions for recursive traversal through composed types.
481 case FILTER_OP_GET_CONTEXT_ROOT
:
482 case FILTER_OP_GET_APP_CONTEXT_ROOT
:
483 case FILTER_OP_GET_PAYLOAD_ROOT
:
484 case FILTER_OP_LOAD_FIELD
:
485 case FILTER_OP_LOAD_FIELD_S8
:
486 case FILTER_OP_LOAD_FIELD_S16
:
487 case FILTER_OP_LOAD_FIELD_S32
:
488 case FILTER_OP_LOAD_FIELD_S64
:
489 case FILTER_OP_LOAD_FIELD_U8
:
490 case FILTER_OP_LOAD_FIELD_U16
:
491 case FILTER_OP_LOAD_FIELD_U32
:
492 case FILTER_OP_LOAD_FIELD_U64
:
493 case FILTER_OP_LOAD_FIELD_STRING
:
494 case FILTER_OP_LOAD_FIELD_SEQUENCE
:
495 case FILTER_OP_LOAD_FIELD_DOUBLE
:
496 if (unlikely(pc
+ sizeof(struct load_op
)
497 > start_pc
+ bytecode
->len
)) {
502 case FILTER_OP_GET_SYMBOL
:
504 struct load_op
*insn
= (struct load_op
*) pc
;
505 struct get_symbol
*sym
= (struct get_symbol
*) insn
->data
;
507 if (unlikely(pc
+ sizeof(struct load_op
) + sizeof(struct get_symbol
)
508 > start_pc
+ bytecode
->len
)) {
511 ret
= validate_get_symbol(bytecode
, sym
);
515 case FILTER_OP_GET_SYMBOL_FIELD
:
516 ERR("Unexpected get symbol field");
520 case FILTER_OP_GET_INDEX_U16
:
521 if (unlikely(pc
+ sizeof(struct load_op
) + sizeof(struct get_index_u16
)
522 > start_pc
+ bytecode
->len
)) {
527 case FILTER_OP_GET_INDEX_U64
:
528 if (unlikely(pc
+ sizeof(struct load_op
) + sizeof(struct get_index_u64
)
529 > start_pc
+ bytecode
->len
)) {
539 unsigned long delete_all_nodes(struct cds_lfht
*ht
)
541 struct cds_lfht_iter iter
;
542 struct lfht_mp_node
*node
;
543 unsigned long nr_nodes
= 0;
545 cds_lfht_for_each_entry(ht
, &iter
, node
, node
) {
548 ret
= cds_lfht_del(ht
, cds_lfht_iter_get_node(&iter
));
550 /* note: this hash table is never used concurrently */
563 int validate_instruction_context(struct bytecode_runtime
*bytecode
,
564 struct vstack
*stack
,
569 const filter_opcode_t opcode
= *(filter_opcode_t
*) pc
;
572 case FILTER_OP_UNKNOWN
:
575 ERR("unknown bytecode op %u\n",
576 (unsigned int) *(filter_opcode_t
*) pc
);
581 case FILTER_OP_RETURN
:
582 case FILTER_OP_RETURN_S64
:
592 case FILTER_OP_MINUS
:
594 ERR("unsupported bytecode op %u\n",
595 (unsigned int) opcode
);
602 ret
= bin_op_compare_check(stack
, opcode
, "==");
609 ret
= bin_op_compare_check(stack
, opcode
, "!=");
616 ret
= bin_op_compare_check(stack
, opcode
, ">");
623 ret
= bin_op_compare_check(stack
, opcode
, "<");
630 ret
= bin_op_compare_check(stack
, opcode
, ">=");
637 ret
= bin_op_compare_check(stack
, opcode
, "<=");
643 case FILTER_OP_EQ_STRING
:
644 case FILTER_OP_NE_STRING
:
645 case FILTER_OP_GT_STRING
:
646 case FILTER_OP_LT_STRING
:
647 case FILTER_OP_GE_STRING
:
648 case FILTER_OP_LE_STRING
:
650 if (!vstack_ax(stack
) || !vstack_bx(stack
)) {
651 ERR("Empty stack\n");
655 if (vstack_ax(stack
)->type
!= REG_STRING
656 || vstack_bx(stack
)->type
!= REG_STRING
) {
657 ERR("Unexpected register type for string comparator\n");
664 case FILTER_OP_EQ_STAR_GLOB_STRING
:
665 case FILTER_OP_NE_STAR_GLOB_STRING
:
667 if (!vstack_ax(stack
) || !vstack_bx(stack
)) {
668 ERR("Empty stack\n");
672 if (vstack_ax(stack
)->type
!= REG_STAR_GLOB_STRING
673 && vstack_bx(stack
)->type
!= REG_STAR_GLOB_STRING
) {
674 ERR("Unexpected register type for globbing pattern comparator\n");
681 case FILTER_OP_EQ_S64
:
682 case FILTER_OP_NE_S64
:
683 case FILTER_OP_GT_S64
:
684 case FILTER_OP_LT_S64
:
685 case FILTER_OP_GE_S64
:
686 case FILTER_OP_LE_S64
:
688 if (!vstack_ax(stack
) || !vstack_bx(stack
)) {
689 ERR("Empty stack\n");
693 if (vstack_ax(stack
)->type
!= REG_S64
694 || vstack_bx(stack
)->type
!= REG_S64
) {
695 ERR("Unexpected register type for s64 comparator\n");
702 case FILTER_OP_EQ_DOUBLE
:
703 case FILTER_OP_NE_DOUBLE
:
704 case FILTER_OP_GT_DOUBLE
:
705 case FILTER_OP_LT_DOUBLE
:
706 case FILTER_OP_GE_DOUBLE
:
707 case FILTER_OP_LE_DOUBLE
:
709 if (!vstack_ax(stack
) || !vstack_bx(stack
)) {
710 ERR("Empty stack\n");
714 if (vstack_ax(stack
)->type
!= REG_DOUBLE
&& vstack_bx(stack
)->type
!= REG_DOUBLE
) {
715 ERR("Double operator should have two double registers\n");
722 case FILTER_OP_EQ_DOUBLE_S64
:
723 case FILTER_OP_NE_DOUBLE_S64
:
724 case FILTER_OP_GT_DOUBLE_S64
:
725 case FILTER_OP_LT_DOUBLE_S64
:
726 case FILTER_OP_GE_DOUBLE_S64
:
727 case FILTER_OP_LE_DOUBLE_S64
:
729 if (!vstack_ax(stack
) || !vstack_bx(stack
)) {
730 ERR("Empty stack\n");
734 if (vstack_ax(stack
)->type
!= REG_S64
&& vstack_bx(stack
)->type
!= REG_DOUBLE
) {
735 ERR("Double-S64 operator has unexpected register types\n");
742 case FILTER_OP_EQ_S64_DOUBLE
:
743 case FILTER_OP_NE_S64_DOUBLE
:
744 case FILTER_OP_GT_S64_DOUBLE
:
745 case FILTER_OP_LT_S64_DOUBLE
:
746 case FILTER_OP_GE_S64_DOUBLE
:
747 case FILTER_OP_LE_S64_DOUBLE
:
749 if (!vstack_ax(stack
) || !vstack_bx(stack
)) {
750 ERR("Empty stack\n");
754 if (vstack_ax(stack
)->type
!= REG_DOUBLE
&& vstack_bx(stack
)->type
!= REG_S64
) {
755 ERR("S64-Double operator has unexpected register types\n");
762 case FILTER_OP_BIT_RSHIFT
:
763 ret
= bin_op_bitwise_check(stack
, opcode
, ">>");
767 case FILTER_OP_BIT_LSHIFT
:
768 ret
= bin_op_bitwise_check(stack
, opcode
, "<<");
772 case FILTER_OP_BIT_AND
:
773 ret
= bin_op_bitwise_check(stack
, opcode
, "&");
777 case FILTER_OP_BIT_OR
:
778 ret
= bin_op_bitwise_check(stack
, opcode
, "|");
782 case FILTER_OP_BIT_XOR
:
783 ret
= bin_op_bitwise_check(stack
, opcode
, "^");
789 case FILTER_OP_UNARY_PLUS
:
790 case FILTER_OP_UNARY_MINUS
:
791 case FILTER_OP_UNARY_NOT
:
793 if (!vstack_ax(stack
)) {
794 ERR("Empty stack\n");
798 switch (vstack_ax(stack
)->type
) {
800 ERR("unknown register type\n");
805 case REG_STAR_GLOB_STRING
:
806 ERR("Unary op can only be applied to numeric or floating point registers\n");
818 case FILTER_OP_UNARY_BIT_NOT
:
820 if (!vstack_ax(stack
)) {
821 ERR("Empty stack\n");
825 switch (vstack_ax(stack
)->type
) {
827 ERR("unknown register type\n");
832 case REG_STAR_GLOB_STRING
:
834 ERR("Unary bitwise op can only be applied to numeric registers\n");
845 case FILTER_OP_UNARY_PLUS_S64
:
846 case FILTER_OP_UNARY_MINUS_S64
:
847 case FILTER_OP_UNARY_NOT_S64
:
849 if (!vstack_ax(stack
)) {
850 ERR("Empty stack\n");
854 if (vstack_ax(stack
)->type
!= REG_S64
) {
855 ERR("Invalid register type\n");
862 case FILTER_OP_UNARY_PLUS_DOUBLE
:
863 case FILTER_OP_UNARY_MINUS_DOUBLE
:
864 case FILTER_OP_UNARY_NOT_DOUBLE
:
866 if (!vstack_ax(stack
)) {
867 ERR("Empty stack\n");
871 if (vstack_ax(stack
)->type
!= REG_DOUBLE
) {
872 ERR("Invalid register type\n");
883 struct logical_op
*insn
= (struct logical_op
*) pc
;
885 if (!vstack_ax(stack
)) {
886 ERR("Empty stack\n");
890 if (vstack_ax(stack
)->type
!= REG_S64
891 && vstack_ax(stack
)->type
!= REG_UNKNOWN
) {
892 ERR("Logical comparator expects S64 or dynamic register\n");
897 dbg_printf("Validate jumping to bytecode offset %u\n",
898 (unsigned int) insn
->skip_offset
);
899 if (unlikely(start_pc
+ insn
->skip_offset
<= pc
)) {
900 ERR("Loops are not allowed in bytecode\n");
908 case FILTER_OP_LOAD_FIELD_REF
:
910 ERR("Unknown field ref type\n");
914 case FILTER_OP_LOAD_FIELD_REF_STRING
:
915 case FILTER_OP_LOAD_FIELD_REF_SEQUENCE
:
917 struct load_op
*insn
= (struct load_op
*) pc
;
918 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
920 dbg_printf("Validate load field ref offset %u type string\n",
924 case FILTER_OP_LOAD_FIELD_REF_S64
:
926 struct load_op
*insn
= (struct load_op
*) pc
;
927 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
929 dbg_printf("Validate load field ref offset %u type s64\n",
933 case FILTER_OP_LOAD_FIELD_REF_DOUBLE
:
935 struct load_op
*insn
= (struct load_op
*) pc
;
936 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
938 dbg_printf("Validate load field ref offset %u type double\n",
943 /* load from immediate operand */
944 case FILTER_OP_LOAD_STRING
:
945 case FILTER_OP_LOAD_STAR_GLOB_STRING
:
950 case FILTER_OP_LOAD_S64
:
955 case FILTER_OP_LOAD_DOUBLE
:
960 case FILTER_OP_CAST_TO_S64
:
961 case FILTER_OP_CAST_DOUBLE_TO_S64
:
963 struct cast_op
*insn
= (struct cast_op
*) pc
;
965 if (!vstack_ax(stack
)) {
966 ERR("Empty stack\n");
970 switch (vstack_ax(stack
)->type
) {
972 ERR("unknown register type\n");
977 case REG_STAR_GLOB_STRING
:
978 ERR("Cast op can only be applied to numeric or floating point registers\n");
988 if (insn
->op
== FILTER_OP_CAST_DOUBLE_TO_S64
) {
989 if (vstack_ax(stack
)->type
!= REG_DOUBLE
) {
990 ERR("Cast expects double\n");
997 case FILTER_OP_CAST_NOP
:
1002 /* get context ref */
1003 case FILTER_OP_GET_CONTEXT_REF
:
1005 struct load_op
*insn
= (struct load_op
*) pc
;
1006 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1008 dbg_printf("Validate get context ref offset %u type dynamic\n",
1012 case FILTER_OP_GET_CONTEXT_REF_STRING
:
1014 struct load_op
*insn
= (struct load_op
*) pc
;
1015 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1017 dbg_printf("Validate get context ref offset %u type string\n",
1021 case FILTER_OP_GET_CONTEXT_REF_S64
:
1023 struct load_op
*insn
= (struct load_op
*) pc
;
1024 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1026 dbg_printf("Validate get context ref offset %u type s64\n",
1030 case FILTER_OP_GET_CONTEXT_REF_DOUBLE
:
1032 struct load_op
*insn
= (struct load_op
*) pc
;
1033 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1035 dbg_printf("Validate get context ref offset %u type double\n",
1041 * Instructions for recursive traversal through composed types.
1043 case FILTER_OP_GET_CONTEXT_ROOT
:
1045 dbg_printf("Validate get context root\n");
1048 case FILTER_OP_GET_APP_CONTEXT_ROOT
:
1050 dbg_printf("Validate get app context root\n");
1053 case FILTER_OP_GET_PAYLOAD_ROOT
:
1055 dbg_printf("Validate get payload root\n");
1058 case FILTER_OP_LOAD_FIELD
:
1061 * We tolerate that field type is unknown at validation,
1062 * because we are performing the load specialization in
1063 * a phase after validation.
1065 dbg_printf("Validate load field\n");
1068 case FILTER_OP_LOAD_FIELD_S8
:
1070 dbg_printf("Validate load field s8\n");
1073 case FILTER_OP_LOAD_FIELD_S16
:
1075 dbg_printf("Validate load field s16\n");
1078 case FILTER_OP_LOAD_FIELD_S32
:
1080 dbg_printf("Validate load field s32\n");
1083 case FILTER_OP_LOAD_FIELD_S64
:
1085 dbg_printf("Validate load field s64\n");
1088 case FILTER_OP_LOAD_FIELD_U8
:
1090 dbg_printf("Validate load field u8\n");
1093 case FILTER_OP_LOAD_FIELD_U16
:
1095 dbg_printf("Validate load field u16\n");
1098 case FILTER_OP_LOAD_FIELD_U32
:
1100 dbg_printf("Validate load field u32\n");
1103 case FILTER_OP_LOAD_FIELD_U64
:
1105 dbg_printf("Validate load field u64\n");
1108 case FILTER_OP_LOAD_FIELD_STRING
:
1110 dbg_printf("Validate load field string\n");
1113 case FILTER_OP_LOAD_FIELD_SEQUENCE
:
1115 dbg_printf("Validate load field sequence\n");
1118 case FILTER_OP_LOAD_FIELD_DOUBLE
:
1120 dbg_printf("Validate load field double\n");
1124 case FILTER_OP_GET_SYMBOL
:
1126 struct load_op
*insn
= (struct load_op
*) pc
;
1127 struct get_symbol
*sym
= (struct get_symbol
*) insn
->data
;
1129 dbg_printf("Validate get symbol offset %u\n", sym
->offset
);
1133 case FILTER_OP_GET_SYMBOL_FIELD
:
1135 struct load_op
*insn
= (struct load_op
*) pc
;
1136 struct get_symbol
*sym
= (struct get_symbol
*) insn
->data
;
1138 dbg_printf("Validate get symbol field offset %u\n", sym
->offset
);
1142 case FILTER_OP_GET_INDEX_U16
:
1144 struct load_op
*insn
= (struct load_op
*) pc
;
1145 struct get_index_u16
*get_index
= (struct get_index_u16
*) insn
->data
;
1147 dbg_printf("Validate get index u16 index %u\n", get_index
->index
);
1151 case FILTER_OP_GET_INDEX_U64
:
1153 struct load_op
*insn
= (struct load_op
*) pc
;
1154 struct get_index_u64
*get_index
= (struct get_index_u64
*) insn
->data
;
1156 dbg_printf("Validate get index u64 index %" PRIu64
"\n", get_index
->index
);
1170 int validate_instruction_all_contexts(struct bytecode_runtime
*bytecode
,
1171 struct cds_lfht
*merge_points
,
1172 struct vstack
*stack
,
1177 unsigned long target_pc
= pc
- start_pc
;
1178 struct cds_lfht_iter iter
;
1179 struct cds_lfht_node
*node
;
1180 struct lfht_mp_node
*mp_node
;
1183 /* Validate the context resulting from the previous instruction */
1184 ret
= validate_instruction_context(bytecode
, stack
, start_pc
, pc
);
1188 /* Validate merge points */
1189 hash
= lttng_hash_mix((const char *) target_pc
, sizeof(target_pc
),
1191 cds_lfht_lookup(merge_points
, hash
, lttng_hash_match
,
1192 (const char *) target_pc
, &iter
);
1193 node
= cds_lfht_iter_get_node(&iter
);
1195 mp_node
= caa_container_of(node
, struct lfht_mp_node
, node
);
1197 dbg_printf("Filter: validate merge point at offset %lu\n",
1199 if (merge_points_compare(stack
, &mp_node
->stack
)) {
1200 ERR("Merge points differ for offset %lu\n",
1204 /* Once validated, we can remove the merge point */
1205 dbg_printf("Filter: remove merge point at offset %lu\n",
1207 ret
= cds_lfht_del(merge_points
, node
);
1215 * >0: going to next insn.
1216 * 0: success, stop iteration.
1220 int exec_insn(struct bytecode_runtime
*bytecode
,
1221 struct cds_lfht
*merge_points
,
1222 struct vstack
*stack
,
1227 char *next_pc
= *_next_pc
;
1229 switch (*(filter_opcode_t
*) pc
) {
1230 case FILTER_OP_UNKNOWN
:
1233 ERR("unknown bytecode op %u\n",
1234 (unsigned int) *(filter_opcode_t
*) pc
);
1239 case FILTER_OP_RETURN
:
1241 if (!vstack_ax(stack
)) {
1242 ERR("Empty stack\n");
1246 switch (vstack_ax(stack
)->type
) {
1251 ERR("Unexpected register type %d at end of bytecode\n",
1252 (int) vstack_ax(stack
)->type
);
1260 case FILTER_OP_RETURN_S64
:
1262 if (!vstack_ax(stack
)) {
1263 ERR("Empty stack\n");
1267 switch (vstack_ax(stack
)->type
) {
1272 ERR("Unexpected register type %d at end of bytecode\n",
1273 (int) vstack_ax(stack
)->type
);
1286 case FILTER_OP_PLUS
:
1287 case FILTER_OP_MINUS
:
1289 ERR("unsupported bytecode op %u\n",
1290 (unsigned int) *(filter_opcode_t
*) pc
);
1301 case FILTER_OP_EQ_STRING
:
1302 case FILTER_OP_NE_STRING
:
1303 case FILTER_OP_GT_STRING
:
1304 case FILTER_OP_LT_STRING
:
1305 case FILTER_OP_GE_STRING
:
1306 case FILTER_OP_LE_STRING
:
1307 case FILTER_OP_EQ_STAR_GLOB_STRING
:
1308 case FILTER_OP_NE_STAR_GLOB_STRING
:
1309 case FILTER_OP_EQ_S64
:
1310 case FILTER_OP_NE_S64
:
1311 case FILTER_OP_GT_S64
:
1312 case FILTER_OP_LT_S64
:
1313 case FILTER_OP_GE_S64
:
1314 case FILTER_OP_LE_S64
:
1315 case FILTER_OP_EQ_DOUBLE
:
1316 case FILTER_OP_NE_DOUBLE
:
1317 case FILTER_OP_GT_DOUBLE
:
1318 case FILTER_OP_LT_DOUBLE
:
1319 case FILTER_OP_GE_DOUBLE
:
1320 case FILTER_OP_LE_DOUBLE
:
1321 case FILTER_OP_EQ_DOUBLE_S64
:
1322 case FILTER_OP_NE_DOUBLE_S64
:
1323 case FILTER_OP_GT_DOUBLE_S64
:
1324 case FILTER_OP_LT_DOUBLE_S64
:
1325 case FILTER_OP_GE_DOUBLE_S64
:
1326 case FILTER_OP_LE_DOUBLE_S64
:
1327 case FILTER_OP_EQ_S64_DOUBLE
:
1328 case FILTER_OP_NE_S64_DOUBLE
:
1329 case FILTER_OP_GT_S64_DOUBLE
:
1330 case FILTER_OP_LT_S64_DOUBLE
:
1331 case FILTER_OP_GE_S64_DOUBLE
:
1332 case FILTER_OP_LE_S64_DOUBLE
:
1333 case FILTER_OP_BIT_RSHIFT
:
1334 case FILTER_OP_BIT_LSHIFT
:
1335 case FILTER_OP_BIT_AND
:
1336 case FILTER_OP_BIT_OR
:
1337 case FILTER_OP_BIT_XOR
:
1340 if (vstack_pop(stack
)) {
1344 if (!vstack_ax(stack
)) {
1345 ERR("Empty stack\n");
1349 switch (vstack_ax(stack
)->type
) {
1353 case REG_STAR_GLOB_STRING
:
1357 ERR("Unexpected register type %d for operation\n",
1358 (int) vstack_ax(stack
)->type
);
1363 vstack_ax(stack
)->type
= REG_S64
;
1364 next_pc
+= sizeof(struct binary_op
);
1369 case FILTER_OP_UNARY_PLUS
:
1370 case FILTER_OP_UNARY_MINUS
:
1373 if (!vstack_ax(stack
)) {
1374 ERR("Empty stack\n");
1378 switch (vstack_ax(stack
)->type
) {
1384 ERR("Unexpected register type %d for operation\n",
1385 (int) vstack_ax(stack
)->type
);
1389 vstack_ax(stack
)->type
= REG_UNKNOWN
;
1390 next_pc
+= sizeof(struct unary_op
);
1394 case FILTER_OP_UNARY_PLUS_S64
:
1395 case FILTER_OP_UNARY_MINUS_S64
:
1396 case FILTER_OP_UNARY_NOT_S64
:
1399 if (!vstack_ax(stack
)) {
1400 ERR("Empty stack\n");
1404 switch (vstack_ax(stack
)->type
) {
1408 ERR("Unexpected register type %d for operation\n",
1409 (int) vstack_ax(stack
)->type
);
1414 vstack_ax(stack
)->type
= REG_S64
;
1415 next_pc
+= sizeof(struct unary_op
);
1419 case FILTER_OP_UNARY_NOT
:
1422 if (!vstack_ax(stack
)) {
1423 ERR("Empty stack\n");
1427 switch (vstack_ax(stack
)->type
) {
1433 ERR("Unexpected register type %d for operation\n",
1434 (int) vstack_ax(stack
)->type
);
1439 vstack_ax(stack
)->type
= REG_S64
;
1440 next_pc
+= sizeof(struct unary_op
);
1444 case FILTER_OP_UNARY_BIT_NOT
:
1447 if (!vstack_ax(stack
)) {
1448 ERR("Empty stack\n");
1452 switch (vstack_ax(stack
)->type
) {
1458 ERR("Unexpected register type %d for operation\n",
1459 (int) vstack_ax(stack
)->type
);
1464 vstack_ax(stack
)->type
= REG_S64
;
1465 next_pc
+= sizeof(struct unary_op
);
1469 case FILTER_OP_UNARY_NOT_DOUBLE
:
1472 if (!vstack_ax(stack
)) {
1473 ERR("Empty stack\n");
1477 switch (vstack_ax(stack
)->type
) {
1481 ERR("Incorrect register type %d for operation\n",
1482 (int) vstack_ax(stack
)->type
);
1487 vstack_ax(stack
)->type
= REG_S64
;
1488 next_pc
+= sizeof(struct unary_op
);
1492 case FILTER_OP_UNARY_PLUS_DOUBLE
:
1493 case FILTER_OP_UNARY_MINUS_DOUBLE
:
1496 if (!vstack_ax(stack
)) {
1497 ERR("Empty stack\n");
1501 switch (vstack_ax(stack
)->type
) {
1505 ERR("Incorrect register type %d for operation\n",
1506 (int) vstack_ax(stack
)->type
);
1511 vstack_ax(stack
)->type
= REG_DOUBLE
;
1512 next_pc
+= sizeof(struct unary_op
);
1520 struct logical_op
*insn
= (struct logical_op
*) pc
;
1523 /* Add merge point to table */
1524 merge_ret
= merge_point_add_check(merge_points
,
1525 insn
->skip_offset
, stack
);
1531 if (!vstack_ax(stack
)) {
1532 ERR("Empty stack\n");
1536 /* There is always a cast-to-s64 operation before a or/and op. */
1537 switch (vstack_ax(stack
)->type
) {
1541 ERR("Incorrect register type %d for operation\n",
1542 (int) vstack_ax(stack
)->type
);
1547 /* Continue to next instruction */
1548 /* Pop 1 when jump not taken */
1549 if (vstack_pop(stack
)) {
1553 next_pc
+= sizeof(struct logical_op
);
1557 /* load field ref */
1558 case FILTER_OP_LOAD_FIELD_REF
:
1560 ERR("Unknown field ref type\n");
1564 /* get context ref */
1565 case FILTER_OP_GET_CONTEXT_REF
:
1567 if (vstack_push(stack
)) {
1571 vstack_ax(stack
)->type
= REG_UNKNOWN
;
1572 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1575 case FILTER_OP_LOAD_FIELD_REF_STRING
:
1576 case FILTER_OP_LOAD_FIELD_REF_SEQUENCE
:
1577 case FILTER_OP_GET_CONTEXT_REF_STRING
:
1579 if (vstack_push(stack
)) {
1583 vstack_ax(stack
)->type
= REG_STRING
;
1584 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1587 case FILTER_OP_LOAD_FIELD_REF_S64
:
1588 case FILTER_OP_GET_CONTEXT_REF_S64
:
1590 if (vstack_push(stack
)) {
1594 vstack_ax(stack
)->type
= REG_S64
;
1595 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1598 case FILTER_OP_LOAD_FIELD_REF_DOUBLE
:
1599 case FILTER_OP_GET_CONTEXT_REF_DOUBLE
:
1601 if (vstack_push(stack
)) {
1605 vstack_ax(stack
)->type
= REG_DOUBLE
;
1606 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1610 /* load from immediate operand */
1611 case FILTER_OP_LOAD_STRING
:
1613 struct load_op
*insn
= (struct load_op
*) pc
;
1615 if (vstack_push(stack
)) {
1619 vstack_ax(stack
)->type
= REG_STRING
;
1620 next_pc
+= sizeof(struct load_op
) + strlen(insn
->data
) + 1;
1624 case FILTER_OP_LOAD_STAR_GLOB_STRING
:
1626 struct load_op
*insn
= (struct load_op
*) pc
;
1628 if (vstack_push(stack
)) {
1632 vstack_ax(stack
)->type
= REG_STAR_GLOB_STRING
;
1633 next_pc
+= sizeof(struct load_op
) + strlen(insn
->data
) + 1;
1637 case FILTER_OP_LOAD_S64
:
1639 if (vstack_push(stack
)) {
1643 vstack_ax(stack
)->type
= REG_S64
;
1644 next_pc
+= sizeof(struct load_op
)
1645 + sizeof(struct literal_numeric
);
1649 case FILTER_OP_LOAD_DOUBLE
:
1651 if (vstack_push(stack
)) {
1655 vstack_ax(stack
)->type
= REG_DOUBLE
;
1656 next_pc
+= sizeof(struct load_op
)
1657 + sizeof(struct literal_double
);
1661 case FILTER_OP_CAST_TO_S64
:
1662 case FILTER_OP_CAST_DOUBLE_TO_S64
:
1665 if (!vstack_ax(stack
)) {
1666 ERR("Empty stack\n");
1670 switch (vstack_ax(stack
)->type
) {
1676 ERR("Incorrect register type %d for cast\n",
1677 (int) vstack_ax(stack
)->type
);
1681 vstack_ax(stack
)->type
= REG_S64
;
1682 next_pc
+= sizeof(struct cast_op
);
1685 case FILTER_OP_CAST_NOP
:
1687 next_pc
+= sizeof(struct cast_op
);
1692 * Instructions for recursive traversal through composed types.
1694 case FILTER_OP_GET_CONTEXT_ROOT
:
1695 case FILTER_OP_GET_APP_CONTEXT_ROOT
:
1696 case FILTER_OP_GET_PAYLOAD_ROOT
:
1698 if (vstack_push(stack
)) {
1702 vstack_ax(stack
)->type
= REG_PTR
;
1703 next_pc
+= sizeof(struct load_op
);
1707 case FILTER_OP_LOAD_FIELD
:
1710 if (!vstack_ax(stack
)) {
1711 ERR("Empty stack\n");
1715 if (vstack_ax(stack
)->type
!= REG_PTR
) {
1716 ERR("Expecting pointer on top of stack\n");
1720 vstack_ax(stack
)->type
= REG_UNKNOWN
;
1721 next_pc
+= sizeof(struct load_op
);
1725 case FILTER_OP_LOAD_FIELD_S8
:
1726 case FILTER_OP_LOAD_FIELD_S16
:
1727 case FILTER_OP_LOAD_FIELD_S32
:
1728 case FILTER_OP_LOAD_FIELD_S64
:
1729 case FILTER_OP_LOAD_FIELD_U8
:
1730 case FILTER_OP_LOAD_FIELD_U16
:
1731 case FILTER_OP_LOAD_FIELD_U32
:
1732 case FILTER_OP_LOAD_FIELD_U64
:
1735 if (!vstack_ax(stack
)) {
1736 ERR("Empty stack\n");
1740 if (vstack_ax(stack
)->type
!= REG_PTR
) {
1741 ERR("Expecting pointer on top of stack\n");
1745 vstack_ax(stack
)->type
= REG_S64
;
1746 next_pc
+= sizeof(struct load_op
);
1750 case FILTER_OP_LOAD_FIELD_STRING
:
1751 case FILTER_OP_LOAD_FIELD_SEQUENCE
:
1754 if (!vstack_ax(stack
)) {
1755 ERR("Empty stack\n");
1759 if (vstack_ax(stack
)->type
!= REG_PTR
) {
1760 ERR("Expecting pointer on top of stack\n");
1764 vstack_ax(stack
)->type
= REG_STRING
;
1765 next_pc
+= sizeof(struct load_op
);
1769 case FILTER_OP_LOAD_FIELD_DOUBLE
:
1772 if (!vstack_ax(stack
)) {
1773 ERR("Empty stack\n");
1777 if (vstack_ax(stack
)->type
!= REG_PTR
) {
1778 ERR("Expecting pointer on top of stack\n");
1782 vstack_ax(stack
)->type
= REG_DOUBLE
;
1783 next_pc
+= sizeof(struct load_op
);
1787 case FILTER_OP_GET_SYMBOL
:
1788 case FILTER_OP_GET_SYMBOL_FIELD
:
1791 if (!vstack_ax(stack
)) {
1792 ERR("Empty stack\n");
1796 if (vstack_ax(stack
)->type
!= REG_PTR
) {
1797 ERR("Expecting pointer on top of stack\n");
1801 next_pc
+= sizeof(struct load_op
) + sizeof(struct get_symbol
);
1805 case FILTER_OP_GET_INDEX_U16
:
1808 if (!vstack_ax(stack
)) {
1809 ERR("Empty stack\n");
1813 if (vstack_ax(stack
)->type
!= REG_PTR
) {
1814 ERR("Expecting pointer on top of stack\n");
1818 next_pc
+= sizeof(struct load_op
) + sizeof(struct get_index_u16
);
1822 case FILTER_OP_GET_INDEX_U64
:
1825 if (!vstack_ax(stack
)) {
1826 ERR("Empty stack\n");
1830 if (vstack_ax(stack
)->type
!= REG_PTR
) {
1831 ERR("Expecting pointer on top of stack\n");
1835 next_pc
+= sizeof(struct load_op
) + sizeof(struct get_index_u64
);
1841 *_next_pc
= next_pc
;
1846 * Never called concurrently (hash seed is shared).
1848 int lttng_filter_validate_bytecode(struct bytecode_runtime
*bytecode
)
1850 struct cds_lfht
*merge_points
;
1851 char *pc
, *next_pc
, *start_pc
;
1853 struct vstack stack
;
1855 vstack_init(&stack
);
1857 if (!lttng_hash_seed_ready
) {
1858 lttng_hash_seed
= time(NULL
);
1859 lttng_hash_seed_ready
= 1;
1862 * Note: merge_points hash table used by single thread, and
1863 * never concurrently resized. Therefore, we can use it without
1864 * holding RCU read-side lock and free nodes without using
1867 merge_points
= cds_lfht_new(DEFAULT_NR_MERGE_POINTS
,
1868 MIN_NR_BUCKETS
, MAX_NR_BUCKETS
,
1870 if (!merge_points
) {
1871 ERR("Error allocating hash table for bytecode validation\n");
1874 start_pc
= &bytecode
->code
[0];
1875 for (pc
= next_pc
= start_pc
; pc
- start_pc
< bytecode
->len
;
1877 ret
= bytecode_validate_overflow(bytecode
, start_pc
, pc
);
1880 ERR("filter bytecode overflow\n");
1883 dbg_printf("Validating op %s (%u)\n",
1884 print_op((unsigned int) *(filter_opcode_t
*) pc
),
1885 (unsigned int) *(filter_opcode_t
*) pc
);
1888 * For each instruction, validate the current context
1889 * (traversal of entire execution flow), and validate
1890 * all merge points targeting this instruction.
1892 ret
= validate_instruction_all_contexts(bytecode
, merge_points
,
1893 &stack
, start_pc
, pc
);
1896 ret
= exec_insn(bytecode
, merge_points
, &stack
, &next_pc
, pc
);
1901 if (delete_all_nodes(merge_points
)) {
1903 ERR("Unexpected merge points\n");
1907 if (cds_lfht_destroy(merge_points
, NULL
)) {
1908 ERR("Error destroying hash table\n");