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