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