Validate registers, no need to initialize to 0
[lttng-ust.git] / liblttng-ust / lttng-filter.c
1 /*
2 * lttng-filter.c
3 *
4 * LTTng UST filter code.
5 *
6 * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; only
11 * version 2.1 of the License.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23 #include <errno.h>
24 #include <stdio.h>
25 #include <helper.h>
26 #include <lttng/ust-events.h>
27 #include <stdint.h>
28 #include <errno.h>
29 #include <string.h>
30 #include <inttypes.h>
31 #include <limits.h>
32 #include <usterr-signal-safe.h>
33 #include "filter-bytecode.h"
34
35 #define NR_REG 2
36
37 #ifndef min_t
38 #define min_t(type, a, b) \
39 ((type) (a) < (type) (b) ? (type) (a) : (type) (b))
40 #endif
41
42 #ifndef likely
43 #define likely(x) __builtin_expect(!!(x), 1)
44 #endif
45
46 #ifndef unlikely
47 #define unlikely(x) __builtin_expect(!!(x), 0)
48 #endif
49
50 #ifdef DEBUG
51 #define dbg_printf(fmt, args...) printf("[debug bytecode] " fmt, ## args)
52 #else
53 #define dbg_printf(fmt, args...) \
54 do { \
55 /* do nothing but check printf format */ \
56 if (0) \
57 printf("[debug bytecode] " fmt, ## args); \
58 } while (0)
59 #endif
60
61 /* Linked bytecode */
62 struct bytecode_runtime {
63 uint16_t len;
64 char data[0];
65 };
66
67 enum reg_type {
68 REG_S64,
69 REG_DOUBLE,
70 REG_STRING,
71 REG_TYPE_UNKNOWN,
72 };
73
74 /* Validation registers */
75 struct vreg {
76 enum reg_type type;
77 int literal; /* is string literal ? */
78 };
79
80 /* Execution registers */
81 struct reg {
82 enum reg_type type;
83 int64_t v;
84 double d;
85
86 const char *str;
87 size_t seq_len;
88 int literal; /* is string literal ? */
89 };
90
91 static const char *opnames[] = {
92 [ FILTER_OP_UNKNOWN ] = "UNKNOWN",
93
94 [ FILTER_OP_RETURN ] = "RETURN",
95
96 /* binary */
97 [ FILTER_OP_MUL ] = "MUL",
98 [ FILTER_OP_DIV ] = "DIV",
99 [ FILTER_OP_MOD ] = "MOD",
100 [ FILTER_OP_PLUS ] = "PLUS",
101 [ FILTER_OP_MINUS ] = "MINUS",
102 [ FILTER_OP_RSHIFT ] = "RSHIFT",
103 [ FILTER_OP_LSHIFT ] = "LSHIFT",
104 [ FILTER_OP_BIN_AND ] = "BIN_AND",
105 [ FILTER_OP_BIN_OR ] = "BIN_OR",
106 [ FILTER_OP_BIN_XOR ] = "BIN_XOR",
107 [ FILTER_OP_EQ ] = "EQ",
108 [ FILTER_OP_NE ] = "NE",
109 [ FILTER_OP_GT ] = "GT",
110 [ FILTER_OP_LT ] = "LT",
111 [ FILTER_OP_GE ] = "GE",
112 [ FILTER_OP_LE ] = "LE",
113
114 /* unary */
115 [ FILTER_OP_UNARY_PLUS ] = "UNARY_PLUS",
116 [ FILTER_OP_UNARY_MINUS ] = "UNARY_MINUS",
117 [ FILTER_OP_UNARY_NOT ] = "UNARY_NOT",
118
119 /* logical */
120 [ FILTER_OP_AND ] = "AND",
121 [ FILTER_OP_OR ] = "OR",
122
123 /* load */
124 [ FILTER_OP_LOAD_FIELD_REF ] = "LOAD_FIELD_REF",
125 [ FILTER_OP_LOAD_FIELD_REF_STRING ] = "LOAD_FIELD_REF_STRING",
126 [ FILTER_OP_LOAD_FIELD_REF_SEQUENCE ] = "LOAD_FIELD_REF_SEQUENCE",
127 [ FILTER_OP_LOAD_FIELD_REF_S64 ] = "LOAD_FIELD_REF_S64",
128 [ FILTER_OP_LOAD_FIELD_REF_DOUBLE ] = "LOAD_FIELD_REF_DOUBLE",
129
130 [ FILTER_OP_LOAD_STRING ] = "LOAD_STRING",
131 [ FILTER_OP_LOAD_S64 ] = "LOAD_S64",
132 [ FILTER_OP_LOAD_DOUBLE ] = "LOAD_DOUBLE",
133 };
134
135 static
136 const char *print_op(enum filter_op op)
137 {
138 if (op >= NR_FILTER_OPS)
139 return "UNKNOWN";
140 else
141 return opnames[op];
142 }
143
144 /*
145 * -1: wildcard found.
146 * -2: unknown escape char.
147 * 0: normal char.
148 */
149
150 static
151 int parse_char(const char **p)
152 {
153 switch (**p) {
154 case '\\':
155 (*p)++;
156 switch (**p) {
157 case '\\':
158 case '*':
159 return 0;
160 default:
161 return -2;
162 }
163 case '*':
164 return -1;
165 default:
166 return 0;
167 }
168 }
169
170 static
171 int reg_strcmp(struct reg reg[NR_REG], const char *cmp_type)
172 {
173 const char *p = reg[REG_R0].str, *q = reg[REG_R1].str;
174 int ret;
175 int diff;
176
177 for (;;) {
178 int escaped_r0 = 0;
179
180 if (unlikely(p - reg[REG_R0].str > reg[REG_R0].seq_len || *p == '\0')) {
181 if (q - reg[REG_R1].str > reg[REG_R1].seq_len || *q == '\0')
182 diff = 0;
183 else
184 diff = -1;
185 break;
186 }
187 if (unlikely(q - reg[REG_R1].str > reg[REG_R1].seq_len || *q == '\0')) {
188 if (p - reg[REG_R0].str > reg[REG_R0].seq_len || *p == '\0')
189 diff = 0;
190 else
191 diff = 1;
192 break;
193 }
194 if (reg[REG_R0].literal) {
195 ret = parse_char(&p);
196 if (ret == -1) {
197 return 0;
198 } else if (ret == -2) {
199 escaped_r0 = 1;
200 }
201 /* else compare both char */
202 }
203 if (reg[REG_R1].literal) {
204 ret = parse_char(&q);
205 if (ret == -1) {
206 return 0;
207 } else if (ret == -2) {
208 if (!escaped_r0)
209 return -1;
210 } else {
211 if (escaped_r0)
212 return 1;
213 }
214 } else {
215 if (escaped_r0)
216 return 1;
217 }
218 diff = *p - *q;
219 if (diff != 0)
220 break;
221 p++;
222 q++;
223 }
224 return diff;
225 }
226
227 static
228 int lttng_filter_false(void *filter_data,
229 const char *filter_stack_data)
230 {
231 return 0;
232 }
233
234 static
235 int lttng_filter_interpret_bytecode(void *filter_data,
236 const char *filter_stack_data)
237 {
238 struct bytecode_runtime *bytecode = filter_data;
239 void *pc, *next_pc, *start_pc;
240 int ret = -EINVAL;
241 int retval = 0;
242 struct reg reg[NR_REG];
243
244 start_pc = &bytecode->data[0];
245 for (pc = next_pc = start_pc; pc - start_pc < bytecode->len;
246 pc = next_pc) {
247 dbg_printf("Executing op %s (%u)\n",
248 print_op((unsigned int) *(filter_opcode_t *) pc),
249 (unsigned int) *(filter_opcode_t *) pc);
250 switch (*(filter_opcode_t *) pc) {
251 case FILTER_OP_UNKNOWN:
252 case FILTER_OP_LOAD_FIELD_REF:
253 default:
254 ERR("unknown bytecode op %u\n",
255 (unsigned int) *(filter_opcode_t *) pc);
256 ret = -EINVAL;
257 goto end;
258
259 case FILTER_OP_RETURN:
260 retval = !!reg[0].v;
261 ret = 0;
262 goto end;
263
264 /* binary */
265 case FILTER_OP_MUL:
266 case FILTER_OP_DIV:
267 case FILTER_OP_MOD:
268 case FILTER_OP_PLUS:
269 case FILTER_OP_MINUS:
270 case FILTER_OP_RSHIFT:
271 case FILTER_OP_LSHIFT:
272 case FILTER_OP_BIN_AND:
273 case FILTER_OP_BIN_OR:
274 case FILTER_OP_BIN_XOR:
275 ERR("unsupported bytecode op %u\n",
276 (unsigned int) *(filter_opcode_t *) pc);
277 ret = -EINVAL;
278 goto end;
279
280 case FILTER_OP_EQ:
281 {
282 switch (reg[REG_R0].type) {
283 default:
284 ERR("unknown register type\n");
285 ret = -EINVAL;
286 goto end;
287
288 case REG_STRING:
289 reg[REG_R0].v = (reg_strcmp(reg, "==") == 0);
290 break;
291 case REG_S64:
292 switch (reg[REG_R1].type) {
293 default:
294 ERR("unknown register type\n");
295 ret = -EINVAL;
296 goto end;
297
298 case REG_S64:
299 reg[REG_R0].v = (reg[REG_R0].v == reg[REG_R1].v);
300 break;
301 case REG_DOUBLE:
302 reg[REG_R0].v = (reg[REG_R0].v == reg[REG_R1].d);
303 break;
304 }
305 break;
306 case REG_DOUBLE:
307 switch (reg[REG_R1].type) {
308 default:
309 ERR("unknown register type\n");
310 ret = -EINVAL;
311 goto end;
312
313 case REG_S64:
314 reg[REG_R0].v = (reg[REG_R0].d == reg[REG_R1].v);
315 break;
316 case REG_DOUBLE:
317 reg[REG_R0].v = (reg[REG_R0].d == reg[REG_R1].d);
318 break;
319 }
320 break;
321 }
322 reg[REG_R0].type = REG_S64;
323 next_pc += sizeof(struct binary_op);
324 break;
325 }
326 case FILTER_OP_NE:
327 {
328 switch (reg[REG_R0].type) {
329 default:
330 ERR("unknown register type\n");
331 ret = -EINVAL;
332 goto end;
333
334 case REG_STRING:
335 reg[REG_R0].v = (reg_strcmp(reg, "!=") != 0);
336 break;
337 case REG_S64:
338 switch (reg[REG_R1].type) {
339 default:
340 ERR("unknown register type\n");
341 ret = -EINVAL;
342 goto end;
343
344 case REG_S64:
345 reg[REG_R0].v = (reg[REG_R0].v != reg[REG_R1].v);
346 break;
347 case REG_DOUBLE:
348 reg[REG_R0].v = (reg[REG_R0].v != reg[REG_R1].d);
349 break;
350 }
351 break;
352 case REG_DOUBLE:
353 switch (reg[REG_R1].type) {
354 default:
355 ERR("unknown register type\n");
356 ret = -EINVAL;
357 goto end;
358
359 case REG_S64:
360 reg[REG_R0].v = (reg[REG_R0].d != reg[REG_R1].v);
361 break;
362 case REG_DOUBLE:
363 reg[REG_R0].v = (reg[REG_R0].d != reg[REG_R1].d);
364 break;
365 }
366 break;
367 }
368 reg[REG_R0].type = REG_S64;
369 next_pc += sizeof(struct binary_op);
370 break;
371 }
372 case FILTER_OP_GT:
373 {
374 switch (reg[REG_R0].type) {
375 default:
376 ERR("unknown register type\n");
377 ret = -EINVAL;
378 goto end;
379
380 case REG_STRING:
381 reg[REG_R0].v = (reg_strcmp(reg, ">") > 0);
382 break;
383 case REG_S64:
384 switch (reg[REG_R1].type) {
385 default:
386 ERR("unknown register type\n");
387 ret = -EINVAL;
388 goto end;
389
390 case REG_S64:
391 reg[REG_R0].v = (reg[REG_R0].v > reg[REG_R1].v);
392 break;
393 case REG_DOUBLE:
394 reg[REG_R0].v = (reg[REG_R0].v > reg[REG_R1].d);
395 break;
396 }
397 break;
398 case REG_DOUBLE:
399 switch (reg[REG_R1].type) {
400 default:
401 ERR("unknown register type\n");
402 ret = -EINVAL;
403 goto end;
404
405 case REG_S64:
406 reg[REG_R0].v = (reg[REG_R0].d > reg[REG_R1].v);
407 break;
408 case REG_DOUBLE:
409 reg[REG_R0].v = (reg[REG_R0].d > reg[REG_R1].d);
410 break;
411 }
412 break;
413 }
414 reg[REG_R0].type = REG_S64;
415 next_pc += sizeof(struct binary_op);
416 break;
417 }
418 case FILTER_OP_LT:
419 {
420 switch (reg[REG_R0].type) {
421 default:
422 ERR("unknown register type\n");
423 ret = -EINVAL;
424 goto end;
425
426 case REG_STRING:
427 reg[REG_R0].v = (reg_strcmp(reg, "<") < 0);
428 break;
429 case REG_S64:
430 switch (reg[REG_R1].type) {
431 default:
432 ERR("unknown register type\n");
433 ret = -EINVAL;
434 goto end;
435
436 case REG_S64:
437 reg[REG_R0].v = (reg[REG_R0].v < reg[REG_R1].v);
438 break;
439 case REG_DOUBLE:
440 reg[REG_R0].v = (reg[REG_R0].v < reg[REG_R1].d);
441 break;
442 }
443 break;
444 case REG_DOUBLE:
445 switch (reg[REG_R1].type) {
446 default:
447 ERR("unknown register type\n");
448 ret = -EINVAL;
449 goto end;
450
451 case REG_S64:
452 reg[REG_R0].v = (reg[REG_R0].d < reg[REG_R1].v);
453 break;
454 case REG_DOUBLE:
455 reg[REG_R0].v = (reg[REG_R0].d < reg[REG_R1].d);
456 break;
457 }
458 break;
459 }
460 reg[REG_R0].type = REG_S64;
461 next_pc += sizeof(struct binary_op);
462 break;
463 }
464 case FILTER_OP_GE:
465 {
466 switch (reg[REG_R0].type) {
467 default:
468 ERR("unknown register type\n");
469 ret = -EINVAL;
470 goto end;
471
472 case REG_STRING:
473 reg[REG_R0].v = (reg_strcmp(reg, ">=") >= 0);
474 break;
475 case REG_S64:
476 switch (reg[REG_R1].type) {
477 default:
478 ERR("unknown register type\n");
479 ret = -EINVAL;
480 goto end;
481
482 case REG_S64:
483 reg[REG_R0].v = (reg[REG_R0].v >= reg[REG_R1].v);
484 break;
485 case REG_DOUBLE:
486 reg[REG_R0].v = (reg[REG_R0].v >= reg[REG_R1].d);
487 break;
488 }
489 break;
490 case REG_DOUBLE:
491 switch (reg[REG_R1].type) {
492 default:
493 ERR("unknown register type\n");
494 ret = -EINVAL;
495 goto end;
496
497 case REG_S64:
498 reg[REG_R0].v = (reg[REG_R0].d >= reg[REG_R1].v);
499 break;
500 case REG_DOUBLE:
501 reg[REG_R0].v = (reg[REG_R0].d >= reg[REG_R1].d);
502 break;
503 }
504 break;
505 }
506 reg[REG_R0].type = REG_S64;
507 next_pc += sizeof(struct binary_op);
508 break;
509 }
510 case FILTER_OP_LE:
511 {
512 switch (reg[REG_R0].type) {
513 default:
514 ERR("unknown register type\n");
515 ret = -EINVAL;
516 goto end;
517
518 case REG_STRING:
519 reg[REG_R0].v = (reg_strcmp(reg, "<=") <= 0);
520 break;
521 case REG_S64:
522 switch (reg[REG_R1].type) {
523 default:
524 ERR("unknown register type\n");
525 ret = -EINVAL;
526 goto end;
527
528 case REG_S64:
529 reg[REG_R0].v = (reg[REG_R0].v <= reg[REG_R1].v);
530 break;
531 case REG_DOUBLE:
532 reg[REG_R0].v = (reg[REG_R0].v <= reg[REG_R1].d);
533 break;
534 }
535 break;
536 case REG_DOUBLE:
537 switch (reg[REG_R1].type) {
538 default:
539 ERR("unknown register type\n");
540 ret = -EINVAL;
541 goto end;
542
543 case REG_S64:
544 reg[REG_R0].v = (reg[REG_R0].d <= reg[REG_R1].v);
545 break;
546 case REG_DOUBLE:
547 reg[REG_R0].v = (reg[REG_R0].d <= reg[REG_R1].d);
548 break;
549 }
550 break;
551 }
552 reg[REG_R0].type = REG_S64;
553 next_pc += sizeof(struct binary_op);
554 break;
555 }
556
557 /* unary */
558 case FILTER_OP_UNARY_PLUS:
559 {
560 next_pc += sizeof(struct unary_op);
561 break;
562 }
563 case FILTER_OP_UNARY_MINUS:
564 {
565 struct unary_op *insn = (struct unary_op *) pc;
566
567 switch (reg[insn->reg].type) {
568 default:
569 ERR("unknown register type\n");
570 ret = -EINVAL;
571 goto end;
572
573 case REG_STRING:
574 ERR("Unary minus can only be applied to numeric or floating point registers\n");
575 ret = -EINVAL;
576 goto end;
577 case REG_S64:
578 reg[insn->reg].v = -reg[insn->reg].v;
579 break;
580 case REG_DOUBLE:
581 reg[insn->reg].d = -reg[insn->reg].d;
582 break;
583 }
584 next_pc += sizeof(struct unary_op);
585 break;
586 }
587 case FILTER_OP_UNARY_NOT:
588 {
589 struct unary_op *insn = (struct unary_op *) pc;
590
591 switch (reg[insn->reg].type) {
592 default:
593 ERR("unknown register type\n");
594 ret = -EINVAL;
595 goto end;
596
597 case REG_STRING:
598 ERR("Unary not can only be applied to numeric or floating point registers\n");
599 ret = -EINVAL;
600 goto end;
601 case REG_S64:
602 reg[insn->reg].v = !reg[insn->reg].v;
603 break;
604 case REG_DOUBLE:
605 reg[insn->reg].d = !reg[insn->reg].d;
606 break;
607 }
608 reg[insn->reg].v = !reg[insn->reg].v;
609 next_pc += sizeof(struct unary_op);
610 break;
611 }
612 /* logical */
613 case FILTER_OP_AND:
614 {
615 struct logical_op *insn = (struct logical_op *) pc;
616
617 /* If REG_R0 is 0, skip and evaluate to 0 */
618 if ((reg[REG_R0].type == REG_S64 && reg[REG_R0].v == 0)
619 || (reg[REG_R0].type == REG_DOUBLE && reg[REG_R0].d == 0.0)) {
620 dbg_printf("Jumping to bytecode offset %u\n",
621 (unsigned int) insn->skip_offset);
622 next_pc = start_pc + insn->skip_offset;
623 } else {
624 next_pc += sizeof(struct logical_op);
625 }
626 break;
627 }
628 case FILTER_OP_OR:
629 {
630 struct logical_op *insn = (struct logical_op *) pc;
631
632 /* If REG_R0 is nonzero, skip and evaluate to 1 */
633
634 if ((reg[REG_R0].type == REG_S64 && reg[REG_R0].v != 0)
635 || (reg[REG_R0].type == REG_DOUBLE && reg[REG_R0].d != 0.0)) {
636 reg[REG_R0].v = 1;
637 dbg_printf("Jumping to bytecode offset %u\n",
638 (unsigned int) insn->skip_offset);
639 next_pc = start_pc + insn->skip_offset;
640 } else {
641 next_pc += sizeof(struct logical_op);
642 }
643 break;
644 }
645
646 /* load */
647 case FILTER_OP_LOAD_FIELD_REF_STRING:
648 {
649 struct load_op *insn = (struct load_op *) pc;
650 struct field_ref *ref = (struct field_ref *) insn->data;
651
652 dbg_printf("load field ref offset %u type string\n",
653 ref->offset);
654 reg[insn->reg].str =
655 *(const char * const *) &filter_stack_data[ref->offset];
656 reg[insn->reg].type = REG_STRING;
657 reg[insn->reg].seq_len = UINT_MAX;
658 reg[insn->reg].literal = 0;
659 dbg_printf("ref load string %s\n", reg[insn->reg].str);
660 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
661 break;
662 }
663
664 case FILTER_OP_LOAD_FIELD_REF_SEQUENCE:
665 {
666 struct load_op *insn = (struct load_op *) pc;
667 struct field_ref *ref = (struct field_ref *) insn->data;
668
669 dbg_printf("load field ref offset %u type sequence\n",
670 ref->offset);
671 reg[insn->reg].seq_len =
672 *(unsigned long *) &filter_stack_data[ref->offset];
673 reg[insn->reg].str =
674 *(const char **) (&filter_stack_data[ref->offset
675 + sizeof(unsigned long)]);
676 reg[insn->reg].type = REG_STRING;
677 reg[insn->reg].literal = 0;
678 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
679 break;
680 }
681
682 case FILTER_OP_LOAD_FIELD_REF_S64:
683 {
684 struct load_op *insn = (struct load_op *) pc;
685 struct field_ref *ref = (struct field_ref *) insn->data;
686
687 dbg_printf("load field ref offset %u type s64\n",
688 ref->offset);
689 memcpy(&reg[insn->reg].v, &filter_stack_data[ref->offset],
690 sizeof(struct literal_numeric));
691 reg[insn->reg].type = REG_S64;
692 reg[insn->reg].literal = 0;
693 dbg_printf("ref load s64 %" PRIi64 "\n", reg[insn->reg].v);
694 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
695 break;
696 }
697
698 case FILTER_OP_LOAD_FIELD_REF_DOUBLE:
699 {
700 struct load_op *insn = (struct load_op *) pc;
701 struct field_ref *ref = (struct field_ref *) insn->data;
702
703 dbg_printf("load field ref offset %u type double\n",
704 ref->offset);
705 memcpy(&reg[insn->reg].d, &filter_stack_data[ref->offset],
706 sizeof(struct literal_double));
707 reg[insn->reg].type = REG_DOUBLE;
708 reg[insn->reg].literal = 0;
709 dbg_printf("ref load double %g\n", reg[insn->reg].d);
710 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
711 break;
712 }
713
714 case FILTER_OP_LOAD_STRING:
715 {
716 struct load_op *insn = (struct load_op *) pc;
717
718 dbg_printf("load string %s\n", insn->data);
719 reg[insn->reg].str = insn->data;
720 reg[insn->reg].type = REG_STRING;
721 reg[insn->reg].seq_len = UINT_MAX;
722 reg[insn->reg].literal = 1;
723 next_pc += sizeof(struct load_op) + strlen(insn->data) + 1;
724 break;
725 }
726
727 case FILTER_OP_LOAD_S64:
728 {
729 struct load_op *insn = (struct load_op *) pc;
730
731 memcpy(&reg[insn->reg].v, insn->data,
732 sizeof(struct literal_numeric));
733 dbg_printf("load s64 %" PRIi64 "\n", reg[insn->reg].v);
734 reg[insn->reg].type = REG_S64;
735 next_pc += sizeof(struct load_op)
736 + sizeof(struct literal_numeric);
737 break;
738 }
739
740 case FILTER_OP_LOAD_DOUBLE:
741 {
742 struct load_op *insn = (struct load_op *) pc;
743
744 memcpy(&reg[insn->reg].d, insn->data,
745 sizeof(struct literal_double));
746 dbg_printf("load s64 %g\n", reg[insn->reg].d);
747 reg[insn->reg].type = REG_DOUBLE;
748 next_pc += sizeof(struct load_op)
749 + sizeof(struct literal_double);
750 break;
751 }
752 }
753 }
754 end:
755 /* return 0 (discard) on error */
756 if (ret)
757 return 0;
758 return retval;
759 }
760
761 static
762 int bin_op_compare_check(struct vreg reg[NR_REG], const char *str)
763 {
764 switch (reg[REG_R0].type) {
765 default:
766 goto error_unknown;
767
768 case REG_STRING:
769 switch (reg[REG_R1].type) {
770 default:
771 goto error_unknown;
772
773 case REG_STRING:
774 break;
775 case REG_S64:
776 case REG_DOUBLE:
777 goto error_mismatch;
778 }
779 break;
780 case REG_S64:
781 case REG_DOUBLE:
782 switch (reg[REG_R1].type) {
783 default:
784 goto error_unknown;
785
786 case REG_STRING:
787 goto error_mismatch;
788
789 case REG_S64:
790 case REG_DOUBLE:
791 break;
792 }
793 break;
794 }
795 return 0;
796
797 error_unknown:
798
799 return -EINVAL;
800 error_mismatch:
801 ERR("type mismatch for '%s' binary operator\n", str);
802 return -EINVAL;
803 }
804
805 static
806 int lttng_filter_validate_bytecode(struct bytecode_runtime *bytecode)
807 {
808 void *pc, *next_pc, *start_pc;
809 int ret = -EINVAL;
810 struct vreg reg[NR_REG];
811 int i;
812
813 for (i = 0; i < NR_REG; i++) {
814 reg[i].type = REG_TYPE_UNKNOWN;
815 reg[i].literal = 0;
816 }
817
818 start_pc = &bytecode->data[0];
819 for (pc = next_pc = start_pc; pc - start_pc < bytecode->len;
820 pc = next_pc) {
821 if (unlikely(pc >= start_pc + bytecode->len)) {
822 ERR("filter bytecode overflow\n");
823 ret = -EINVAL;
824 goto end;
825 }
826 dbg_printf("Validating op %s (%u)\n",
827 print_op((unsigned int) *(filter_opcode_t *) pc),
828 (unsigned int) *(filter_opcode_t *) pc);
829 switch (*(filter_opcode_t *) pc) {
830 case FILTER_OP_UNKNOWN:
831 default:
832 ERR("unknown bytecode op %u\n",
833 (unsigned int) *(filter_opcode_t *) pc);
834 ret = -EINVAL;
835 goto end;
836
837 case FILTER_OP_RETURN:
838 ret = 0;
839 goto end;
840
841 /* binary */
842 case FILTER_OP_MUL:
843 case FILTER_OP_DIV:
844 case FILTER_OP_MOD:
845 case FILTER_OP_PLUS:
846 case FILTER_OP_MINUS:
847 case FILTER_OP_RSHIFT:
848 case FILTER_OP_LSHIFT:
849 case FILTER_OP_BIN_AND:
850 case FILTER_OP_BIN_OR:
851 case FILTER_OP_BIN_XOR:
852 ERR("unsupported bytecode op %u\n",
853 (unsigned int) *(filter_opcode_t *) pc);
854 ret = -EINVAL;
855 goto end;
856
857 case FILTER_OP_EQ:
858 {
859 ret = bin_op_compare_check(reg, "==");
860 if (ret)
861 goto end;
862 reg[REG_R0].type = REG_S64;
863 next_pc += sizeof(struct binary_op);
864 break;
865 }
866 case FILTER_OP_NE:
867 {
868 ret = bin_op_compare_check(reg, "!=");
869 if (ret)
870 goto end;
871 reg[REG_R0].type = REG_S64;
872 next_pc += sizeof(struct binary_op);
873 break;
874 }
875 case FILTER_OP_GT:
876 {
877 ret = bin_op_compare_check(reg, ">");
878 if (ret)
879 goto end;
880 reg[REG_R0].type = REG_S64;
881 next_pc += sizeof(struct binary_op);
882 break;
883 }
884 case FILTER_OP_LT:
885 {
886 ret = bin_op_compare_check(reg, "<");
887 if (ret)
888 goto end;
889 reg[REG_R0].type = REG_S64;
890 next_pc += sizeof(struct binary_op);
891 break;
892 }
893 case FILTER_OP_GE:
894 {
895 ret = bin_op_compare_check(reg, ">=");
896 if (ret)
897 goto end;
898 reg[REG_R0].type = REG_S64;
899 next_pc += sizeof(struct binary_op);
900 break;
901 }
902 case FILTER_OP_LE:
903 {
904 ret = bin_op_compare_check(reg, "<=");
905 if (ret)
906 goto end;
907 reg[REG_R0].type = REG_S64;
908 next_pc += sizeof(struct binary_op);
909 break;
910 }
911
912 /* unary */
913 case FILTER_OP_UNARY_PLUS:
914 case FILTER_OP_UNARY_MINUS:
915 case FILTER_OP_UNARY_NOT:
916 {
917 struct unary_op *insn = (struct unary_op *) pc;
918
919 if (unlikely(insn->reg >= REG_ERROR)) {
920 ERR("invalid register %u\n",
921 (unsigned int) insn->reg);
922 ret = -EINVAL;
923 goto end;
924 }
925 switch (reg[insn->reg].type) {
926 default:
927 ERR("unknown register type\n");
928 ret = -EINVAL;
929 goto end;
930
931 case REG_STRING:
932 ERR("Unary op can only be applied to numeric or floating point registers\n");
933 ret = -EINVAL;
934 goto end;
935 case REG_S64:
936 break;
937 case REG_DOUBLE:
938 break;
939 }
940 next_pc += sizeof(struct unary_op);
941 break;
942 }
943 /* logical */
944 case FILTER_OP_AND:
945 case FILTER_OP_OR:
946 {
947 struct logical_op *insn = (struct logical_op *) pc;
948
949 if (unlikely(reg[REG_R0].type == REG_TYPE_UNKNOWN
950 || reg[REG_R0].type == REG_TYPE_UNKNOWN
951 || reg[REG_R0].type == REG_STRING
952 || reg[REG_R1].type == REG_STRING)) {
953 ERR("Logical comparator can only be applied to numeric and floating point registers\n");
954 ret = -EINVAL;
955 goto end;
956 }
957
958 dbg_printf("Validate jumping to bytecode offset %u\n",
959 (unsigned int) insn->skip_offset);
960 if (unlikely(start_pc + insn->skip_offset <= pc)) {
961 ERR("Loops are not allowed in bytecode\n");
962 ret = -EINVAL;
963 goto end;
964 }
965 next_pc += sizeof(struct logical_op);
966 break;
967 }
968
969 /* load */
970 case FILTER_OP_LOAD_FIELD_REF:
971 {
972 ERR("Unknown field ref type\n");
973 ret = -EINVAL;
974 goto end;
975 }
976 case FILTER_OP_LOAD_FIELD_REF_STRING:
977 case FILTER_OP_LOAD_FIELD_REF_SEQUENCE:
978 {
979 struct load_op *insn = (struct load_op *) pc;
980 struct field_ref *ref = (struct field_ref *) insn->data;
981
982 if (unlikely(insn->reg >= REG_ERROR)) {
983 ERR("invalid register %u\n",
984 (unsigned int) insn->reg);
985 ret = -EINVAL;
986 goto end;
987 }
988 dbg_printf("Validate load field ref offset %u type string\n",
989 ref->offset);
990 reg[insn->reg].type = REG_STRING;
991 reg[insn->reg].literal = 0;
992 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
993 break;
994 }
995 case FILTER_OP_LOAD_FIELD_REF_S64:
996 {
997 struct load_op *insn = (struct load_op *) pc;
998 struct field_ref *ref = (struct field_ref *) insn->data;
999
1000 if (unlikely(insn->reg >= REG_ERROR)) {
1001 ERR("invalid register %u\n",
1002 (unsigned int) insn->reg);
1003 ret = -EINVAL;
1004 goto end;
1005 }
1006 dbg_printf("Validate load field ref offset %u type s64\n",
1007 ref->offset);
1008 reg[insn->reg].type = REG_S64;
1009 reg[insn->reg].literal = 0;
1010 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1011 break;
1012 }
1013 case FILTER_OP_LOAD_FIELD_REF_DOUBLE:
1014 {
1015 struct load_op *insn = (struct load_op *) pc;
1016 struct field_ref *ref = (struct field_ref *) insn->data;
1017
1018 if (unlikely(insn->reg >= REG_ERROR)) {
1019 ERR("invalid register %u\n",
1020 (unsigned int) insn->reg);
1021 ret = -EINVAL;
1022 goto end;
1023 }
1024 dbg_printf("Validate load field ref offset %u type double\n",
1025 ref->offset);
1026 reg[insn->reg].type = REG_DOUBLE;
1027 reg[insn->reg].literal = 0;
1028 next_pc += sizeof(struct load_op) + sizeof(struct field_ref);
1029 break;
1030 }
1031
1032 case FILTER_OP_LOAD_STRING:
1033 {
1034 struct load_op *insn = (struct load_op *) pc;
1035
1036 if (unlikely(insn->reg >= REG_ERROR)) {
1037 ERR("invalid register %u\n",
1038 (unsigned int) insn->reg);
1039 ret = -EINVAL;
1040 goto end;
1041 }
1042 reg[insn->reg].type = REG_STRING;
1043 reg[insn->reg].literal = 1;
1044 next_pc += sizeof(struct load_op) + strlen(insn->data) + 1;
1045 break;
1046 }
1047
1048 case FILTER_OP_LOAD_S64:
1049 {
1050 struct load_op *insn = (struct load_op *) pc;
1051
1052 if (unlikely(insn->reg >= REG_ERROR)) {
1053 ERR("invalid register %u\n",
1054 (unsigned int) insn->reg);
1055 ret = -EINVAL;
1056 goto end;
1057 }
1058 reg[insn->reg].type = REG_S64;
1059 next_pc += sizeof(struct load_op)
1060 + sizeof(struct literal_numeric);
1061 break;
1062 }
1063
1064 case FILTER_OP_LOAD_DOUBLE:
1065 {
1066 struct load_op *insn = (struct load_op *) pc;
1067
1068 if (unlikely(insn->reg >= REG_ERROR)) {
1069 ERR("invalid register %u\n",
1070 (unsigned int) insn->reg);
1071 ret = -EINVAL;
1072 goto end;
1073 }
1074 reg[insn->reg].type = REG_DOUBLE;
1075 next_pc += sizeof(struct load_op)
1076 + sizeof(struct literal_double);
1077 break;
1078 }
1079 }
1080 }
1081 end:
1082 return ret;
1083 }
1084
1085 static
1086 int apply_field_reloc(struct ltt_event *event,
1087 struct bytecode_runtime *runtime,
1088 uint32_t runtime_len,
1089 uint32_t reloc_offset,
1090 const char *field_name)
1091 {
1092 const struct lttng_event_desc *desc;
1093 const struct lttng_event_field *fields, *field = NULL;
1094 unsigned int nr_fields, i;
1095 struct field_ref *field_ref;
1096 struct load_op *op;
1097 uint32_t field_offset = 0;
1098
1099 dbg_printf("Apply reloc: %u %s\n", reloc_offset, field_name);
1100
1101 /* Ensure that the reloc is within the code */
1102 if (runtime_len - reloc_offset < sizeof(uint16_t))
1103 return -EINVAL;
1104
1105 /* Lookup event by name */
1106 desc = event->desc;
1107 if (!desc)
1108 return -EINVAL;
1109 fields = desc->fields;
1110 if (!fields)
1111 return -EINVAL;
1112 nr_fields = desc->nr_fields;
1113 for (i = 0; i < nr_fields; i++) {
1114 if (!strcmp(fields[i].name, field_name)) {
1115 field = &fields[i];
1116 break;
1117 }
1118 /* compute field offset */
1119 switch (fields[i].type.atype) {
1120 case atype_integer:
1121 case atype_enum:
1122 field_offset += sizeof(int64_t);
1123 break;
1124 case atype_array:
1125 case atype_sequence:
1126 field_offset += sizeof(unsigned long);
1127 field_offset += sizeof(void *);
1128 break;
1129 case atype_string:
1130 field_offset += sizeof(void *);
1131 break;
1132 case atype_float:
1133 field_offset += sizeof(double);
1134 break;
1135 default:
1136 return -EINVAL;
1137 }
1138 }
1139 if (!field)
1140 return -EINVAL;
1141
1142 /* Check if field offset is too large for 16-bit offset */
1143 if (field_offset > FILTER_BYTECODE_MAX_LEN)
1144 return -EINVAL;
1145
1146 /* set type */
1147 op = (struct load_op *) &runtime->data[reloc_offset];
1148 field_ref = (struct field_ref *) op->data;
1149 switch (field->type.atype) {
1150 case atype_integer:
1151 case atype_enum:
1152 op->op = FILTER_OP_LOAD_FIELD_REF_S64;
1153 break;
1154 case atype_array:
1155 case atype_sequence:
1156 op->op = FILTER_OP_LOAD_FIELD_REF_SEQUENCE;
1157 break;
1158 case atype_string:
1159 op->op = FILTER_OP_LOAD_FIELD_REF_STRING;
1160 break;
1161 case atype_float:
1162 op->op = FILTER_OP_LOAD_FIELD_REF_DOUBLE;
1163 break;
1164 default:
1165 return -EINVAL;
1166 }
1167 /* set offset */
1168 field_ref->offset = (uint16_t) field_offset;
1169 return 0;
1170 }
1171
1172 /*
1173 * Take a bytecode with reloc table and link it to an event to create a
1174 * bytecode runtime.
1175 */
1176 static
1177 int _lttng_filter_event_link_bytecode(struct ltt_event *event,
1178 struct lttng_ust_filter_bytecode *filter_bytecode)
1179 {
1180 int ret, offset, next_offset;
1181 struct bytecode_runtime *runtime = NULL;
1182 size_t runtime_alloc_len;
1183
1184 if (!filter_bytecode)
1185 return 0;
1186 /* Even is not connected to any description */
1187 if (!event->desc)
1188 return 0;
1189 /* Bytecode already linked */
1190 if (event->filter || event->filter_data)
1191 return 0;
1192
1193 dbg_printf("Linking\n");
1194
1195 /* We don't need the reloc table in the runtime */
1196 runtime_alloc_len = sizeof(*runtime) + filter_bytecode->reloc_offset;
1197 runtime = zmalloc(runtime_alloc_len);
1198 if (!runtime) {
1199 ret = -ENOMEM;
1200 goto link_error;
1201 }
1202 runtime->len = filter_bytecode->reloc_offset;
1203 /* copy original bytecode */
1204 memcpy(runtime->data, filter_bytecode->data, runtime->len);
1205 /*
1206 * apply relocs. Those are a uint16_t (offset in bytecode)
1207 * followed by a string (field name).
1208 */
1209 for (offset = filter_bytecode->reloc_offset;
1210 offset < filter_bytecode->len;
1211 offset = next_offset) {
1212 uint16_t reloc_offset =
1213 *(uint16_t *) &filter_bytecode->data[offset];
1214 const char *field_name =
1215 (const char *) &filter_bytecode->data[offset + sizeof(uint16_t)];
1216
1217 ret = apply_field_reloc(event, runtime, runtime->len, reloc_offset, field_name);
1218 if (ret) {
1219 goto link_error;
1220 }
1221 next_offset = offset + sizeof(uint16_t) + strlen(field_name) + 1;
1222 }
1223 /* Validate bytecode */
1224 ret = lttng_filter_validate_bytecode(runtime);
1225 if (ret) {
1226 goto link_error;
1227 }
1228 event->filter_data = runtime;
1229 event->filter = lttng_filter_interpret_bytecode;
1230 return 0;
1231
1232 link_error:
1233 event->filter = lttng_filter_false;
1234 free(runtime);
1235 return ret;
1236 }
1237
1238 void lttng_filter_event_link_bytecode(struct ltt_event *event,
1239 struct lttng_ust_filter_bytecode *filter_bytecode)
1240 {
1241 int ret;
1242
1243 ret = _lttng_filter_event_link_bytecode(event, filter_bytecode);
1244 if (ret) {
1245 fprintf(stderr, "[lttng filter] error linking event bytecode\n");
1246 }
1247 }
1248
1249 /*
1250 * Link bytecode to all events for a wildcard. Skips events that already
1251 * have a bytecode linked.
1252 * We do not set each event's filter_bytecode field, because they do not
1253 * own the filter_bytecode: the wildcard owns it.
1254 */
1255 void lttng_filter_wildcard_link_bytecode(struct session_wildcard *wildcard)
1256 {
1257 struct ltt_event *event;
1258 int ret;
1259
1260 if (!wildcard->filter_bytecode)
1261 return;
1262
1263 cds_list_for_each_entry(event, &wildcard->events, wildcard_list) {
1264 if (event->filter)
1265 continue;
1266 ret = _lttng_filter_event_link_bytecode(event,
1267 wildcard->filter_bytecode);
1268 if (ret) {
1269 fprintf(stderr, "[lttng filter] error linking wildcard bytecode\n");
1270 }
1271
1272 }
1273 return;
1274 }
1275
1276 /*
1277 * Need to attach filter to an event before starting tracing for the
1278 * session. We own the filter_bytecode if we return success.
1279 */
1280 int lttng_filter_event_attach_bytecode(struct ltt_event *event,
1281 struct lttng_ust_filter_bytecode *filter_bytecode)
1282 {
1283 if (event->chan->session->been_active)
1284 return -EPERM;
1285 if (event->filter_bytecode)
1286 return -EEXIST;
1287 event->filter_bytecode = filter_bytecode;
1288 return 0;
1289 }
1290
1291 /*
1292 * Need to attach filter to a wildcard before starting tracing for the
1293 * session. We own the filter_bytecode if we return success.
1294 */
1295 int lttng_filter_wildcard_attach_bytecode(struct session_wildcard *wildcard,
1296 struct lttng_ust_filter_bytecode *filter_bytecode)
1297 {
1298 if (wildcard->chan->session->been_active)
1299 return -EPERM;
1300 if (wildcard->filter_bytecode)
1301 return -EEXIST;
1302 wildcard->filter_bytecode = filter_bytecode;
1303 return 0;
1304 }
This page took 0.055004 seconds and 5 git commands to generate.