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