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
33 #include <urcu/rculfhash.h>
35 #include "lttng-filter.h"
36 #include "lttng-hash-helper.h"
37 #include "string-utils.h"
40 * Number of merge points for hash table size. Hash table initialized to
41 * that size, and we do not resize, because we do not want to trigger
42 * RCU worker thread execution: fall-back on linear traversal if number
43 * of merge points exceeds this value.
45 #define DEFAULT_NR_MERGE_POINTS 128
46 #define MIN_NR_BUCKETS 128
47 #define MAX_NR_BUCKETS 128
49 /* merge point table node */
51 struct cds_lfht_node node
;
53 /* Context at merge point */
55 unsigned long target_pc
;
58 static unsigned long lttng_hash_seed
;
59 static unsigned int lttng_hash_seed_ready
;
62 int lttng_hash_match(struct cds_lfht_node
*node
, const void *key
)
64 struct lfht_mp_node
*mp_node
=
65 caa_container_of(node
, struct lfht_mp_node
, node
);
66 unsigned long key_pc
= (unsigned long) key
;
68 if (mp_node
->target_pc
== key_pc
)
75 int merge_points_compare(const struct vstack
*stacka
,
76 const struct vstack
*stackb
)
80 if (stacka
->top
!= stackb
->top
)
82 len
= stacka
->top
+ 1;
84 for (i
= 0; i
< len
; i
++) {
85 if (stacka
->e
[i
].type
!= REG_UNKNOWN
86 && stackb
->e
[i
].type
!= REG_UNKNOWN
87 && stacka
->e
[i
].type
!= stackb
->e
[i
].type
)
94 int merge_point_add_check(struct cds_lfht
*ht
, unsigned long target_pc
,
95 const struct vstack
*stack
)
97 struct lfht_mp_node
*node
;
98 unsigned long hash
= lttng_hash_mix((const char *) target_pc
,
101 struct cds_lfht_node
*ret
;
103 dbg_printf("Filter: adding merge point at offset %lu, hash %lu\n",
105 node
= zmalloc(sizeof(struct lfht_mp_node
));
108 node
->target_pc
= target_pc
;
109 memcpy(&node
->stack
, stack
, sizeof(node
->stack
));
110 ret
= cds_lfht_add_unique(ht
, hash
, lttng_hash_match
,
111 (const char *) target_pc
, &node
->node
);
112 if (ret
!= &node
->node
) {
113 struct lfht_mp_node
*ret_mp
=
114 caa_container_of(ret
, struct lfht_mp_node
, node
);
116 /* Key already present */
117 dbg_printf("Filter: compare merge points for offset %lu, hash %lu\n",
120 if (merge_points_compare(stack
, &ret_mp
->stack
)) {
121 ERR("Merge points differ for offset %lu\n",
130 * Binary comparators use top of stack and top of stack -1.
131 * Return 0 if typing is known to match, 1 if typing is dynamic
132 * (unknown), negative error value on error.
135 int bin_op_compare_check(struct vstack
*stack
, filter_opcode_t opcode
,
138 if (unlikely(!vstack_ax(stack
) || !vstack_bx(stack
)))
141 switch (vstack_ax(stack
)->type
) {
148 switch (vstack_bx(stack
)->type
) {
156 case REG_STAR_GLOB_STRING
:
157 if (opcode
!= FILTER_OP_EQ
&& opcode
!= FILTER_OP_NE
) {
166 case REG_STAR_GLOB_STRING
:
167 switch (vstack_bx(stack
)->type
) {
174 if (opcode
!= FILTER_OP_EQ
&& opcode
!= FILTER_OP_NE
) {
178 case REG_STAR_GLOB_STRING
:
186 switch (vstack_bx(stack
)->type
) {
193 case REG_STAR_GLOB_STRING
:
207 ERR("type mismatch for '%s' binary operator\n", str
);
211 ERR("empty stack for '%s' binary operator\n", str
);
215 ERR("unknown type for '%s' binary operator\n", str
);
220 * Binary bitwise operators use top of stack and top of stack -1.
221 * Return 0 if typing is known to match, 1 if typing is dynamic
222 * (unknown), negative error value on error.
225 int bin_op_bitwise_check(struct vstack
*stack
, filter_opcode_t opcode
,
228 if (unlikely(!vstack_ax(stack
) || !vstack_bx(stack
)))
231 switch (vstack_ax(stack
)->type
) {
238 switch (vstack_bx(stack
)->type
) {
255 ERR("empty stack for '%s' binary operator\n", str
);
259 ERR("unknown type for '%s' binary operator\n", str
);
264 int validate_get_symbol(struct bytecode_runtime
*bytecode
,
265 const struct get_symbol
*sym
)
267 const char *str
, *str_limit
;
270 if (sym
->offset
>= bytecode
->p
.bc
->bc
.len
- bytecode
->p
.bc
->bc
.reloc_offset
)
273 str
= bytecode
->p
.bc
->bc
.data
+ bytecode
->p
.bc
->bc
.reloc_offset
+ sym
->offset
;
274 str_limit
= bytecode
->p
.bc
->bc
.data
+ bytecode
->p
.bc
->bc
.len
;
275 len_limit
= str_limit
- str
;
276 if (strnlen(str
, len_limit
) == len_limit
)
282 * Validate bytecode range overflow within the validation pass.
283 * Called for each instruction encountered.
286 int bytecode_validate_overflow(struct bytecode_runtime
*bytecode
,
287 char *start_pc
, char *pc
)
291 switch (*(filter_opcode_t
*) pc
) {
292 case FILTER_OP_UNKNOWN
:
295 ERR("unknown bytecode op %u\n",
296 (unsigned int) *(filter_opcode_t
*) pc
);
301 case FILTER_OP_RETURN
:
302 case FILTER_OP_RETURN_S64
:
304 if (unlikely(pc
+ sizeof(struct return_op
)
305 > start_pc
+ bytecode
->len
)) {
316 case FILTER_OP_MINUS
:
318 ERR("unsupported bytecode op %u\n",
319 (unsigned int) *(filter_opcode_t
*) pc
);
330 case FILTER_OP_EQ_STRING
:
331 case FILTER_OP_NE_STRING
:
332 case FILTER_OP_GT_STRING
:
333 case FILTER_OP_LT_STRING
:
334 case FILTER_OP_GE_STRING
:
335 case FILTER_OP_LE_STRING
:
336 case FILTER_OP_EQ_STAR_GLOB_STRING
:
337 case FILTER_OP_NE_STAR_GLOB_STRING
:
338 case FILTER_OP_EQ_S64
:
339 case FILTER_OP_NE_S64
:
340 case FILTER_OP_GT_S64
:
341 case FILTER_OP_LT_S64
:
342 case FILTER_OP_GE_S64
:
343 case FILTER_OP_LE_S64
:
344 case FILTER_OP_EQ_DOUBLE
:
345 case FILTER_OP_NE_DOUBLE
:
346 case FILTER_OP_GT_DOUBLE
:
347 case FILTER_OP_LT_DOUBLE
:
348 case FILTER_OP_GE_DOUBLE
:
349 case FILTER_OP_LE_DOUBLE
:
350 case FILTER_OP_EQ_DOUBLE_S64
:
351 case FILTER_OP_NE_DOUBLE_S64
:
352 case FILTER_OP_GT_DOUBLE_S64
:
353 case FILTER_OP_LT_DOUBLE_S64
:
354 case FILTER_OP_GE_DOUBLE_S64
:
355 case FILTER_OP_LE_DOUBLE_S64
:
356 case FILTER_OP_EQ_S64_DOUBLE
:
357 case FILTER_OP_NE_S64_DOUBLE
:
358 case FILTER_OP_GT_S64_DOUBLE
:
359 case FILTER_OP_LT_S64_DOUBLE
:
360 case FILTER_OP_GE_S64_DOUBLE
:
361 case FILTER_OP_LE_S64_DOUBLE
:
362 case FILTER_OP_BIT_RSHIFT
:
363 case FILTER_OP_BIT_LSHIFT
:
364 case FILTER_OP_BIT_AND
:
365 case FILTER_OP_BIT_OR
:
366 case FILTER_OP_BIT_XOR
:
368 if (unlikely(pc
+ sizeof(struct binary_op
)
369 > start_pc
+ bytecode
->len
)) {
376 case FILTER_OP_UNARY_PLUS
:
377 case FILTER_OP_UNARY_MINUS
:
378 case FILTER_OP_UNARY_NOT
:
379 case FILTER_OP_UNARY_PLUS_S64
:
380 case FILTER_OP_UNARY_MINUS_S64
:
381 case FILTER_OP_UNARY_NOT_S64
:
382 case FILTER_OP_UNARY_PLUS_DOUBLE
:
383 case FILTER_OP_UNARY_MINUS_DOUBLE
:
384 case FILTER_OP_UNARY_NOT_DOUBLE
:
385 case FILTER_OP_UNARY_BIT_NOT
:
387 if (unlikely(pc
+ sizeof(struct unary_op
)
388 > start_pc
+ bytecode
->len
)) {
398 if (unlikely(pc
+ sizeof(struct logical_op
)
399 > start_pc
+ bytecode
->len
)) {
406 case FILTER_OP_LOAD_FIELD_REF
:
408 ERR("Unknown field ref type\n");
413 /* get context ref */
414 case FILTER_OP_GET_CONTEXT_REF
:
415 case FILTER_OP_LOAD_FIELD_REF_STRING
:
416 case FILTER_OP_LOAD_FIELD_REF_SEQUENCE
:
417 case FILTER_OP_LOAD_FIELD_REF_S64
:
418 case FILTER_OP_LOAD_FIELD_REF_DOUBLE
:
419 case FILTER_OP_GET_CONTEXT_REF_STRING
:
420 case FILTER_OP_GET_CONTEXT_REF_S64
:
421 case FILTER_OP_GET_CONTEXT_REF_DOUBLE
:
423 if (unlikely(pc
+ sizeof(struct load_op
) + sizeof(struct field_ref
)
424 > start_pc
+ bytecode
->len
)) {
430 /* load from immediate operand */
431 case FILTER_OP_LOAD_STRING
:
432 case FILTER_OP_LOAD_STAR_GLOB_STRING
:
434 struct load_op
*insn
= (struct load_op
*) pc
;
435 uint32_t str_len
, maxlen
;
437 if (unlikely(pc
+ sizeof(struct load_op
)
438 > start_pc
+ bytecode
->len
)) {
443 maxlen
= start_pc
+ bytecode
->len
- pc
- sizeof(struct load_op
);
444 str_len
= strnlen(insn
->data
, maxlen
);
445 if (unlikely(str_len
>= maxlen
)) {
446 /* Final '\0' not found within range */
452 case FILTER_OP_LOAD_S64
:
454 if (unlikely(pc
+ sizeof(struct load_op
) + sizeof(struct literal_numeric
)
455 > start_pc
+ bytecode
->len
)) {
461 case FILTER_OP_LOAD_DOUBLE
:
463 if (unlikely(pc
+ sizeof(struct load_op
) + sizeof(struct literal_double
)
464 > start_pc
+ bytecode
->len
)) {
470 case FILTER_OP_CAST_TO_S64
:
471 case FILTER_OP_CAST_DOUBLE_TO_S64
:
472 case FILTER_OP_CAST_NOP
:
474 if (unlikely(pc
+ sizeof(struct cast_op
)
475 > start_pc
+ bytecode
->len
)) {
482 * Instructions for recursive traversal through composed types.
484 case FILTER_OP_GET_CONTEXT_ROOT
:
485 case FILTER_OP_GET_APP_CONTEXT_ROOT
:
486 case FILTER_OP_GET_PAYLOAD_ROOT
:
487 case FILTER_OP_LOAD_FIELD
:
488 case FILTER_OP_LOAD_FIELD_S8
:
489 case FILTER_OP_LOAD_FIELD_S16
:
490 case FILTER_OP_LOAD_FIELD_S32
:
491 case FILTER_OP_LOAD_FIELD_S64
:
492 case FILTER_OP_LOAD_FIELD_U8
:
493 case FILTER_OP_LOAD_FIELD_U16
:
494 case FILTER_OP_LOAD_FIELD_U32
:
495 case FILTER_OP_LOAD_FIELD_U64
:
496 case FILTER_OP_LOAD_FIELD_STRING
:
497 case FILTER_OP_LOAD_FIELD_SEQUENCE
:
498 case FILTER_OP_LOAD_FIELD_DOUBLE
:
499 if (unlikely(pc
+ sizeof(struct load_op
)
500 > start_pc
+ bytecode
->len
)) {
505 case FILTER_OP_GET_SYMBOL
:
507 struct load_op
*insn
= (struct load_op
*) pc
;
508 struct get_symbol
*sym
= (struct get_symbol
*) insn
->data
;
510 if (unlikely(pc
+ sizeof(struct load_op
) + sizeof(struct get_symbol
)
511 > start_pc
+ bytecode
->len
)) {
515 ret
= validate_get_symbol(bytecode
, sym
);
519 case FILTER_OP_GET_SYMBOL_FIELD
:
520 ERR("Unexpected get symbol field");
524 case FILTER_OP_GET_INDEX_U16
:
525 if (unlikely(pc
+ sizeof(struct load_op
) + sizeof(struct get_index_u16
)
526 > start_pc
+ bytecode
->len
)) {
531 case FILTER_OP_GET_INDEX_U64
:
532 if (unlikely(pc
+ sizeof(struct load_op
) + sizeof(struct get_index_u64
)
533 > start_pc
+ bytecode
->len
)) {
543 unsigned long delete_all_nodes(struct cds_lfht
*ht
)
545 struct cds_lfht_iter iter
;
546 struct lfht_mp_node
*node
;
547 unsigned long nr_nodes
= 0;
549 cds_lfht_for_each_entry(ht
, &iter
, node
, node
) {
552 ret
= cds_lfht_del(ht
, cds_lfht_iter_get_node(&iter
));
554 /* note: this hash table is never used concurrently */
567 int validate_instruction_context(struct bytecode_runtime
*bytecode
,
568 struct vstack
*stack
,
573 const filter_opcode_t opcode
= *(filter_opcode_t
*) pc
;
576 case FILTER_OP_UNKNOWN
:
579 ERR("unknown bytecode op %u\n",
580 (unsigned int) *(filter_opcode_t
*) pc
);
585 case FILTER_OP_RETURN
:
586 case FILTER_OP_RETURN_S64
:
596 case FILTER_OP_MINUS
:
598 ERR("unsupported bytecode op %u\n",
599 (unsigned int) opcode
);
606 ret
= bin_op_compare_check(stack
, opcode
, "==");
613 ret
= bin_op_compare_check(stack
, opcode
, "!=");
620 ret
= bin_op_compare_check(stack
, opcode
, ">");
627 ret
= bin_op_compare_check(stack
, opcode
, "<");
634 ret
= bin_op_compare_check(stack
, opcode
, ">=");
641 ret
= bin_op_compare_check(stack
, opcode
, "<=");
647 case FILTER_OP_EQ_STRING
:
648 case FILTER_OP_NE_STRING
:
649 case FILTER_OP_GT_STRING
:
650 case FILTER_OP_LT_STRING
:
651 case FILTER_OP_GE_STRING
:
652 case FILTER_OP_LE_STRING
:
654 if (!vstack_ax(stack
) || !vstack_bx(stack
)) {
655 ERR("Empty stack\n");
659 if (vstack_ax(stack
)->type
!= REG_STRING
660 || vstack_bx(stack
)->type
!= REG_STRING
) {
661 ERR("Unexpected register type for string comparator\n");
668 case FILTER_OP_EQ_STAR_GLOB_STRING
:
669 case FILTER_OP_NE_STAR_GLOB_STRING
:
671 if (!vstack_ax(stack
) || !vstack_bx(stack
)) {
672 ERR("Empty stack\n");
676 if (vstack_ax(stack
)->type
!= REG_STAR_GLOB_STRING
677 && vstack_bx(stack
)->type
!= REG_STAR_GLOB_STRING
) {
678 ERR("Unexpected register type for globbing pattern comparator\n");
685 case FILTER_OP_EQ_S64
:
686 case FILTER_OP_NE_S64
:
687 case FILTER_OP_GT_S64
:
688 case FILTER_OP_LT_S64
:
689 case FILTER_OP_GE_S64
:
690 case FILTER_OP_LE_S64
:
692 if (!vstack_ax(stack
) || !vstack_bx(stack
)) {
693 ERR("Empty stack\n");
697 if (vstack_ax(stack
)->type
!= REG_S64
698 || vstack_bx(stack
)->type
!= REG_S64
) {
699 ERR("Unexpected register type for s64 comparator\n");
706 case FILTER_OP_EQ_DOUBLE
:
707 case FILTER_OP_NE_DOUBLE
:
708 case FILTER_OP_GT_DOUBLE
:
709 case FILTER_OP_LT_DOUBLE
:
710 case FILTER_OP_GE_DOUBLE
:
711 case FILTER_OP_LE_DOUBLE
:
713 if (!vstack_ax(stack
) || !vstack_bx(stack
)) {
714 ERR("Empty stack\n");
718 if (vstack_ax(stack
)->type
!= REG_DOUBLE
&& vstack_bx(stack
)->type
!= REG_DOUBLE
) {
719 ERR("Double operator should have two double registers\n");
726 case FILTER_OP_EQ_DOUBLE_S64
:
727 case FILTER_OP_NE_DOUBLE_S64
:
728 case FILTER_OP_GT_DOUBLE_S64
:
729 case FILTER_OP_LT_DOUBLE_S64
:
730 case FILTER_OP_GE_DOUBLE_S64
:
731 case FILTER_OP_LE_DOUBLE_S64
:
733 if (!vstack_ax(stack
) || !vstack_bx(stack
)) {
734 ERR("Empty stack\n");
738 if (vstack_ax(stack
)->type
!= REG_S64
&& vstack_bx(stack
)->type
!= REG_DOUBLE
) {
739 ERR("Double-S64 operator has unexpected register types\n");
746 case FILTER_OP_EQ_S64_DOUBLE
:
747 case FILTER_OP_NE_S64_DOUBLE
:
748 case FILTER_OP_GT_S64_DOUBLE
:
749 case FILTER_OP_LT_S64_DOUBLE
:
750 case FILTER_OP_GE_S64_DOUBLE
:
751 case FILTER_OP_LE_S64_DOUBLE
:
753 if (!vstack_ax(stack
) || !vstack_bx(stack
)) {
754 ERR("Empty stack\n");
758 if (vstack_ax(stack
)->type
!= REG_DOUBLE
&& vstack_bx(stack
)->type
!= REG_S64
) {
759 ERR("S64-Double operator has unexpected register types\n");
766 case FILTER_OP_BIT_RSHIFT
:
767 ret
= bin_op_bitwise_check(stack
, opcode
, ">>");
771 case FILTER_OP_BIT_LSHIFT
:
772 ret
= bin_op_bitwise_check(stack
, opcode
, "<<");
776 case FILTER_OP_BIT_AND
:
777 ret
= bin_op_bitwise_check(stack
, opcode
, "&");
781 case FILTER_OP_BIT_OR
:
782 ret
= bin_op_bitwise_check(stack
, opcode
, "|");
786 case FILTER_OP_BIT_XOR
:
787 ret
= bin_op_bitwise_check(stack
, opcode
, "^");
793 case FILTER_OP_UNARY_PLUS
:
794 case FILTER_OP_UNARY_MINUS
:
795 case FILTER_OP_UNARY_NOT
:
797 if (!vstack_ax(stack
)) {
798 ERR("Empty stack\n");
802 switch (vstack_ax(stack
)->type
) {
804 ERR("unknown register type\n");
809 case REG_STAR_GLOB_STRING
:
810 ERR("Unary op can only be applied to numeric or floating point registers\n");
822 case FILTER_OP_UNARY_BIT_NOT
:
824 if (!vstack_ax(stack
)) {
825 ERR("Empty stack\n");
829 switch (vstack_ax(stack
)->type
) {
831 ERR("unknown register type\n");
836 case REG_STAR_GLOB_STRING
:
838 ERR("Unary bitwise op can only be applied to numeric registers\n");
849 case FILTER_OP_UNARY_PLUS_S64
:
850 case FILTER_OP_UNARY_MINUS_S64
:
851 case FILTER_OP_UNARY_NOT_S64
:
853 if (!vstack_ax(stack
)) {
854 ERR("Empty stack\n");
858 if (vstack_ax(stack
)->type
!= REG_S64
) {
859 ERR("Invalid register type\n");
866 case FILTER_OP_UNARY_PLUS_DOUBLE
:
867 case FILTER_OP_UNARY_MINUS_DOUBLE
:
868 case FILTER_OP_UNARY_NOT_DOUBLE
:
870 if (!vstack_ax(stack
)) {
871 ERR("Empty stack\n");
875 if (vstack_ax(stack
)->type
!= REG_DOUBLE
) {
876 ERR("Invalid register type\n");
887 struct logical_op
*insn
= (struct logical_op
*) pc
;
889 if (!vstack_ax(stack
)) {
890 ERR("Empty stack\n");
894 if (vstack_ax(stack
)->type
!= REG_S64
895 && vstack_ax(stack
)->type
!= REG_UNKNOWN
) {
896 ERR("Logical comparator expects S64 or dynamic register\n");
901 dbg_printf("Validate jumping to bytecode offset %u\n",
902 (unsigned int) insn
->skip_offset
);
903 if (unlikely(start_pc
+ insn
->skip_offset
<= pc
)) {
904 ERR("Loops are not allowed in bytecode\n");
912 case FILTER_OP_LOAD_FIELD_REF
:
914 ERR("Unknown field ref type\n");
918 case FILTER_OP_LOAD_FIELD_REF_STRING
:
919 case FILTER_OP_LOAD_FIELD_REF_SEQUENCE
:
921 struct load_op
*insn
= (struct load_op
*) pc
;
922 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
924 dbg_printf("Validate load field ref offset %u type string\n",
928 case FILTER_OP_LOAD_FIELD_REF_S64
:
930 struct load_op
*insn
= (struct load_op
*) pc
;
931 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
933 dbg_printf("Validate load field ref offset %u type s64\n",
937 case FILTER_OP_LOAD_FIELD_REF_DOUBLE
:
939 struct load_op
*insn
= (struct load_op
*) pc
;
940 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
942 dbg_printf("Validate load field ref offset %u type double\n",
947 /* load from immediate operand */
948 case FILTER_OP_LOAD_STRING
:
949 case FILTER_OP_LOAD_STAR_GLOB_STRING
:
954 case FILTER_OP_LOAD_S64
:
959 case FILTER_OP_LOAD_DOUBLE
:
964 case FILTER_OP_CAST_TO_S64
:
965 case FILTER_OP_CAST_DOUBLE_TO_S64
:
967 struct cast_op
*insn
= (struct cast_op
*) pc
;
969 if (!vstack_ax(stack
)) {
970 ERR("Empty stack\n");
974 switch (vstack_ax(stack
)->type
) {
976 ERR("unknown register type\n");
981 case REG_STAR_GLOB_STRING
:
982 ERR("Cast op can only be applied to numeric or floating point registers\n");
992 if (insn
->op
== FILTER_OP_CAST_DOUBLE_TO_S64
) {
993 if (vstack_ax(stack
)->type
!= REG_DOUBLE
) {
994 ERR("Cast expects double\n");
1001 case FILTER_OP_CAST_NOP
:
1006 /* get context ref */
1007 case FILTER_OP_GET_CONTEXT_REF
:
1009 struct load_op
*insn
= (struct load_op
*) pc
;
1010 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1012 dbg_printf("Validate get context ref offset %u type dynamic\n",
1016 case FILTER_OP_GET_CONTEXT_REF_STRING
:
1018 struct load_op
*insn
= (struct load_op
*) pc
;
1019 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1021 dbg_printf("Validate get context ref offset %u type string\n",
1025 case FILTER_OP_GET_CONTEXT_REF_S64
:
1027 struct load_op
*insn
= (struct load_op
*) pc
;
1028 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1030 dbg_printf("Validate get context ref offset %u type s64\n",
1034 case FILTER_OP_GET_CONTEXT_REF_DOUBLE
:
1036 struct load_op
*insn
= (struct load_op
*) pc
;
1037 struct field_ref
*ref
= (struct field_ref
*) insn
->data
;
1039 dbg_printf("Validate get context ref offset %u type double\n",
1045 * Instructions for recursive traversal through composed types.
1047 case FILTER_OP_GET_CONTEXT_ROOT
:
1049 dbg_printf("Validate get context root\n");
1052 case FILTER_OP_GET_APP_CONTEXT_ROOT
:
1054 dbg_printf("Validate get app context root\n");
1057 case FILTER_OP_GET_PAYLOAD_ROOT
:
1059 dbg_printf("Validate get payload root\n");
1062 case FILTER_OP_LOAD_FIELD
:
1065 * We tolerate that field type is unknown at validation,
1066 * because we are performing the load specialization in
1067 * a phase after validation.
1069 dbg_printf("Validate load field\n");
1072 case FILTER_OP_LOAD_FIELD_S8
:
1074 dbg_printf("Validate load field s8\n");
1077 case FILTER_OP_LOAD_FIELD_S16
:
1079 dbg_printf("Validate load field s16\n");
1082 case FILTER_OP_LOAD_FIELD_S32
:
1084 dbg_printf("Validate load field s32\n");
1087 case FILTER_OP_LOAD_FIELD_S64
:
1089 dbg_printf("Validate load field s64\n");
1092 case FILTER_OP_LOAD_FIELD_U8
:
1094 dbg_printf("Validate load field u8\n");
1097 case FILTER_OP_LOAD_FIELD_U16
:
1099 dbg_printf("Validate load field u16\n");
1102 case FILTER_OP_LOAD_FIELD_U32
:
1104 dbg_printf("Validate load field u32\n");
1107 case FILTER_OP_LOAD_FIELD_U64
:
1109 dbg_printf("Validate load field u64\n");
1112 case FILTER_OP_LOAD_FIELD_STRING
:
1114 dbg_printf("Validate load field string\n");
1117 case FILTER_OP_LOAD_FIELD_SEQUENCE
:
1119 dbg_printf("Validate load field sequence\n");
1122 case FILTER_OP_LOAD_FIELD_DOUBLE
:
1124 dbg_printf("Validate load field double\n");
1128 case FILTER_OP_GET_SYMBOL
:
1130 struct load_op
*insn
= (struct load_op
*) pc
;
1131 struct get_symbol
*sym
= (struct get_symbol
*) insn
->data
;
1133 dbg_printf("Validate get symbol offset %u\n", sym
->offset
);
1137 case FILTER_OP_GET_SYMBOL_FIELD
:
1139 struct load_op
*insn
= (struct load_op
*) pc
;
1140 struct get_symbol
*sym
= (struct get_symbol
*) insn
->data
;
1142 dbg_printf("Validate get symbol field offset %u\n", sym
->offset
);
1146 case FILTER_OP_GET_INDEX_U16
:
1148 struct load_op
*insn
= (struct load_op
*) pc
;
1149 struct get_index_u16
*get_index
= (struct get_index_u16
*) insn
->data
;
1151 dbg_printf("Validate get index u16 index %u\n", get_index
->index
);
1155 case FILTER_OP_GET_INDEX_U64
:
1157 struct load_op
*insn
= (struct load_op
*) pc
;
1158 struct get_index_u64
*get_index
= (struct get_index_u64
*) insn
->data
;
1160 dbg_printf("Validate get index u64 index %" PRIu64
"\n", get_index
->index
);
1174 int validate_instruction_all_contexts(struct bytecode_runtime
*bytecode
,
1175 struct cds_lfht
*merge_points
,
1176 struct vstack
*stack
,
1181 unsigned long target_pc
= pc
- start_pc
;
1182 struct cds_lfht_iter iter
;
1183 struct cds_lfht_node
*node
;
1184 struct lfht_mp_node
*mp_node
;
1187 /* Validate the context resulting from the previous instruction */
1188 ret
= validate_instruction_context(bytecode
, stack
, start_pc
, pc
);
1192 /* Validate merge points */
1193 hash
= lttng_hash_mix((const char *) target_pc
, sizeof(target_pc
),
1195 cds_lfht_lookup(merge_points
, hash
, lttng_hash_match
,
1196 (const char *) target_pc
, &iter
);
1197 node
= cds_lfht_iter_get_node(&iter
);
1199 mp_node
= caa_container_of(node
, struct lfht_mp_node
, node
);
1201 dbg_printf("Filter: validate merge point at offset %lu\n",
1203 if (merge_points_compare(stack
, &mp_node
->stack
)) {
1204 ERR("Merge points differ for offset %lu\n",
1208 /* Once validated, we can remove the merge point */
1209 dbg_printf("Filter: remove merge point at offset %lu\n",
1211 ret
= cds_lfht_del(merge_points
, node
);
1219 * >0: going to next insn.
1220 * 0: success, stop iteration.
1224 int exec_insn(struct bytecode_runtime
*bytecode
,
1225 struct cds_lfht
*merge_points
,
1226 struct vstack
*stack
,
1231 char *next_pc
= *_next_pc
;
1233 switch (*(filter_opcode_t
*) pc
) {
1234 case FILTER_OP_UNKNOWN
:
1237 ERR("unknown bytecode op %u\n",
1238 (unsigned int) *(filter_opcode_t
*) pc
);
1243 case FILTER_OP_RETURN
:
1245 if (!vstack_ax(stack
)) {
1246 ERR("Empty stack\n");
1250 switch (vstack_ax(stack
)->type
) {
1255 ERR("Unexpected register type %d at end of bytecode\n",
1256 (int) vstack_ax(stack
)->type
);
1264 case FILTER_OP_RETURN_S64
:
1266 if (!vstack_ax(stack
)) {
1267 ERR("Empty stack\n");
1271 switch (vstack_ax(stack
)->type
) {
1276 ERR("Unexpected register type %d at end of bytecode\n",
1277 (int) vstack_ax(stack
)->type
);
1290 case FILTER_OP_PLUS
:
1291 case FILTER_OP_MINUS
:
1293 ERR("unsupported bytecode op %u\n",
1294 (unsigned int) *(filter_opcode_t
*) pc
);
1305 case FILTER_OP_EQ_STRING
:
1306 case FILTER_OP_NE_STRING
:
1307 case FILTER_OP_GT_STRING
:
1308 case FILTER_OP_LT_STRING
:
1309 case FILTER_OP_GE_STRING
:
1310 case FILTER_OP_LE_STRING
:
1311 case FILTER_OP_EQ_STAR_GLOB_STRING
:
1312 case FILTER_OP_NE_STAR_GLOB_STRING
:
1313 case FILTER_OP_EQ_S64
:
1314 case FILTER_OP_NE_S64
:
1315 case FILTER_OP_GT_S64
:
1316 case FILTER_OP_LT_S64
:
1317 case FILTER_OP_GE_S64
:
1318 case FILTER_OP_LE_S64
:
1319 case FILTER_OP_EQ_DOUBLE
:
1320 case FILTER_OP_NE_DOUBLE
:
1321 case FILTER_OP_GT_DOUBLE
:
1322 case FILTER_OP_LT_DOUBLE
:
1323 case FILTER_OP_GE_DOUBLE
:
1324 case FILTER_OP_LE_DOUBLE
:
1325 case FILTER_OP_EQ_DOUBLE_S64
:
1326 case FILTER_OP_NE_DOUBLE_S64
:
1327 case FILTER_OP_GT_DOUBLE_S64
:
1328 case FILTER_OP_LT_DOUBLE_S64
:
1329 case FILTER_OP_GE_DOUBLE_S64
:
1330 case FILTER_OP_LE_DOUBLE_S64
:
1331 case FILTER_OP_EQ_S64_DOUBLE
:
1332 case FILTER_OP_NE_S64_DOUBLE
:
1333 case FILTER_OP_GT_S64_DOUBLE
:
1334 case FILTER_OP_LT_S64_DOUBLE
:
1335 case FILTER_OP_GE_S64_DOUBLE
:
1336 case FILTER_OP_LE_S64_DOUBLE
:
1337 case FILTER_OP_BIT_RSHIFT
:
1338 case FILTER_OP_BIT_LSHIFT
:
1339 case FILTER_OP_BIT_AND
:
1340 case FILTER_OP_BIT_OR
:
1341 case FILTER_OP_BIT_XOR
:
1344 if (vstack_pop(stack
)) {
1348 if (!vstack_ax(stack
)) {
1349 ERR("Empty stack\n");
1353 switch (vstack_ax(stack
)->type
) {
1357 case REG_STAR_GLOB_STRING
:
1361 ERR("Unexpected register type %d for operation\n",
1362 (int) vstack_ax(stack
)->type
);
1367 vstack_ax(stack
)->type
= REG_S64
;
1368 next_pc
+= sizeof(struct binary_op
);
1373 case FILTER_OP_UNARY_PLUS
:
1374 case FILTER_OP_UNARY_MINUS
:
1377 if (!vstack_ax(stack
)) {
1378 ERR("Empty stack\n");
1382 switch (vstack_ax(stack
)->type
) {
1388 ERR("Unexpected register type %d for operation\n",
1389 (int) vstack_ax(stack
)->type
);
1393 vstack_ax(stack
)->type
= REG_UNKNOWN
;
1394 next_pc
+= sizeof(struct unary_op
);
1398 case FILTER_OP_UNARY_PLUS_S64
:
1399 case FILTER_OP_UNARY_MINUS_S64
:
1400 case FILTER_OP_UNARY_NOT_S64
:
1403 if (!vstack_ax(stack
)) {
1404 ERR("Empty stack\n");
1408 switch (vstack_ax(stack
)->type
) {
1412 ERR("Unexpected register type %d for operation\n",
1413 (int) vstack_ax(stack
)->type
);
1418 vstack_ax(stack
)->type
= REG_S64
;
1419 next_pc
+= sizeof(struct unary_op
);
1423 case FILTER_OP_UNARY_NOT
:
1426 if (!vstack_ax(stack
)) {
1427 ERR("Empty stack\n");
1431 switch (vstack_ax(stack
)->type
) {
1437 ERR("Unexpected register type %d for operation\n",
1438 (int) vstack_ax(stack
)->type
);
1443 vstack_ax(stack
)->type
= REG_S64
;
1444 next_pc
+= sizeof(struct unary_op
);
1448 case FILTER_OP_UNARY_BIT_NOT
:
1451 if (!vstack_ax(stack
)) {
1452 ERR("Empty stack\n");
1456 switch (vstack_ax(stack
)->type
) {
1462 ERR("Unexpected register type %d for operation\n",
1463 (int) vstack_ax(stack
)->type
);
1468 vstack_ax(stack
)->type
= REG_S64
;
1469 next_pc
+= sizeof(struct unary_op
);
1473 case FILTER_OP_UNARY_NOT_DOUBLE
:
1476 if (!vstack_ax(stack
)) {
1477 ERR("Empty stack\n");
1481 switch (vstack_ax(stack
)->type
) {
1485 ERR("Incorrect register type %d for operation\n",
1486 (int) vstack_ax(stack
)->type
);
1491 vstack_ax(stack
)->type
= REG_S64
;
1492 next_pc
+= sizeof(struct unary_op
);
1496 case FILTER_OP_UNARY_PLUS_DOUBLE
:
1497 case FILTER_OP_UNARY_MINUS_DOUBLE
:
1500 if (!vstack_ax(stack
)) {
1501 ERR("Empty stack\n");
1505 switch (vstack_ax(stack
)->type
) {
1509 ERR("Incorrect register type %d for operation\n",
1510 (int) vstack_ax(stack
)->type
);
1515 vstack_ax(stack
)->type
= REG_DOUBLE
;
1516 next_pc
+= sizeof(struct unary_op
);
1524 struct logical_op
*insn
= (struct logical_op
*) pc
;
1527 /* Add merge point to table */
1528 merge_ret
= merge_point_add_check(merge_points
,
1529 insn
->skip_offset
, stack
);
1535 if (!vstack_ax(stack
)) {
1536 ERR("Empty stack\n");
1540 /* There is always a cast-to-s64 operation before a or/and op. */
1541 switch (vstack_ax(stack
)->type
) {
1545 ERR("Incorrect register type %d for operation\n",
1546 (int) vstack_ax(stack
)->type
);
1551 /* Continue to next instruction */
1552 /* Pop 1 when jump not taken */
1553 if (vstack_pop(stack
)) {
1557 next_pc
+= sizeof(struct logical_op
);
1561 /* load field ref */
1562 case FILTER_OP_LOAD_FIELD_REF
:
1564 ERR("Unknown field ref type\n");
1568 /* get context ref */
1569 case FILTER_OP_GET_CONTEXT_REF
:
1571 if (vstack_push(stack
)) {
1575 vstack_ax(stack
)->type
= REG_UNKNOWN
;
1576 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1579 case FILTER_OP_LOAD_FIELD_REF_STRING
:
1580 case FILTER_OP_LOAD_FIELD_REF_SEQUENCE
:
1581 case FILTER_OP_GET_CONTEXT_REF_STRING
:
1583 if (vstack_push(stack
)) {
1587 vstack_ax(stack
)->type
= REG_STRING
;
1588 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1591 case FILTER_OP_LOAD_FIELD_REF_S64
:
1592 case FILTER_OP_GET_CONTEXT_REF_S64
:
1594 if (vstack_push(stack
)) {
1598 vstack_ax(stack
)->type
= REG_S64
;
1599 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1602 case FILTER_OP_LOAD_FIELD_REF_DOUBLE
:
1603 case FILTER_OP_GET_CONTEXT_REF_DOUBLE
:
1605 if (vstack_push(stack
)) {
1609 vstack_ax(stack
)->type
= REG_DOUBLE
;
1610 next_pc
+= sizeof(struct load_op
) + sizeof(struct field_ref
);
1614 /* load from immediate operand */
1615 case FILTER_OP_LOAD_STRING
:
1617 struct load_op
*insn
= (struct load_op
*) pc
;
1619 if (vstack_push(stack
)) {
1623 vstack_ax(stack
)->type
= REG_STRING
;
1624 next_pc
+= sizeof(struct load_op
) + strlen(insn
->data
) + 1;
1628 case FILTER_OP_LOAD_STAR_GLOB_STRING
:
1630 struct load_op
*insn
= (struct load_op
*) pc
;
1632 if (vstack_push(stack
)) {
1636 vstack_ax(stack
)->type
= REG_STAR_GLOB_STRING
;
1637 next_pc
+= sizeof(struct load_op
) + strlen(insn
->data
) + 1;
1641 case FILTER_OP_LOAD_S64
:
1643 if (vstack_push(stack
)) {
1647 vstack_ax(stack
)->type
= REG_S64
;
1648 next_pc
+= sizeof(struct load_op
)
1649 + sizeof(struct literal_numeric
);
1653 case FILTER_OP_LOAD_DOUBLE
:
1655 if (vstack_push(stack
)) {
1659 vstack_ax(stack
)->type
= REG_DOUBLE
;
1660 next_pc
+= sizeof(struct load_op
)
1661 + sizeof(struct literal_double
);
1665 case FILTER_OP_CAST_TO_S64
:
1666 case FILTER_OP_CAST_DOUBLE_TO_S64
:
1669 if (!vstack_ax(stack
)) {
1670 ERR("Empty stack\n");
1674 switch (vstack_ax(stack
)->type
) {
1680 ERR("Incorrect register type %d for cast\n",
1681 (int) vstack_ax(stack
)->type
);
1685 vstack_ax(stack
)->type
= REG_S64
;
1686 next_pc
+= sizeof(struct cast_op
);
1689 case FILTER_OP_CAST_NOP
:
1691 next_pc
+= sizeof(struct cast_op
);
1696 * Instructions for recursive traversal through composed types.
1698 case FILTER_OP_GET_CONTEXT_ROOT
:
1699 case FILTER_OP_GET_APP_CONTEXT_ROOT
:
1700 case FILTER_OP_GET_PAYLOAD_ROOT
:
1702 if (vstack_push(stack
)) {
1706 vstack_ax(stack
)->type
= REG_PTR
;
1707 next_pc
+= sizeof(struct load_op
);
1711 case FILTER_OP_LOAD_FIELD
:
1714 if (!vstack_ax(stack
)) {
1715 ERR("Empty stack\n");
1719 if (vstack_ax(stack
)->type
!= REG_PTR
) {
1720 ERR("Expecting pointer on top of stack\n");
1724 vstack_ax(stack
)->type
= REG_UNKNOWN
;
1725 next_pc
+= sizeof(struct load_op
);
1729 case FILTER_OP_LOAD_FIELD_S8
:
1730 case FILTER_OP_LOAD_FIELD_S16
:
1731 case FILTER_OP_LOAD_FIELD_S32
:
1732 case FILTER_OP_LOAD_FIELD_S64
:
1733 case FILTER_OP_LOAD_FIELD_U8
:
1734 case FILTER_OP_LOAD_FIELD_U16
:
1735 case FILTER_OP_LOAD_FIELD_U32
:
1736 case FILTER_OP_LOAD_FIELD_U64
:
1739 if (!vstack_ax(stack
)) {
1740 ERR("Empty stack\n");
1744 if (vstack_ax(stack
)->type
!= REG_PTR
) {
1745 ERR("Expecting pointer on top of stack\n");
1749 vstack_ax(stack
)->type
= REG_S64
;
1750 next_pc
+= sizeof(struct load_op
);
1754 case FILTER_OP_LOAD_FIELD_STRING
:
1755 case FILTER_OP_LOAD_FIELD_SEQUENCE
:
1758 if (!vstack_ax(stack
)) {
1759 ERR("Empty stack\n");
1763 if (vstack_ax(stack
)->type
!= REG_PTR
) {
1764 ERR("Expecting pointer on top of stack\n");
1768 vstack_ax(stack
)->type
= REG_STRING
;
1769 next_pc
+= sizeof(struct load_op
);
1773 case FILTER_OP_LOAD_FIELD_DOUBLE
:
1776 if (!vstack_ax(stack
)) {
1777 ERR("Empty stack\n");
1781 if (vstack_ax(stack
)->type
!= REG_PTR
) {
1782 ERR("Expecting pointer on top of stack\n");
1786 vstack_ax(stack
)->type
= REG_DOUBLE
;
1787 next_pc
+= sizeof(struct load_op
);
1791 case FILTER_OP_GET_SYMBOL
:
1792 case FILTER_OP_GET_SYMBOL_FIELD
:
1795 if (!vstack_ax(stack
)) {
1796 ERR("Empty stack\n");
1800 if (vstack_ax(stack
)->type
!= REG_PTR
) {
1801 ERR("Expecting pointer on top of stack\n");
1805 next_pc
+= sizeof(struct load_op
) + sizeof(struct get_symbol
);
1809 case FILTER_OP_GET_INDEX_U16
:
1812 if (!vstack_ax(stack
)) {
1813 ERR("Empty stack\n");
1817 if (vstack_ax(stack
)->type
!= REG_PTR
) {
1818 ERR("Expecting pointer on top of stack\n");
1822 next_pc
+= sizeof(struct load_op
) + sizeof(struct get_index_u16
);
1826 case FILTER_OP_GET_INDEX_U64
:
1829 if (!vstack_ax(stack
)) {
1830 ERR("Empty stack\n");
1834 if (vstack_ax(stack
)->type
!= REG_PTR
) {
1835 ERR("Expecting pointer on top of stack\n");
1839 next_pc
+= sizeof(struct load_op
) + sizeof(struct get_index_u64
);
1845 *_next_pc
= next_pc
;
1850 * Never called concurrently (hash seed is shared).
1852 int lttng_filter_validate_bytecode(struct bytecode_runtime
*bytecode
)
1854 struct cds_lfht
*merge_points
;
1855 char *pc
, *next_pc
, *start_pc
;
1857 struct vstack stack
;
1859 vstack_init(&stack
);
1861 if (!lttng_hash_seed_ready
) {
1862 lttng_hash_seed
= time(NULL
);
1863 lttng_hash_seed_ready
= 1;
1866 * Note: merge_points hash table used by single thread, and
1867 * never concurrently resized. Therefore, we can use it without
1868 * holding RCU read-side lock and free nodes without using
1871 merge_points
= cds_lfht_new(DEFAULT_NR_MERGE_POINTS
,
1872 MIN_NR_BUCKETS
, MAX_NR_BUCKETS
,
1874 if (!merge_points
) {
1875 ERR("Error allocating hash table for bytecode validation\n");
1878 start_pc
= &bytecode
->code
[0];
1879 for (pc
= next_pc
= start_pc
; pc
- start_pc
< bytecode
->len
;
1881 ret
= bytecode_validate_overflow(bytecode
, start_pc
, pc
);
1884 ERR("filter bytecode overflow\n");
1887 dbg_printf("Validating op %s (%u)\n",
1888 print_op((unsigned int) *(filter_opcode_t
*) pc
),
1889 (unsigned int) *(filter_opcode_t
*) pc
);
1892 * For each instruction, validate the current context
1893 * (traversal of entire execution flow), and validate
1894 * all merge points targeting this instruction.
1896 ret
= validate_instruction_all_contexts(bytecode
, merge_points
,
1897 &stack
, start_pc
, pc
);
1900 ret
= exec_insn(bytecode
, merge_points
, &stack
, &next_pc
, pc
);
1905 if (delete_all_nodes(merge_points
)) {
1907 ERR("Unexpected merge points\n");
1911 if (cds_lfht_destroy(merge_points
, NULL
)) {
1912 ERR("Error destroying hash table\n");