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