2 * Copyright (c) 2012 The Native Client Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file.
7 #include "native_client/src/trusted/validator/x86/ncval_reg_sfi/nc_postconds.h"
9 #include "native_client/src/include/portability_io.h"
10 #include "native_client/src/shared/platform/nacl_log.h"
11 #include "native_client/src/trusted/validator/x86/decoder/ncop_exps.h"
12 #include "native_client/src/trusted/validator/x86/decoder/nc_inst_state.h"
13 #include "native_client/src/trusted/validator/x86/decoder/nc_inst_trans.h"
14 #include "native_client/src/trusted/validator/x86/ncval_reg_sfi/ncvalidate_iter.h"
15 #include "native_client/src/trusted/validator/x86/ncval_reg_sfi/ncvalidate_iter_internal.h"
16 #include "native_client/src/trusted/validator/x86/ncval_reg_sfi/ncvalidate_utils.h"
17 #include "native_client/src/trusted/validator/x86/ncval_reg_sfi/nc_memory_protect.h"
19 /* To turn on debugging of instruction decoding, change value of
24 #include "native_client/src/shared/utils/debugging.h"
26 #include "native_client/src/trusted/validator/x86/decoder/ncop_exps_inl.c"
28 /* Maximum character buffer size to use for generating messages. */
29 static const size_t kMaxBufferSize = 1024;
32 void NaClAddAssignsRegisterWithZeroExtendsPostconds(
33 struct NaClValidatorState* state) {
35 NaClExpVector* vector = state->cur_inst_vector;
37 DEBUG(NaClValidatorInstMessage(
38 LOG_INFO, state, state->cur_inst_state,
39 "-> Checking ZeroExtends postconditions...\n"));
41 /* Look for assignments to 32-bit registers for instructions that
44 for (i = 0; i < vector->number_expr_nodes; ++i) {
45 NaClExp* node = &vector->node[i];
47 if (ExprRegister != node->kind) continue;
48 if (!NaClHasBit(node->flags, NACL_EFLAG(ExprSet))) continue;
49 if (!NaClHasBit(node->flags, NACL_EFLAG(ExprSize32))) continue;
50 node_reg = NaClGetExpRegisterInline(node);
51 if (node_reg == RegUnknown) continue;
52 if (NaClAssignsRegisterWithZeroExtends32(state, 0, node_reg)) {
55 char reg_name[kMaxBufferSize];
56 NaClOpRegName(node_reg, reg_name, kMaxBufferSize);
57 NaClConditionAppend(state->postcond, &buffer, &buffer_size);
58 SNPRINTF(buffer, buffer_size, "ZeroExtends(%s)", reg_name);
61 DEBUG(NaClValidatorMessage(
62 LOG_INFO, state, "<- Finished ZeroExtends postconditions...\n"));
65 void NaClAddLeaSafeAddressPostconds(
66 struct NaClValidatorState* state) {
68 NaClExpVector* vector = state->cur_inst_vector;
69 DEBUG(NaClValidatorInstMessage(
70 LOG_INFO, state, state->cur_inst_state,
71 "Checking SafeAddress postconditions...\n"));
73 /* Look for assignments to registers. */
74 for (i = 0; i < vector->number_expr_nodes; ++i) {
76 NaClExp* node = &vector->node[i];
77 if (ExprRegister != node->kind) continue;
78 if (!NaClHasBit(node->flags, NACL_EFLAG(ExprSet))) continue;
79 if (!NaClHasBit(node->flags, NACL_EFLAG(ExprSize64))) continue;
80 reg = NaClGetExpRegisterInline(node);
81 if (RegUnknown == reg) continue;
82 if ((reg == RegRSP) || (reg == RegRBP)) {
83 /* Note: Do not need to check safe addresses computed
84 * by "LEA Rsp/Rbp ...". Currently, these two registers
85 * are already checked.. See NaClCheckRspAssignments and
86 * NaClCheckRbpAssignments in nc_protect_base.c for more
87 * information on how such LEA instructions are checked.
89 if (InstLea != NaClInstStateInst(state->cur_inst_state)->name) {
90 NaClAcceptLeaWithMoveLea32To64(state, reg);
92 } else if (NaClAcceptLeaSafeAddress(state)) {
95 char reg_name[kMaxBufferSize];
96 NaClOpRegName(reg, reg_name, kMaxBufferSize);
97 NaClConditionAppend(state->postcond, &buffer, &buffer_size);
98 SNPRINTF(buffer, buffer_size, "SafeAddress(%s)", reg_name);
101 DEBUG(NaClValidatorMessage(
102 LOG_INFO, state, "Finished SafeAddress postconditions...\n"));