Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(284)

Unified Diff: src/trusted/validator/x86/ncval_reg_sfi/nc_protect_base.c

Issue 625923004: Delete old x86 validator. (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client
Patch Set: rebase master Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/trusted/validator/x86/ncval_reg_sfi/nc_protect_base.c
diff --git a/src/trusted/validator/x86/ncval_reg_sfi/nc_protect_base.c b/src/trusted/validator/x86/ncval_reg_sfi/nc_protect_base.c
deleted file mode 100644
index e33cd54f1780de2d1bd2351b853c660673e175f6..0000000000000000000000000000000000000000
--- a/src/trusted/validator/x86/ncval_reg_sfi/nc_protect_base.c
+++ /dev/null
@@ -1,512 +0,0 @@
-/*
- * Copyright (c) 2012 The Native Client Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-/* nc_protect_base.h - For 64-bit mode, verifies that no instruction
- * changes the value of the base register, that the invariant between
- * RSP and RBP is maintained, and that segment registers are not set.
- */
-#include <assert.h>
-#include <string.h>
-
-#include "native_client/src/trusted/validator/x86/ncval_reg_sfi/nc_protect_base.h"
-
-#include "native_client/src/include/portability_io.h"
-#include "native_client/src/shared/platform/nacl_log.h"
-#include "native_client/src/trusted/validator/x86/decoder/ncop_exps.h"
-#include "native_client/src/trusted/validator/x86/decoder/nc_inst_state_internal.h"
-#include "native_client/src/trusted/validator/x86/decoder/nc_inst_trans.h"
-#include "native_client/src/trusted/validator/x86/ncval_reg_sfi/ncvalidate_iter.h"
-#include "native_client/src/trusted/validator/x86/ncval_reg_sfi/ncvalidate_iter_internal.h"
-#include "native_client/src/trusted/validator/x86/ncval_reg_sfi/ncvalidate_utils.h"
-#include "native_client/src/trusted/validator/x86/ncval_reg_sfi/nc_jumps.h"
-
-/* To turn on debugging of instruction decoding, change value of
- * DEBUGGING to 1.
- */
-#define DEBUGGING 0
-
-#include "native_client/src/shared/utils/debugging.h"
-
-#include "native_client/src/trusted/validator/x86/decoder/ncopcode_desc_inl.c"
-#include "native_client/src/trusted/validator/x86/decoder/ncop_exps_inl.c"
-#include "native_client/src/trusted/validator/x86/decoder/nc_inst_iter_inl.c"
-
-static void NaClReportIllegalChangeToRsp(NaClValidatorState* state,
- NaClInstState* inst) {
- NaClValidatorInstMessage(LOG_ERROR, state, inst,
- "Illegal assignment to RSP\n");
-}
-
-/* Checks flags in the possible set base registers, and reports any
- * previous instructions that were marked as bad.
- *
- * Parameters:
- * state - The state of the validator.
- */
-static INLINE void NaClMaybeReportPreviousBad(NaClValidatorState* state) {
- NaClInstState* prev_esp_set_inst =
- state->set_base_registers.buffer[
- state->set_base_registers.previous_index].esp_set_inst;
- NaClInstState* prev_ebp_set_inst =
- state->set_base_registers.buffer[
- state->set_base_registers.previous_index].ebp_set_inst;
-
- /* First check if previous register references are not followed
- * by acceptable instructions.
- */
- if (NULL != prev_esp_set_inst) {
- NaClValidatorInstMessage(LOG_ERROR,
- state,
- prev_esp_set_inst,
- "Illegal assignment to ESP\n");
- state->set_base_registers.buffer[
- state->set_base_registers.previous_index].esp_set_inst = NULL;
- }
- if (NULL != prev_ebp_set_inst) {
- NaClValidatorInstMessage(LOG_ERROR,
- state,
- prev_ebp_set_inst,
- "Illegal assignment to EBP\n");
- state->set_base_registers.buffer[
- state->set_base_registers.previous_index].ebp_set_inst = NULL;
- }
-
- /* Now advance the register recording by one instruction. */
- state->set_base_registers.previous_index =
- state->set_base_registers.current_index;
- state->set_base_registers.current_index =
- ((state->set_base_registers.current_index + 1)
- % NACL_REGISTER_LOCALS_BUFFER_SIZE);
-}
-
-void NaClBaseRegisterMemoryInitialize(NaClValidatorState* state) {
- int i;
- for (i = 0; i < NACL_REGISTER_LOCALS_BUFFER_SIZE; ++i) {
- state->set_base_registers.buffer[i].esp_set_inst = NULL;
- state->set_base_registers.buffer[i].ebp_set_inst = NULL;
- }
- state->set_base_registers.previous_index = 0;
- state->set_base_registers.current_index = 1;
-}
-
-/* Returns true iff the instruction of form "lea _, [%reg+%rbase*1]" */
-static Bool NaClIsLeaAddressRegPlusRbase(NaClValidatorState* state,
- NaClInstState* inst_state,
- NaClOpKind reg) {
- const NaClInst* inst = NaClInstStateInst(inst_state);
- Bool result = FALSE;
- DEBUG(NaClLog(LOG_INFO, "-> LeaAddressRegPlusRbase(%s)\n",
- NaClOpKindName(reg)));
- if (InstLea == inst->name &&
- 2 == NaClGetInstNumberOperandsInline(inst)) {
- NaClExpVector* vector = NaClInstStateExpVector(inst_state);
- int op2_index =
- NaClGetExpKidIndex(vector,
- NaClGetNthExpKind(vector, OperandReference, 2),
- 0);
- NaClExp* op2 = &(vector->node[op2_index]);
- /* Only allow memory offset nodes with address size 64. */
- if (ExprMemOffset == op2->kind &&
- NACL_EMPTY_EFLAGS != (op2->flags & NACL_EFLAG(ExprSize64))) {
- int base_reg_index = op2_index + 1;
- NaClOpKind base_reg = NaClGetExpVectorRegister(vector, base_reg_index);
- DEBUG(NaClLog(LOG_INFO, " base_reg = %s\n", NaClOpKindName(base_reg)));
- if (base_reg == reg) {
- int index_reg_index =
- base_reg_index + NaClExpWidth(vector, base_reg_index);
- NaClOpKind index_reg =
- NaClGetExpVectorRegister(vector, index_reg_index);
- DEBUG(NaClLog(LOG_INFO,
- " index_reg = %s\n", NaClOpKindName(index_reg)));
- if (index_reg == state->base_register) {
- int scale_index =
- index_reg_index + NaClExpWidth(vector, index_reg_index);
- DEBUG(NaClLog(LOG_INFO, " scale_index = %d\n", scale_index));
- if (ExprConstant == vector->node[scale_index].kind) {
- if ((uint64_t)1 ==
- NaClGetExprUnsignedValue(&vector->node[scale_index])) {
- int disp_index = scale_index + NaClExpWidth(vector, scale_index);
- DEBUG(NaClLog(LOG_INFO, " disp_index = %d\n", disp_index));
- if (ExprConstant == vector->node[disp_index].kind) {
- if ((uint64_t)0 ==
- NaClGetExprSignedValue(&vector->node[disp_index])) {
- result = TRUE;
- } else {
- DEBUG(NaClLog(LOG_INFO, " disp not zero!\n"));
- }
- }
- } else {
- DEBUG(NaClLog(LOG_INFO, " scale not 1!\n"));
- }
- }
- }
- }
- }
- }
- /* If reached, did not match. */
- DEBUG(NaClLog(LOG_INFO, "<-LeaAddressRegPlusRbase = %d\n", result));
- return result;
-}
-
-Bool NaClAcceptLeaWithMoveLea32To64(struct NaClValidatorState* state,
- NaClOpKind reg) {
- NaClInstState* inst_state = state->cur_inst_state;
- Bool result = NaClOperandOneIsRegisterSet(inst_state, reg) &&
- NaClIsLeaAddressRegPlusRbase(state, inst_state, reg) &&
- NaClAssignsRegisterWithZeroExtends64(state, 1, reg);
- if (result) {
- DEBUG({
- const char* reg_name = NaClOpKindName(reg);
- printf("nc protect base for 'lea %s. [%s, rbase]'\n",
- reg_name, reg_name);
- });
- result = TRUE;
- }
- return result;
-}
-
-/* Check if assignments to stack register RSP is legal.
- *
- * Parameters are:
- * state - The state of the validator.
- * i - The index of the node (in the expression tree) that
- * assigns the RSP register.
- */
-static void NaClCheckRspAssignments(struct NaClValidatorState* state,
- uint32_t i) {
- /*
- * Only allow one of:
- * (1) mov %rsp, %rbp
- *
- * Note: maintains RSP/RBP invariant, since RBP was already
- * meeting the invariant.
- * (2) %esp = zero extend 32-bit value
- * OP %rsp, %rbase
- *
- * where OP in { or , add }.
- * (3) An instruction that updates the stack a (small) bounded amount,
- * and then does a memory access. This includes Push, Pop, Call,
- *
- * Note that entering a function corresponds to the pattern:
- * push %rpb
- * mov %rbp, %rsp
- * (4) Allow stack updates of the form:
- * OP %esp, C
- * add %rsp, %rbase
- * where OP is a operator in { add , sub },
- * and C is a 32-bit constant.
- * Note: Since add/sub are zero-extending operations for operand
- * size 32, this doesn't have to be treated as a special case!
- * (5) Allow "and $rsp, 0xXX" where 0xXX is an immediate 8 bit
- * value that is negative. Used to realign the stack pointer.
- * (6) %esp = zero extend 32-bit value.
- * lea %rsp, [%rsp+%rbase*1]
- *
- * Same as (6), except that we use instructions prior to the
- * pattern to do the add/subtract. Then let the result be
- * (zero-extended) moved into ESP, and use the lea to fill
- * in the top 32 bits of %rsp.
- *
- * Note: We require the scale to be 1, and rbase be in
- * the index position.
- *
- * Note: Cases 2, 4, 5, and 6 are maintaining the invariant that
- * the top half of RSP is the same as RBASE, and the lower half
- * of RBASE is zero. Case (2) does this by seting the bottom 32
- * bits with the first instruction (zeroing out the top 32 bits),
- * and then copies (via or or add) the top 32 bits of RBASE into RSP
- * (since the bottom 32 bits of RBASE are zero).
- * Case (4) maintains this by first clearing the top half
- * of RSP, and then setting the top half to match RBASE. Case (5)
- * maintains the variant because the constant is small
- * (-1 to -128) to that the invariant for $RSP (top half
- * is unchanged). Case 6 uses the addition in the address calculation
- * of lea to fill in the top 32 bits.
- */
- NaClInstState* inst_state = state->cur_inst_state;
- const NaClInst* inst = state->cur_inst;
- NaClMnemonic inst_name = inst->name;
- NaClExpVector* vector = state->cur_inst_vector;
-#ifdef NCVAL_TESTING
- char* buffer;
- size_t buffer_size;
-#endif
-
- switch (inst_name) {
- case InstPush:
- case InstPop:
- /* Legal if index corresponds to the first (stack) argument.
- * Note: Since the vector contains a list of operand exrpessions,
- * the first operand reference is always at index zero, and its
- * first child (where the stack register is defined) is at index 1.
- */
- if (i == 1) return;
- break;
- case InstCall:
- /* Legal if index corresponds to the second (stack) argument.
- * Note: The first operand is an operand reference to the instruction
- * register. It consists of an operand reference at index zero,
- * and its first child (where the instruction registers is defined)
- * is at index 1. The node at index 2 is the operand reference to
- * the stack register, and its first child (where the stack register is
- * defined) is at index 3;
- */
- if (i == 3) return;
- break;
- case InstOr:
- case InstAdd:
- /* case 2/4 (depending on instruction name) */
- if (NaClIsBinarySetUsingRegisters(
- state->decoder_tables,
- inst, inst_name, vector, RegRSP,
- state->base_register) &&
- NaClAssignsRegisterWithZeroExtends32(state, 1, RegESP)) {
-#ifdef NCVAL_TESTING
- /* Report precondition of test. */
- NaClConditionAppend(state->precond, &buffer, &buffer_size);
- SNPRINTF(buffer, buffer_size, "ZeroExtends(esp)");
-#endif
- NaClMarkInstructionJumpIllegal(state, state->cur_inst_state);
- state->set_base_registers.buffer[
- state->set_base_registers.previous_index].esp_set_inst = NULL;
- return;
- }
- break;
- case InstLea:
- if (NaClAcceptLeaWithMoveLea32To64(state, RegRSP)) {
- /* case 6. Found that the assignment to ESP in the previous
- * instruction is legal, so long as the two instructions
- * are atomic.
- */
-#ifdef NCVAL_TESTING
- /* Report precondition of test. */
- NaClConditionAppend(state->precond, &buffer, &buffer_size);
- SNPRINTF(buffer, buffer_size, "ZeroExtends(esp)");
-#endif
- NaClMarkInstructionJumpIllegal(state, state->cur_inst_state);
- state->set_base_registers.buffer[
- state->set_base_registers.previous_index].esp_set_inst = NULL;
- return;
- }
- break;
- case InstAnd:
- /* See if case 5: and $rsp, 0xXX */
- if (NaClInstStateLength(inst_state) == 4 &&
- NaClInstStateByte(inst_state, 0) == 0x48 &&
- NaClInstStateByte(inst_state, 1) == 0x83 &&
- NaClInstStateByte(inst_state, 2) == 0xe4 &&
- /* negative byte test: check if leftmost bit set. */
- (NaClInstStateByte(inst_state, 3) & 0x80)) {
- return;
- }
- /* Intentionally fall to the next case. */
- default:
- if (NaClIsMovUsingRegisters(state->decoder_tables,
- inst, vector, RegRSP, RegRBP)) {
- /* case (1) -- see above, matching
- * mov %rsp, %rbp
- */
- return;
- }
- break;
- }
- /* If reached, assume that not a special case. */
- NaClReportIllegalChangeToRsp(state, inst_state);
-}
-
-/* Check if assignments to rbp resister is legal.
- *
- * Parameters are:
- * state - The state of the validator.
- * i - The index of the node (in the expression tree) that
- * assigns the RSP register.
- */
-static void NaClCheckRbpAssignments(struct NaClValidatorState* state,
- uint32_t i) {
- /* (1) mov %rbp, %rsp
- *
- * Note: maintains RSP/RBP invariant, since RSP was already
- * meeting the invariant.
- *
- * (2) %ebp = zero extend 32-bit value.
- * add %rbp, %rbase
- *
- * Typical use in the exit from a function, restoring RBP.
- * The ... in the MOV is gotten from a stack pop in such
- * cases. However, for long jumps etc., the value may
- * be gotten from memory, or even a register.
- *
- * (3) %ebp = zero extend 32-bit value.
- * lea %rbp, [%rbp+%rbase*1]
- *
- * Same as (2), except that we use instructions prior to the
- * pattern to do the add/subtract. Then let the result be
- * (zero-extended) moved into EBP, and use the lea to fill
- * in the top 32 bits of %RSP.
- *
- * Note: We require the scale to be 1, and rbase be in
- * the index position.
- */
- NaClInstState* inst_state = state->cur_inst_state;
- const NaClInst* inst = state->cur_inst;
- NaClMnemonic inst_name = inst->name;
- NaClExpVector* vector = state->cur_inst_vector;
-#ifdef NCVAL_TESTING
- char* buffer;
- size_t buffer_size;
-#endif
-
- switch (inst_name) {
- case InstAdd:
- /* case 2. */
- if (NaClIsBinarySetUsingRegisters(
- state->decoder_tables,
- inst, InstAdd, vector,
- RegRBP, state->base_register) &&
- NaClAssignsRegisterWithZeroExtends32(state, 1, RegEBP)) {
-#ifdef NCVAL_TESTING
- /* Report precondition of test. */
- NaClConditionAppend(state->precond, &buffer, &buffer_size);
- SNPRINTF(buffer, buffer_size, "ZeroExtends(ebp)");
-#endif
- NaClMarkInstructionJumpIllegal(state, state->cur_inst_state);
- state->set_base_registers.buffer[
- state->set_base_registers.previous_index].ebp_set_inst = NULL;
- return;
- }
- break;
- case InstLea:
- /* case 3 */
- if (NaClAcceptLeaWithMoveLea32To64(state, RegRBP)) {
-#ifdef NCVAL_TESTING
- /* Report precondition of test. */
- NaClConditionAppend(state->precond, &buffer, &buffer_size);
- SNPRINTF(buffer, buffer_size, "ZeroExtends(ebp)");
-#endif
- NaClMarkInstructionJumpIllegal(state, state->cur_inst_state);
- state->set_base_registers.buffer[
- state->set_base_registers.previous_index].ebp_set_inst = NULL;
- return;
- }
- break;
- default:
- if (NaClIsMovUsingRegisters(inst_state->decoder_tables,
- inst, vector, RegRBP, RegRSP)) {
- /* case 1 */
- return;
- }
- break;
- }
- /* If reached, not valid. */
- NaClValidatorInstMessage(LOG_ERROR, state, inst_state,
- "Illegal change to register RBP\n");
-}
-
-/* Reports error if the register name is a subregister of Rsp/Rbp/base register,
- * under assumption that it is illegal to change the value of such registers.
- */
-static void NaClCheckSubregChangeOfRspRbpOrBase(
- struct NaClValidatorState* state,
- NaClOpKind reg_name) {
- NaClInstState* inst_state = state->cur_inst_state;
- if (NaClIs64Subreg(inst_state, reg_name, state->base_register)) {
- NaClValidatorInstMessage(
- LOG_ERROR, state, inst_state,
- "Changing %s changes the value of %s\n",
- NaClOpKindName(reg_name),
- NaClOpKindName(state->base_register));
- } else if (NaClIs64Subreg(inst_state, reg_name, RegRSP)) {
- NaClValidatorInstMessage(
- LOG_ERROR, state, inst_state,
- "Changing %s changes the value of %s\n",
- NaClOpKindName(reg_name),
- NaClOpKindName(RegRSP));
- } else if (NaClIs64Subreg(inst_state, reg_name, RegRBP)) {
- NaClValidatorInstMessage(
- LOG_ERROR, state, inst_state,
- "Changing %s changes the value of %s\n",
- NaClOpKindName(reg_name),
- NaClOpKindName(RegRBP));
- }
-}
-
-void NaClBaseRegisterValidator(struct NaClValidatorState* state) {
- uint32_t i;
- NaClInstState* inst_state = state->cur_inst_state;
- NaClExpVector* vector = state->cur_inst_vector;
-
- DEBUG(NaClValidatorInstMessage(
- LOG_INFO, state, inst_state, "Checking base registers...\n"));
-
- /* Look for assignments to registers. */
- for (i = 0; i < vector->number_expr_nodes; ++i) {
- NaClExp* node = &vector->node[i];
- if (ExprRegister == node->kind) {
- if (node->flags & NACL_EFLAG(ExprSet)) {
- NaClOpKind reg_name = NaClGetExpRegisterInline(node);
-
- /* If reached, found an assignment to a register.
- * Check if its one that we care about (i.e.
- * the base register (RBASE), RSP, RBP, or segment register).
- */
- if (reg_name == state->base_register) {
- NaClValidatorInstMessage(
- LOG_ERROR, state, inst_state,
- "Illegal to change the value of register %s\n",
- NaClOpKindName(state->base_register));
- } else {
- switch (reg_name) {
- case RegRSP:
- NaClCheckRspAssignments(state, i);
- break;
- case RegRBP:
- NaClCheckRbpAssignments(state, i);
- break;
- case RegESP:
- /* Record that we must recheck this after we have
- * moved to the next instruction.
- */
- state->set_base_registers.buffer[
- state->set_base_registers.current_index
- ].esp_set_inst = inst_state;
- break;
- case RegEBP:
- /* Record that we must recheck this after we have
- * moved to the next instruction.
- */
- state->set_base_registers.buffer[
- state->set_base_registers.current_index
- ].ebp_set_inst = inst_state;
- break;
- case RegCS:
- case RegDS:
- case RegSS:
- case RegES:
- case RegFS:
- case RegGS:
- NaClValidatorInstMessage(
- LOG_ERROR, state, inst_state,
- "Illegal assignment to segment register %s\n",
- NaClOpKindName(reg_name));
- break;
- default:
- NaClCheckSubregChangeOfRspRbpOrBase(state, reg_name);
- break;
- }
- }
- }
- }
- }
- /* Before moving to the next instruction, see if we need to report
- * problems with the previous instruction.
- */
- NaClMaybeReportPreviousBad(state);
-}
-
-void NaClBaseRegisterSummarize(struct NaClValidatorState* state) {
- /* Check if problems in last instruction of segment. */
- NaClMaybeReportPreviousBad(state);
-}

Powered by Google App Engine
This is Rietveld 408576698