1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #ifndef CODE_SIGN_JIT_CODE_SIGNER_H
17 #define CODE_SIGN_JIT_CODE_SIGNER_H
18
19 #include <queue>
20 #include <vector>
21 #include "pac_sign_ctx.h"
22
23 namespace OHOS {
24 namespace Security {
25 namespace CodeSign {
26 using Instr = uint32_t;
27 using Byte = uint8_t;
28
29 constexpr int32_t INSTRUCTION_SIZE = 4;
30 constexpr int32_t LOG_2_INSTRUCTION_SIZE = 2;
31 #ifndef JIT_FORT_DISABLE
32 // This is interpreted from code logic. If a new long log comes this must be updated.
33 constexpr size_t MAX_DEFERRED_LOG_LENGTH = 150;
34 #endif
35
GetIndexFromOffset(int offset)36 static inline int GetIndexFromOffset(int offset)
37 {
38 return static_cast<int>(static_cast<uint32_t>(offset) >> LOG_2_INSTRUCTION_SIZE);
39 }
40
41 #ifndef JIT_FORT_DISABLE
42 struct DeferredLog {
43 DeferredLog() = delete;
DeferredLogDeferredLog44 DeferredLog(char *message) noexcept : message(message) {}
45 DeferredLog(const DeferredLog &other) = delete;
DeferredLogDeferredLog46 DeferredLog(DeferredLog &&other) noexcept : message(other.message)
47 {
48 other.message = nullptr;
49 }
~DeferredLogDeferredLog50 ~DeferredLog()
51 {
52 free(message);
53 message = nullptr;
54 }
55 char *message;
56 };
57 #endif
58
59 class JitCodeSigner {
60 public:
61 JitCodeSigner();
~JitCodeSigner()62 ~JitCodeSigner() {};
63 void Reset();
64 void SignInstruction(Instr insn);
65 void SkipNext(uint32_t n);
66 int32_t PatchInstruction(int offset, Instr insn);
67 int32_t ValidateCodeCopy(Instr *jitMemory, Byte *jitBuffer, int size);
68
69 void RegisterTmpBuffer(Byte *tmpBuffer);
70 int32_t SignData(const Byte *data, uint32_t size);
71 int32_t PatchInstruction(Byte *jitBuffer, Instr insn);
72 int32_t PatchData(int offset, const Byte *const data, uint32_t size);
73 int32_t PatchData(Byte *buffer, const Byte *const data, uint32_t size);
74 #ifndef JIT_FORT_DISABLE
75 void FlushLog();
76 #endif
77
78 protected:
79 bool ConvertPatchOffsetToIndex(const int offset, int &curIndex);
80 int32_t CheckDataCopy(Instr *jitMemory, Byte *jitBuffer, int size);
81
82 protected:
83 Byte *tmpBuffer_;
84 int offset_;
85 std::queue<Byte> willSign_;
86 std::vector<uint32_t> signTable_;
87 PACSignCtx ctx_;
88 #ifndef JIT_FORT_DISABLE
89 std::vector<DeferredLog> deferredLogs;
90 #endif
91 };
92 }
93 }
94 }
95 #endif