X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=liblttng-ust%2Flttng-filter-validator.c;h=456407ffde228fa625e3973b3d5e02c71b0bd4d7;hb=814f7df1401ce02529847840edd84836c1ce646a;hp=a41deb5e7ac54bdd1df2b8a842f368d3a556fd76;hpb=71c1ceeb09675681606ac8c81cbc6fcb363da9e3;p=lttng-ust.git diff --git a/liblttng-ust/lttng-filter-validator.c b/liblttng-ust/lttng-filter-validator.c index a41deb5e..456407ff 100644 --- a/liblttng-ust/lttng-filter-validator.c +++ b/liblttng-ust/lttng-filter-validator.c @@ -190,7 +190,7 @@ int bytecode_validate_overflow(struct bytecode_runtime *bytecode, { if (unlikely(pc + sizeof(struct return_op) > start_pc + bytecode->len)) { - ret = -EINVAL; + ret = -ERANGE; } break; } @@ -237,10 +237,22 @@ int bytecode_validate_overflow(struct bytecode_runtime *bytecode, case FILTER_OP_LT_DOUBLE: case FILTER_OP_GE_DOUBLE: case FILTER_OP_LE_DOUBLE: + case FILTER_OP_EQ_DOUBLE_S64: + case FILTER_OP_NE_DOUBLE_S64: + case FILTER_OP_GT_DOUBLE_S64: + case FILTER_OP_LT_DOUBLE_S64: + case FILTER_OP_GE_DOUBLE_S64: + case FILTER_OP_LE_DOUBLE_S64: + case FILTER_OP_EQ_S64_DOUBLE: + case FILTER_OP_NE_S64_DOUBLE: + case FILTER_OP_GT_S64_DOUBLE: + case FILTER_OP_LT_S64_DOUBLE: + case FILTER_OP_GE_S64_DOUBLE: + case FILTER_OP_LE_S64_DOUBLE: { if (unlikely(pc + sizeof(struct binary_op) > start_pc + bytecode->len)) { - ret = -EINVAL; + ret = -ERANGE; } break; } @@ -258,7 +270,7 @@ int bytecode_validate_overflow(struct bytecode_runtime *bytecode, { if (unlikely(pc + sizeof(struct unary_op) > start_pc + bytecode->len)) { - ret = -EINVAL; + ret = -ERANGE; } break; } @@ -269,7 +281,7 @@ int bytecode_validate_overflow(struct bytecode_runtime *bytecode, { if (unlikely(pc + sizeof(struct logical_op) > start_pc + bytecode->len)) { - ret = -EINVAL; + ret = -ERANGE; } break; } @@ -288,7 +300,7 @@ int bytecode_validate_overflow(struct bytecode_runtime *bytecode, { if (unlikely(pc + sizeof(struct load_op) + sizeof(struct field_ref) > start_pc + bytecode->len)) { - ret = -EINVAL; + ret = -ERANGE; } break; } @@ -300,7 +312,7 @@ int bytecode_validate_overflow(struct bytecode_runtime *bytecode, if (unlikely(pc + sizeof(struct load_op) > start_pc + bytecode->len)) { - ret = -EINVAL; + ret = -ERANGE; break; } @@ -308,7 +320,7 @@ int bytecode_validate_overflow(struct bytecode_runtime *bytecode, str_len = strnlen(insn->data, maxlen); if (unlikely(str_len >= maxlen)) { /* Final '\0' not found within range */ - ret = -EINVAL; + ret = -ERANGE; } break; } @@ -317,7 +329,7 @@ int bytecode_validate_overflow(struct bytecode_runtime *bytecode, { if (unlikely(pc + sizeof(struct load_op) + sizeof(struct literal_numeric) > start_pc + bytecode->len)) { - ret = -EINVAL; + ret = -ERANGE; } break; } @@ -326,7 +338,7 @@ int bytecode_validate_overflow(struct bytecode_runtime *bytecode, { if (unlikely(pc + sizeof(struct load_op) + sizeof(struct literal_double) > start_pc + bytecode->len)) { - ret = -EINVAL; + ret = -ERANGE; } break; } @@ -337,7 +349,7 @@ int bytecode_validate_overflow(struct bytecode_runtime *bytecode, { if (unlikely(pc + sizeof(struct cast_op) > start_pc + bytecode->len)) { - ret = -EINVAL; + ret = -ERANGE; } break; } @@ -508,14 +520,48 @@ int validate_instruction_context(struct bytecode_runtime *bytecode, ret = -EINVAL; goto end; } - if ((vstack_ax(stack)->type != REG_DOUBLE && vstack_ax(stack)->type != REG_S64) - || (vstack_bx(stack)-> type != REG_DOUBLE && vstack_bx(stack)->type != REG_S64)) { - ERR("Unexpected register type for double comparator\n"); + if (vstack_ax(stack)->type != REG_DOUBLE && vstack_bx(stack)->type != REG_DOUBLE) { + ERR("Double operator should have two double registers\n"); ret = -EINVAL; goto end; } - if (vstack_ax(stack)->type != REG_DOUBLE && vstack_bx(stack)->type != REG_DOUBLE) { - ERR("Double operator should have at least one double register\n"); + break; + } + + case FILTER_OP_EQ_DOUBLE_S64: + case FILTER_OP_NE_DOUBLE_S64: + case FILTER_OP_GT_DOUBLE_S64: + case FILTER_OP_LT_DOUBLE_S64: + case FILTER_OP_GE_DOUBLE_S64: + case FILTER_OP_LE_DOUBLE_S64: + { + if (!vstack_ax(stack) || !vstack_bx(stack)) { + ERR("Empty stack\n"); + ret = -EINVAL; + goto end; + } + if (vstack_ax(stack)->type != REG_S64 && vstack_bx(stack)->type != REG_DOUBLE) { + ERR("Double-S64 operator has unexpected register types\n"); + ret = -EINVAL; + goto end; + } + break; + } + + case FILTER_OP_EQ_S64_DOUBLE: + case FILTER_OP_NE_S64_DOUBLE: + case FILTER_OP_GT_S64_DOUBLE: + case FILTER_OP_LT_S64_DOUBLE: + case FILTER_OP_GE_S64_DOUBLE: + case FILTER_OP_LE_S64_DOUBLE: + { + if (!vstack_ax(stack) || !vstack_bx(stack)) { + ERR("Empty stack\n"); + ret = -EINVAL; + goto end; + } + if (vstack_ax(stack)->type != REG_DOUBLE && vstack_bx(stack)->type != REG_S64) { + ERR("S64-Double operator has unexpected register types\n"); ret = -EINVAL; goto end; } @@ -834,6 +880,18 @@ int exec_insn(struct bytecode_runtime *bytecode, case FILTER_OP_LT_DOUBLE: case FILTER_OP_GE_DOUBLE: case FILTER_OP_LE_DOUBLE: + case FILTER_OP_EQ_DOUBLE_S64: + case FILTER_OP_NE_DOUBLE_S64: + case FILTER_OP_GT_DOUBLE_S64: + case FILTER_OP_LT_DOUBLE_S64: + case FILTER_OP_GE_DOUBLE_S64: + case FILTER_OP_LE_DOUBLE_S64: + case FILTER_OP_EQ_S64_DOUBLE: + case FILTER_OP_NE_S64_DOUBLE: + case FILTER_OP_GT_S64_DOUBLE: + case FILTER_OP_LT_S64_DOUBLE: + case FILTER_OP_GE_S64_DOUBLE: + case FILTER_OP_LE_S64_DOUBLE: { /* Pop 2, push 1 */ if (vstack_pop(stack)) { @@ -1041,9 +1099,10 @@ int lttng_filter_validate_bytecode(struct bytecode_runtime *bytecode) start_pc = &bytecode->data[0]; for (pc = next_pc = start_pc; pc - start_pc < bytecode->len; pc = next_pc) { - if (bytecode_validate_overflow(bytecode, start_pc, pc) != 0) { - ERR("filter bytecode overflow\n"); - ret = -EINVAL; + ret = bytecode_validate_overflow(bytecode, start_pc, pc); + if (ret != 0) { + if (ret == -ERANGE) + ERR("filter bytecode overflow\n"); goto end; } dbg_printf("Validating op %s (%u)\n",