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