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