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