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