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