• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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