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