1 : /*
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.
5 : */
6 :
7 : #include "native_client/src/shared/platform/nacl_log.h"
8 : #include "native_client/src/trusted/service_runtime/sel_ldr.h"
9 : #include "native_client/src/trusted/validator/ncvalidate.h"
10 :
11 : /* Translate validation status to values wanted by sel_ldr. */
12 3 : static int NaClValidateStatus(NaClValidationStatus status) {
13 3 : switch (status) {
14 : case NaClValidationSucceeded:
15 3 : return LOAD_OK;
16 : case NaClValidationFailedOutOfMemory:
17 : /* Note: this is confusing, but is what sel_ldr is expecting. */
18 0 : return LOAD_BAD_FILE;
19 : case NaClValidationFailed:
20 : case NaClValidationFailedNotImplemented:
21 : case NaClValidationFailedCpuNotSupported:
22 : case NaClValidationFailedSegmentationIssue:
23 : default:
24 0 : return LOAD_VALIDATION_FAILED;
25 : }
26 : }
27 :
28 : int NaClValidateCode(struct NaClApp *nap, uintptr_t guest_addr,
29 3 : uint8_t *data, size_t size) {
30 3 : NaClValidationStatus status = NaClValidationSucceeded;
31 3 : enum NaClSBKind sb_kind = NACL_SB_DEFAULT;
32 3 : if (nap->validator_stub_out_mode) {
33 : /* In stub out mode, we do two passes. The second pass acts as a
34 : sanity check that bad instructions were indeed overwritten with
35 : allowable HLTs. */
36 0 : status = NACL_SUBARCH_NAME(ApplyValidator,
37 : NACL_TARGET_ARCH,
38 : NACL_TARGET_SUBARCH)(
39 : sb_kind,
40 : NaClApplyValidationDoStubout,
41 : guest_addr, data, size,
42 : nap->bundle_size, &nap->cpu_features);
43 : }
44 3 : if (status == NaClValidationSucceeded) {
45 3 : status = NACL_SUBARCH_NAME(ApplyValidator,
46 : NACL_TARGET_ARCH,
47 : NACL_TARGET_SUBARCH)(
48 : sb_kind,
49 : NaClApplyCodeValidation,
50 : guest_addr, data, size,
51 : nap->bundle_size, &nap->cpu_features);
52 : }
53 3 : return NaClValidateStatus(status);
54 : }
55 :
56 : int NaClValidateCodeReplacement(struct NaClApp *nap, uintptr_t guest_addr,
57 : uint8_t *data_old, uint8_t *data_new,
58 0 : size_t size) {
59 0 : enum NaClSBKind sb_kind = NACL_SB_DEFAULT;
60 0 : if (nap->validator_stub_out_mode) return LOAD_BAD_FILE;
61 :
62 0 : if ((guest_addr % nap->bundle_size) != 0 ||
63 : (size % nap->bundle_size) != 0) {
64 0 : return LOAD_BAD_FILE;
65 : }
66 :
67 0 : return NaClValidateStatus(
68 : NACL_SUBARCH_NAME(ApplyValidatorCodeReplacement,
69 : NACL_TARGET_ARCH,
70 : NACL_TARGET_SUBARCH)
71 : (sb_kind, guest_addr, data_old, data_new, size, nap->bundle_size,
72 : &nap->cpu_features));
73 : }
74 :
75 : int NaClCopyCode(struct NaClApp *nap, uintptr_t guest_addr,
76 : uint8_t *data_old, uint8_t *data_new,
77 0 : size_t size) {
78 0 : enum NaClSBKind sb_kind = NACL_SB_DEFAULT;
79 0 : return NaClValidateStatus(
80 : NACL_SUBARCH_NAME(ApplyValidatorCopy,
81 : NACL_TARGET_ARCH,
82 : NACL_TARGET_SUBARCH)
83 : (sb_kind, guest_addr, data_old, data_new, size, nap->bundle_size,
84 : &nap->cpu_features));
85 : }
86 :
87 3 : NaClErrorCode NaClValidateImage(struct NaClApp *nap) {
88 : uintptr_t memp;
89 : uintptr_t endp;
90 : size_t regionsize;
91 : NaClErrorCode rcode;
92 :
93 3 : memp = nap->mem_start + NACL_TRAMPOLINE_END;
94 3 : endp = nap->mem_start + nap->static_text_end;
95 3 : regionsize = endp - memp;
96 3 : if (endp < memp) {
97 0 : return LOAD_NO_MEMORY;
98 : }
99 :
100 3 : if (nap->skip_validator) {
101 0 : NaClLog(LOG_ERROR, "VALIDATION SKIPPED.\n");
102 0 : return LOAD_OK;
103 : } else {
104 3 : rcode = NaClValidateCode(nap, NACL_TRAMPOLINE_END,
105 : (uint8_t *) memp, regionsize);
106 3 : if (LOAD_OK != rcode) {
107 0 : if (nap->ignore_validator_result) {
108 0 : NaClLog(LOG_ERROR, "VALIDATION FAILED: continuing anyway...\n");
109 0 : rcode = LOAD_OK;
110 : } else {
111 0 : NaClLog(LOG_ERROR, "VALIDATION FAILED.\n");
112 0 : NaClLog(LOG_ERROR,
113 : "Run sel_ldr in debug mode to ignore validation failure.\n");
114 0 : NaClLog(LOG_ERROR,
115 : "Run ncval <module-name> for validation error details.\n");
116 0 : rcode = LOAD_VALIDATION_FAILED;
117 : }
118 : }
119 : }
120 3 : return rcode;
121 : }
|