• 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 #include <cstdio>
17 #include <cstring>
18 #include <fcntl.h>
19 #include <gtest/gtest.h>
20 #include <gtest/hwext/gtest-multithread.h>
21 #include <random>
22 #include <securec.h>
23 #include <sys/mman.h>
24 #include <sys/ioctl.h>
25 #include <unistd.h>
26 
27 #include "errcode.h"
28 #include "jit_buffer_integrity.h"
29 #include "code_sign_attr_utils.h"
30 #include "pac_sign_ctx.h"
31 
32 namespace OHOS {
33 namespace Security {
34 namespace CodeSign {
35 using namespace std;
36 using namespace testing::ext;
37 using namespace testing::mt;
38 
39 enum class JitBufferIntegrityLevel {
40     Level0,
41     Level1,
42 };
43 
44 #define CAST_VOID_PTR(buffer) (reinterpret_cast<void *>(buffer))
45 
46 static Instr g_testInstructionSet[] = {
47     0x11111111,
48     0x22222222,
49     0x33333333, // patched -> 0x66666666
50     0x44444444, // patched -> 0x77777777
51     0x55555555
52 };
53 
54 static Instr g_afterPatchInstructionSet[] = {
55     0x11111111,
56     0x22222222,
57     0x66666666,
58     0x77777777,
59     0x55555555
60 };
61 
62 static Instr g_testPatchInstructionSet[] = {
63     0x66666666,
64     0x77777777
65 };
66 
67 static constexpr uint32_t MULTI_THREAD_NUM = 10;
68 static constexpr int INSTRUCTIONS_SET_SIZE =
69     sizeof(g_testInstructionSet) / sizeof(g_testInstructionSet[0]);
70 static constexpr int INSTRUCTIONS_SET_SIZE_BYTES = sizeof(g_testInstructionSet);
71 static constexpr int TEST_PATCH_INDEX = 2;
72 
73 static constexpr int PATCH_INSTRUCTIONS_SET_SIZE =
74     sizeof(g_testPatchInstructionSet) / sizeof(g_testPatchInstructionSet[0]);
75 
76 static void *g_testInstructionBuf = CAST_VOID_PTR(g_testInstructionSet);
77 static void *g_afterPatchInstructionBuf = CAST_VOID_PTR(g_afterPatchInstructionSet);
78 static void *g_testPatchInstructionBuf = CAST_VOID_PTR(g_testPatchInstructionSet);
79 static void *g_jitMemory = nullptr;
80 
81 void *g_mapJitBase = CAST_VOID_PTR(0x800000000);
82 void *g_mapJitBase2 = CAST_VOID_PTR(0x800001000);
83 constexpr size_t PAGE_SIZE = 4096;
84 constexpr int BUFFER_SIZE = 4096;
85 
86 #define JITFORT_PRCTL_OPTION 0x6a6974
87 #define JITFORT_CREATE_COPGTABLE    5
88 #define MAP_JIT 0x1000
89 
90 const JitBufferIntegrityLevel MIN_LEVEL = JitBufferIntegrityLevel::Level0;
91 const JitBufferIntegrityLevel MAX_LEVEL = JitBufferIntegrityLevel::Level1;
92 
93 std::mutex g_jitMemory_mutex;
94 
AllocJitMemory()95 static inline void AllocJitMemory()
96 {
97     g_jitMemory = mmap(g_mapJitBase, PAGE_SIZE + PAGE_SIZE,
98         PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
99 #ifndef JIT_FORT_DISABLE
100     int cookie = std::random_device{}();
101     g_jitMemory = mmap(g_mapJitBase2, PAGE_SIZE,
102         PROT_READ | PROT_WRITE | PROT_EXEC,
103         MAP_ANONYMOUS | MAP_PRIVATE | MAP_JIT, cookie, 0);
104 #endif
105     EXPECT_NE(g_jitMemory, MAP_FAILED);
106 }
107 
JitFortPrepare()108 static inline void JitFortPrepare()
109 {
110 #ifndef JIT_FORT_DISABLE
111     EXPECT_EQ(InitXpm(1, PROCESS_OWNERID_UNINIT, NULL, NULL), CS_SUCCESS);
112     PrctlWrapper(JITFORT_PRCTL_OPTION, JITFORT_CREATE_COPGTABLE);
113 #endif
114 }
115 
FreeJitMemory()116 static inline void FreeJitMemory()
117 {
118 #ifndef JIT_FORT_DISABLE
119     munmap(g_mapJitBase, PAGE_SIZE);
120     munmap(g_mapJitBase2, PAGE_SIZE);
121 #endif
122 }
123 
124 class JitCodeSignTest : public testing::Test {
125 public:
JitCodeSignTest()126     JitCodeSignTest() {};
~JitCodeSignTest()127     virtual ~JitCodeSignTest() {};
128 
SetUpTestCase()129     static void SetUpTestCase()
130     {
131         EXPECT_EQ(IsSupportJitCodeSigner(), true);
132         JitFortPrepare();
133         AllocJitMemory();
134     };
135 
TearDownTestCase()136     static void TearDownTestCase()
137     {
138         FreeJitMemory();
139     };
140 
SetUp()141     void SetUp() {};
TearDown()142     void TearDown() {};
143 };
144 
145 /**
146  * @tc.name: JitCodeSignTest_0001
147  * @tc.desc: sign instructions and verify succuss
148  * @tc.type: Func
149  * @tc.require: I9O6PK
150  */
151 HWTEST_F(JitCodeSignTest, JitCodeSignTest_0001, TestSize.Level0)
152 {
153     JitCodeSigner *signer = nullptr;
154     for (JitBufferIntegrityLevel level = MIN_LEVEL;
155         level <= MAX_LEVEL; level = static_cast<JitBufferIntegrityLevel>(static_cast<int>(level) + 1)) {
156         signer = CreateJitCodeSigner();
157         int i = 0;
158         while (i < INSTRUCTIONS_SET_SIZE) {
159             AppendInstruction(signer, g_testInstructionSet[i]);
160             i++;
161         }
162 
163         EXPECT_EQ(CopyToJitCode(signer, g_jitMemory, g_testInstructionSet,
164             INSTRUCTIONS_SET_SIZE_BYTES), CS_SUCCESS);
165         EXPECT_EQ(memcmp(g_jitMemory, g_testInstructionSet, INSTRUCTIONS_SET_SIZE_BYTES), 0);
166 
167         delete signer;
168         signer = nullptr;
169     }
170 }
171 
172 
173 /**
174  * @tc.name: JitCodeSignTest_0002
175  * @tc.desc: sign data and verify succuss
176  * @tc.type: Func
177  * @tc.require: I9O6PK
178  */
179 HWTEST_F(JitCodeSignTest, JitCodeSignTest_0002, TestSize.Level0)
180 {
181     JitCodeSigner *signer = nullptr;
182     for (JitBufferIntegrityLevel level = MIN_LEVEL;
183         level <= MAX_LEVEL; level = static_cast<JitBufferIntegrityLevel>(static_cast<int>(level) + 1)) {
184         signer = CreateJitCodeSigner();
185         AppendData(signer, g_testInstructionBuf, INSTRUCTIONS_SET_SIZE_BYTES);
186 
187         EXPECT_EQ(CopyToJitCode(signer, g_jitMemory, g_testInstructionBuf,
188             INSTRUCTIONS_SET_SIZE_BYTES), CS_SUCCESS);
189         EXPECT_EQ(memcmp(g_jitMemory, g_testInstructionBuf, INSTRUCTIONS_SET_SIZE_BYTES), 0);
190 
191         delete signer;
192         signer = nullptr;
193     }
194 }
195 
196 /**
197  * @tc.name: JitCodeSignTest_0003
198  * @tc.desc: sign and patch instructions succuss
199  * @tc.type: Func
200  * @tc.require: I9O6PK
201  */
202 HWTEST_F(JitCodeSignTest, JitCodeSignTest_0003, TestSize.Level0)
203 {
204     JitCodeSigner *signer = nullptr;
205     for (JitBufferIntegrityLevel level = MIN_LEVEL;
206         level <= MAX_LEVEL;
207         level = static_cast<JitBufferIntegrityLevel>(static_cast<int>(level) + 1)) {
208         signer = CreateJitCodeSigner();
209         int i = 0, offset = 0;
210         while (i < TEST_PATCH_INDEX) {
211             AppendInstruction(signer, g_testInstructionSet[i]);
212             i++;
213         }
214         for (int j = 0; j < PATCH_INSTRUCTIONS_SET_SIZE; j++) {
215             WillFixUp(signer, 1);
216             AppendInstruction(signer, g_testInstructionSet[i]);
217             i++;
218         }
219         while (i < INSTRUCTIONS_SET_SIZE) {
220             AppendInstruction(signer, g_testInstructionSet[i]);
221             i++;
222         }
223         offset = TEST_PATCH_INDEX * INSTRUCTION_SIZE;
224         for (int j = 0; j < PATCH_INSTRUCTIONS_SET_SIZE; j++) {
225             PatchInstruction(signer, offset, g_testPatchInstructionSet[j]);
226             offset += INSTRUCTION_SIZE;
227         }
228 
229         EXPECT_EQ(CopyToJitCode(signer, g_jitMemory, g_afterPatchInstructionBuf,
230             INSTRUCTIONS_SET_SIZE_BYTES), CS_SUCCESS);
231         EXPECT_EQ(memcmp(g_jitMemory, g_afterPatchInstructionBuf, INSTRUCTIONS_SET_SIZE_BYTES), 0);
232 
233         delete signer;
234         signer = nullptr;
235     }
236 }
237 
238 /**
239  * @tc.name: JitCodeSignTest_0004
240  * @tc.desc: sign and patch data succuss
241  * @tc.type: Func
242  * @tc.require: I9O6PK
243  */
244 HWTEST_F(JitCodeSignTest, JitCodeSignTest_0004, TestSize.Level0)
245 {
246     JitCodeSigner *signer = nullptr;
247     for (JitBufferIntegrityLevel level = MIN_LEVEL;
248         level <= MAX_LEVEL;
249         level = static_cast<JitBufferIntegrityLevel>(static_cast<int>(level) + 1)) {
250         signer = CreateJitCodeSigner();
251         int i = 0, offset = 0;
252         while (i < TEST_PATCH_INDEX) {
253             AppendInstruction(signer, g_testInstructionSet[i]);
254             offset += INSTRUCTION_SIZE;
255             i++;
256         }
257 
258         int patchSize = sizeof(g_testPatchInstructionSet);
259         WillFixUp(signer, PATCH_INSTRUCTIONS_SET_SIZE);
260         AppendData(signer, CAST_VOID_PTR(&g_testInstructionSet[i]), patchSize);
261         i += PATCH_INSTRUCTIONS_SET_SIZE;
262         offset += patchSize;
263 
264         while (i < INSTRUCTIONS_SET_SIZE) {
265             AppendInstruction(signer, g_testInstructionSet[i]);
266             i++;
267         }
268 
269         offset = TEST_PATCH_INDEX * INSTRUCTION_SIZE;
270         PatchData(signer, offset, g_testPatchInstructionBuf, INSTRUCTION_SIZE);
271 
272         RegisterTmpBuffer(signer, g_afterPatchInstructionBuf);
273         PatchData(signer, CAST_VOID_PTR(reinterpret_cast<uintptr_t>(
274             g_afterPatchInstructionBuf) + offset + INSTRUCTION_SIZE),
275             CAST_VOID_PTR(&g_testPatchInstructionSet[1]),
276             INSTRUCTION_SIZE);
277 
278         EXPECT_EQ(CopyToJitCode(signer, g_jitMemory, g_afterPatchInstructionBuf,
279             INSTRUCTIONS_SET_SIZE_BYTES), CS_SUCCESS);
280         EXPECT_EQ(memcmp(g_jitMemory, g_afterPatchInstructionBuf, INSTRUCTIONS_SET_SIZE_BYTES), 0);
281 
282         delete signer;
283         signer = nullptr;
284     }
285 }
286 
287 /**
288  * @tc.name: JitCodeSignTest_0005
289  * @tc.desc: sign and copy wrong data failed
290  * @tc.type: Func
291  * @tc.require: I9O6PK
292  */
293 HWTEST_F(JitCodeSignTest, JitCodeSignTest_0005, TestSize.Level0)
294 {
295     JitCodeSigner *signer = nullptr;
296     for (JitBufferIntegrityLevel level = MIN_LEVEL;
297         level <= MAX_LEVEL;
298         level = static_cast<JitBufferIntegrityLevel>(static_cast<int>(level) + 1)) {
299         signer = CreateJitCodeSigner();
300         AppendData(signer, g_testInstructionBuf, INSTRUCTIONS_SET_SIZE_BYTES);
301         int sizeInByte = sizeof(g_testInstructionSet);
302         EXPECT_EQ(CopyToJitCode(signer, g_jitMemory, g_afterPatchInstructionBuf,
303             sizeInByte), CS_ERR_VALIDATE_CODE);
304 
305         delete signer;
306         signer = nullptr;
307     }
308 }
309 
310 /**
311  * @tc.name: JitCodeSignTest_0006
312  * @tc.desc: sign and copy with wrong size failed
313  * @tc.type: Func
314  * @tc.require: I9O6PK
315  */
316 HWTEST_F(JitCodeSignTest, JitCodeSignTest_0006, TestSize.Level0)
317 {
318     JitCodeSigner *signer = nullptr;
319     for (JitBufferIntegrityLevel level = MIN_LEVEL;
320         level <= MAX_LEVEL;
321         level = static_cast<JitBufferIntegrityLevel>(static_cast<int>(level) + 1)) {
322         signer = CreateJitCodeSigner();
323         RegisterTmpBuffer(signer, g_testInstructionBuf);
324         AppendData(signer, g_testInstructionBuf, INSTRUCTIONS_SET_SIZE_BYTES);
325 
326         EXPECT_EQ(CopyToJitCode(signer, g_jitMemory, g_testInstructionBuf,
327             INSTRUCTIONS_SET_SIZE_BYTES - 1), CS_ERR_JIT_SIGN_SIZE);
328 
329         delete signer;
330         signer = nullptr;
331     }
332 }
333 
334 /**
335  * @tc.name: JitCodeSignTest_0007
336  * @tc.desc: sign and copy with buffer failed
337  * @tc.type: Func
338  * @tc.require: I9O6PK
339  */
340 HWTEST_F(JitCodeSignTest, JitCodeSignTest_0007, TestSize.Level0)
341 {
342     JitCodeSigner *signer = nullptr;
343     for (JitBufferIntegrityLevel level = MIN_LEVEL;
344         level <= MAX_LEVEL;
345         level = static_cast<JitBufferIntegrityLevel>(static_cast<int>(level) + 1)) {
346         signer = CreateJitCodeSigner();
347         RegisterTmpBuffer(signer, g_testInstructionBuf);
348         AppendData(signer, g_testInstructionBuf, INSTRUCTIONS_SET_SIZE_BYTES - 1);
349 
350         EXPECT_EQ(CopyToJitCode(signer, g_jitMemory, g_afterPatchInstructionBuf,
351             INSTRUCTIONS_SET_SIZE_BYTES), CS_ERR_JIT_SIGN_SIZE);
352 
353         delete signer;
354         signer = nullptr;
355     }
356 }
357 
358 /**
359  * @tc.name: JitCodeSignTest_0008
360  * @tc.desc: sign data without 4 byte-alignment and copy success
361  * @tc.type: Func
362  * @tc.require: I9O6PK
363  */
364 HWTEST_F(JitCodeSignTest, JitCodeSignTest_0008, TestSize.Level0)
365 {
366     JitCodeSigner *signer = nullptr;
367     for (JitBufferIntegrityLevel level = MIN_LEVEL;
368         level <= MAX_LEVEL;
369         level = static_cast<JitBufferIntegrityLevel>(static_cast<int>(level) + 1)) {
370         signer = CreateJitCodeSigner();
371         Byte *ptr = reinterpret_cast<Byte *>(g_testInstructionBuf) + 1;
372         AppendData(signer, g_testInstructionBuf, 1);
373         AppendData(signer, CAST_VOID_PTR(ptr), INSTRUCTIONS_SET_SIZE_BYTES - 1);
374 
375         EXPECT_EQ(CopyToJitCode(signer, g_jitMemory, g_testInstructionBuf,
376             INSTRUCTIONS_SET_SIZE_BYTES), CS_SUCCESS);
377 
378         delete signer;
379         signer = nullptr;
380     }
381 }
382 
383 /**
384  * @tc.name: JitCodeSignTest_0009
385  * @tc.desc: sign data and patch without 4 byte-alignment failed
386  * @tc.type: Func
387  * @tc.require: I9O6PK
388  */
389 HWTEST_F(JitCodeSignTest, JitCodeSignTest_0009, TestSize.Level0)
390 {
391     JitCodeSigner *signer = nullptr;
392     for (JitBufferIntegrityLevel level = MIN_LEVEL;
393         level <= MAX_LEVEL;
394         level = static_cast<JitBufferIntegrityLevel>(static_cast<int>(level) + 1)) {
395         signer = CreateJitCodeSigner();
396         int i = 0, offset = 0;
397         while (i < TEST_PATCH_INDEX) {
398             AppendInstruction(signer, g_testInstructionSet[i]);
399             offset += INSTRUCTION_SIZE;
400             i++;
401         }
402 
403         int patchSize = sizeof(g_testPatchInstructionSet);
404         WillFixUp(signer, PATCH_INSTRUCTIONS_SET_SIZE);
405         AppendData(signer, CAST_VOID_PTR(&g_testInstructionSet[i]), patchSize);
406         i += PATCH_INSTRUCTIONS_SET_SIZE;
407         offset += patchSize;
408 
409         while (i < INSTRUCTIONS_SET_SIZE) {
410             AppendInstruction(signer, g_testInstructionSet[i]);
411             i++;
412         }
413 
414         offset = TEST_PATCH_INDEX * INSTRUCTION_SIZE;
415         EXPECT_EQ(PatchData(signer, offset, g_testPatchInstructionBuf,
416             patchSize - 1), CS_ERR_JIT_SIGN_SIZE);
417 
418         delete signer;
419         signer = nullptr;
420     }
421 }
422 
423 /**
424  * @tc.name: JitCodeSignTest_0010
425  * @tc.desc: patch with buffer address successfully
426  * @tc.type: Func
427  * @tc.require: I9O6PK
428  */
429 HWTEST_F(JitCodeSignTest, JitCodeSignTest_0010, TestSize.Level0)
430 {
431     JitCodeSigner *signer = nullptr;
432     for (JitBufferIntegrityLevel level = MIN_LEVEL;
433         level <= MAX_LEVEL;
434         level = static_cast<JitBufferIntegrityLevel>(static_cast<int>(level) + 1)) {
435         signer = CreateJitCodeSigner();
436         int i = 0, offset = 0;
437         while (i < TEST_PATCH_INDEX) {
438             AppendInstruction(signer, g_testInstructionSet[i]);
439             i++;
440         }
441         for (int j = 0; j < PATCH_INSTRUCTIONS_SET_SIZE; j++) {
442             WillFixUp(signer, 1);
443             AppendInstruction(signer, g_testInstructionSet[i]);
444             i++;
445         }
446         while (i < INSTRUCTIONS_SET_SIZE) {
447             AppendInstruction(signer, g_testInstructionSet[i]);
448             i++;
449         }
450         offset = TEST_PATCH_INDEX * INSTRUCTION_SIZE;
451         RegisterTmpBuffer(signer, g_afterPatchInstructionBuf);
452         for (int j = 0; j < PATCH_INSTRUCTIONS_SET_SIZE; j++) {
453             PatchInstruction(signer, CAST_VOID_PTR(
454                 &g_afterPatchInstructionSet[TEST_PATCH_INDEX + j]), g_testPatchInstructionSet[j]);
455             offset += INSTRUCTION_SIZE;
456         }
457 
458         EXPECT_EQ(CopyToJitCode(signer, g_jitMemory, g_afterPatchInstructionBuf,
459             INSTRUCTIONS_SET_SIZE_BYTES), CS_SUCCESS);
460         EXPECT_EQ(memcmp(g_jitMemory, g_afterPatchInstructionBuf, INSTRUCTIONS_SET_SIZE_BYTES), 0);
461 
462         delete signer;
463         signer = nullptr;
464     }
465 }
466 
467 /**
468  * @tc.name: JitCodeSignTest_0011
469  * @tc.desc: patch faied with invalid buffer
470  * @tc.type: Func
471  * @tc.require: I9O6PK
472  */
473 HWTEST_F(JitCodeSignTest, JitCodeSignTest_0011, TestSize.Level0)
474 {
475     JitCodeSigner *signer = nullptr;
476     for (JitBufferIntegrityLevel level = MIN_LEVEL;
477         level <= MAX_LEVEL;
478         level = static_cast<JitBufferIntegrityLevel>(static_cast<int>(level) + 1)) {
479         signer = CreateJitCodeSigner();
480 
481         RegisterTmpBuffer(signer, g_afterPatchInstructionBuf);
482         EXPECT_EQ(PatchInstruction(signer, nullptr, INSTRUCTION_SIZE), CS_ERR_PATCH_INVALID);
483 
484         RegisterTmpBuffer(signer, nullptr);
485         EXPECT_EQ(PatchInstruction(signer, reinterpret_cast<Byte *>(g_afterPatchInstructionBuf),
486             INSTRUCTION_SIZE), CS_ERR_PATCH_INVALID);
487 
488         delete signer;
489         signer = nullptr;
490     }
491 }
492 
493 /**
494  * @tc.name: JitCodeSignTest_00012
495  * @tc.desc: reset jit memory success
496  * @tc.type: Func
497  * @tc.require: I9O6PK
498  */
499 HWTEST_F(JitCodeSignTest, JitCodeSignTest_00012, TestSize.Level0)
500 {
501     Byte tmpBuffer[INSTRUCTIONS_SET_SIZE_BYTES] = {0};
502     ResetJitCode(g_jitMemory, INSTRUCTIONS_SET_SIZE_BYTES);
503     EXPECT_EQ(memcmp(g_jitMemory, tmpBuffer, INSTRUCTIONS_SET_SIZE_BYTES), 0);
504 }
505 
506 /**
507  * @tc.name: JitCodeSignTest_00013
508  * @tc.desc: copy failed with wrong size
509  * @tc.type: Func
510  * @tc.require: I9O6PK
511  */
512 HWTEST_F(JitCodeSignTest, JitCodeSignTest_00013, TestSize.Level0)
513 {
514     JitCodeSigner *signer = nullptr;
515     for (JitBufferIntegrityLevel level = MIN_LEVEL;
516         level <= MAX_LEVEL;
517         level = static_cast<JitBufferIntegrityLevel>(static_cast<int>(level) + 1)) {
518         signer = CreateJitCodeSigner();
519         AppendData(signer, g_testInstructionBuf, INSTRUCTIONS_SET_SIZE_BYTES);
520         EXPECT_EQ(CopyToJitCode(signer, g_jitMemory, g_testInstructionBuf,
521             INSTRUCTIONS_SET_SIZE_BYTES - 1), CS_ERR_JIT_SIGN_SIZE);
522 
523         signer->Reset();
524         EXPECT_EQ(CopyToJitCode(signer, g_jitMemory, g_testInstructionBuf,
525             INSTRUCTIONS_SET_SIZE_BYTES), CS_ERR_JIT_SIGN_SIZE);
526 
527         delete signer;
528         signer = nullptr;
529     }
530 }
531 
532 /**
533  * @tc.name: JitCodeSignTest_00014
534  * @tc.desc: copy data with different size
535  * @tc.type: Func
536  * @tc.require: I9O6PK
537  */
538 HWTEST_F(JitCodeSignTest, JitCodeSignTest_00014, TestSize.Level0)
539 {
540     JitCodeSigner *signer = nullptr;
541     for (JitBufferIntegrityLevel level = MIN_LEVEL;
542         level <= MAX_LEVEL;
543         level = static_cast<JitBufferIntegrityLevel>(static_cast<int>(level) + 1)) {
544         signer = CreateJitCodeSigner();
545         Byte *data = reinterpret_cast<Byte *>(g_testInstructionSet);
546         uint32_t dataSize[] = {1, 2, 1, 4, 2, 8, 2, 1, 3};
547         int pos = 0;
548         for (auto size : dataSize) {
549             AppendData(signer, CAST_VOID_PTR(data + pos), size);
550             pos += size;
551         }
552 
553         EXPECT_EQ(CopyToJitCode(signer, g_jitMemory, g_testInstructionBuf,
554             INSTRUCTIONS_SET_SIZE_BYTES), CS_SUCCESS);
555         EXPECT_EQ(memcmp(g_jitMemory, g_testInstructionBuf, INSTRUCTIONS_SET_SIZE_BYTES), 0);
556 
557         delete signer;
558         signer = nullptr;
559     }
560 }
561 
562 /**
563  * @tc.name: JitCodeSignTest_00015
564  * @tc.desc: validate and copy code to same buffer in parallel
565  * @tc.type: Func
566  * @tc.require: I9O6PK
567  */
568 HWMTEST_F(JitCodeSignTest, JitCodeSignTest_00015, TestSize.Level1, MULTI_THREAD_NUM)
569 {
570     JitCodeSigner *signer = nullptr;
571     for (JitBufferIntegrityLevel level = MIN_LEVEL;
572         level <= MAX_LEVEL;
573         level = static_cast<JitBufferIntegrityLevel>(static_cast<int>(level) + 1)) {
574         signer = CreateJitCodeSigner();
575         int i = 0;
576         while (i < INSTRUCTIONS_SET_SIZE) {
577             AppendInstruction(signer, g_testInstructionSet[i]);
578             i++;
579         }
580         size_t size = INSTRUCTIONS_SET_SIZE_BYTES;
581         {
582             std::lock_guard<std::mutex> lock(g_jitMemory_mutex);
583 #ifndef JIT_FORT_DISABLE
584             PrctlWrapper(JITFORT_PRCTL_OPTION, JITFORT_SWITCH_IN, 0);
585 #endif
586             EXPECT_EQ(signer->ValidateCodeCopy(reinterpret_cast<Instr *>(g_jitMemory),
587                 reinterpret_cast<Byte *>(g_testInstructionSet), size), CS_SUCCESS);
588 #ifndef JIT_FORT_DISABLE
589             PrctlWrapper(JITFORT_PRCTL_OPTION, JITFORT_SWITCH_OUT, 0);
590 #endif
591             EXPECT_EQ(memcmp(g_jitMemory, g_testInstructionSet, size), 0);
592         }
593 
594         delete signer;
595         signer = nullptr;
596     }
597 }
598 
599 /**
600  * @tc.name: JitCodeSignTest_0016
601  * @tc.desc: validate and copy code to different buffer in parallel
602  * @tc.type: Func
603  * @tc.require: I9O6PK
604  */
605 HWTEST_F(JitCodeSignTest, JitCodeSignTest_00016, TestSize.Level0)
606 {
607     void *tmpMemory = nullptr;
608 #ifndef JIT_FORT_DISABLE
609     int cookie = std::random_device{}();
610     tmpMemory = mmap(nullptr, PAGE_SIZE,
611         PROT_READ | PROT_WRITE | PROT_EXEC,
612         MAP_ANONYMOUS | MAP_PRIVATE | MAP_JIT, cookie, 0);
613 #else
614     tmpMemory = mmap(nullptr, PAGE_SIZE,
615         PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
616 #endif
617     EXPECT_NE(tmpMemory, MAP_FAILED);
618     JitCodeSigner *signer = nullptr;
619     for (JitBufferIntegrityLevel level = MIN_LEVEL;
620         level <= MAX_LEVEL;
621         level = static_cast<JitBufferIntegrityLevel>(static_cast<int>(level) + 1)) {
622         signer = CreateJitCodeSigner();
623         int i = 0;
624         while (i < INSTRUCTIONS_SET_SIZE) {
625             AppendInstruction(signer, g_testInstructionSet[i]);
626             i++;
627         }
628         size_t size = INSTRUCTIONS_SET_SIZE_BYTES;
629         {
630 #ifndef JIT_FORT_DISABLE
631             PrctlWrapper(JITFORT_PRCTL_OPTION, JITFORT_SWITCH_IN, 0);
632 #endif
633             EXPECT_EQ(signer->ValidateCodeCopy(reinterpret_cast<Instr *>(tmpMemory),
634                 reinterpret_cast<Byte *>(g_testInstructionSet), size), CS_SUCCESS);
635 #ifndef JIT_FORT_DISABLE
636             PrctlWrapper(JITFORT_PRCTL_OPTION, JITFORT_SWITCH_OUT, 0);
637 #endif
638             EXPECT_EQ(memcmp(tmpMemory, g_testInstructionSet, size), 0);
639         }
640 
641         delete signer;
642         signer = nullptr;
643     }
644     munmap(tmpMemory, PAGE_SIZE);
645 }
646 
647 /**
648  * @tc.name: JitCodeSignTest_0017
649  * @tc.desc: validate and copy code to same buffer in parallel
650  * @tc.type: Func
651  * @tc.require: I9O6PK
652  */
653 HWMTEST_F(JitCodeSignTest, JitCodeSignTest_0017, TestSize.Level1, MULTI_THREAD_NUM)
654 {
655     int instructionNum = BUFFER_SIZE / sizeof(uint32_t);
656     uint32_t *tmpBuffer = reinterpret_cast<uint32_t *>(malloc(BUFFER_SIZE));
657     for (int i = 0; i < instructionNum; i++) {
658         tmpBuffer[i] = i;
659     }
660 
661     for (JitBufferIntegrityLevel level = MIN_LEVEL;
662         level <= MAX_LEVEL;
663         level = static_cast<JitBufferIntegrityLevel>(static_cast<int>(level) + 1)) {
664         JitCodeSigner *signer = CreateJitCodeSigner();
665         int i = 0;
666         while (i < instructionNum) {
667             AppendInstruction(signer, tmpBuffer[i]);
668             i++;
669         }
670         int cookie = std::random_device{}();
671         void *tmpJitMemory = mmap(nullptr, PAGE_SIZE,
672             PROT_READ | PROT_WRITE | PROT_EXEC,
673             MAP_ANONYMOUS | MAP_PRIVATE | MAP_JIT, cookie, 0);
674 
675         EXPECT_EQ(CopyToJitCode(signer, tmpJitMemory, tmpBuffer, BUFFER_SIZE), CS_SUCCESS);
676         EXPECT_EQ(memcmp(tmpJitMemory, tmpBuffer, BUFFER_SIZE), 0);
677 
678         delete signer;
679         signer = nullptr;
680     }
681     free(tmpBuffer);
682     tmpBuffer = nullptr;
683 }
684 
685 /**
686  * @tc.name: JitCodeSignTest_0018
687  * @tc.desc: no signer
688  * @tc.type: Func
689  * @tc.require: I9O6PK
690  */
691 HWTEST_F(JitCodeSignTest, JitCodeSignTest_0018, TestSize.Level0)
692 {
693     EXPECT_EQ(RegisterTmpBuffer(nullptr, nullptr), CS_ERR_NO_SIGNER);
694     EXPECT_EQ(AppendInstruction(nullptr, 0), CS_ERR_NO_SIGNER);
695     EXPECT_EQ(AppendData(nullptr, nullptr, 0), CS_ERR_NO_SIGNER);
696     EXPECT_EQ(WillFixUp(nullptr, 1), CS_ERR_NO_SIGNER);
697     EXPECT_EQ(PatchInstruction(nullptr, 0, 0), CS_ERR_NO_SIGNER);
698     EXPECT_EQ(PatchInstruction(nullptr, nullptr, 1), CS_ERR_NO_SIGNER);
699     EXPECT_EQ(PatchData(nullptr, 0, nullptr, 0), CS_ERR_NO_SIGNER);
700     EXPECT_EQ(PatchData(nullptr, nullptr, nullptr, 0), CS_ERR_NO_SIGNER);
701     EXPECT_EQ(CopyToJitCode(nullptr, nullptr, nullptr, 0), CS_ERR_JIT_MEMORY);
702 }
703 
704 /**
705  * @tc.name: JitCodeSignTest_0019
706  * @tc.desc: create failed
707  * @tc.type: Func
708  * @tc.require: I9O6PK
709  */
710 HWTEST_F(JitCodeSignTest, JitCodeSignTest_0019, TestSize.Level0)
711 {
712     EXPECT_NE(CreateJitCodeSigner(),
713         nullptr);
714 }
715 
716 /**
717  * @tc.name: JitCodeSignTest_0020
718  * @tc.desc: patch instruction failed for wrong offset or address
719  * @tc.type: Func
720  * @tc.require: I9O6PK
721  */
722 HWTEST_F(JitCodeSignTest, JitCodeSignTest_0020, TestSize.Level0)
723 {
724     JitCodeSigner *signer = nullptr;
725     for (JitBufferIntegrityLevel level = MIN_LEVEL;
726         level <= MAX_LEVEL; level = static_cast<JitBufferIntegrityLevel>(static_cast<int>(level) + 1)) {
727         signer = CreateJitCodeSigner();
728         AppendData(signer, g_testInstructionBuf, INSTRUCTIONS_SET_SIZE_BYTES);
729 
730         // offset is greater than signed size
731         EXPECT_EQ(PatchInstruction(signer, INSTRUCTIONS_SET_SIZE_BYTES + 4, 1), CS_ERR_PATCH_INVALID);
732         // offset < 0
733         EXPECT_EQ(PatchInstruction(signer, -INSTRUCTION_SIZE, 1), CS_ERR_PATCH_INVALID);
734 
735         // offset is greater than signed size
736         EXPECT_EQ(PatchInstruction(signer, CAST_VOID_PTR(reinterpret_cast<uintptr_t>(
737             g_testInstructionBuf) + INSTRUCTIONS_SET_SIZE_BYTES), 1), CS_ERR_PATCH_INVALID);
738         // offset < 0
739         EXPECT_EQ(PatchInstruction(signer, CAST_VOID_PTR(reinterpret_cast<uintptr_t>(
740             g_testInstructionBuf) - INSTRUCTION_SIZE), 1), CS_ERR_PATCH_INVALID);
741 
742         delete signer;
743         signer = nullptr;
744     }
745 }
746 
747 /**
748  * @tc.name: JitCodeSignTest_0021
749  * @tc.desc: append or patch data with nullptr failed
750  * @tc.type: Func
751  * @tc.require: I9O6PK
752  */
753 HWTEST_F(JitCodeSignTest, JitCodeSignTest_0021, TestSize.Level0)
754 {
755     JitCodeSigner *signer = nullptr;
756     for (JitBufferIntegrityLevel level = MIN_LEVEL;
757         level <= MAX_LEVEL; level = static_cast<JitBufferIntegrityLevel>(
758         static_cast<int>(level) + 1)) {
759         signer = CreateJitCodeSigner();
760         AppendData(signer, nullptr, INSTRUCTIONS_SET_SIZE_BYTES);
761 
762         AppendData(signer, g_testInstructionBuf, INSTRUCTIONS_SET_SIZE_BYTES);
763         EXPECT_EQ(PatchInstruction(signer, nullptr, 0), CS_ERR_PATCH_INVALID);
764         EXPECT_EQ(PatchData(signer, 0, nullptr, 0), CS_ERR_INVALID_DATA);
765 
766         RegisterTmpBuffer(signer, g_testInstructionBuf);
767         EXPECT_EQ(PatchData(signer, reinterpret_cast<Byte *>(g_testInstructionBuf),
768             nullptr, 0), CS_ERR_INVALID_DATA);
769 
770         delete signer;
771         signer = nullptr;
772     }
773 }
774 
775 /**
776  * @tc.name: JitCodeSignTest_0022
777  * @tc.desc: jit memory == nullptr
778  * @tc.type: Func
779  * @tc.require: I9O6PK
780  */
781 HWTEST_F(JitCodeSignTest, JitCodeSignTest_0022, TestSize.Level0)
782 {
783     JitCodeSigner *signer = nullptr;
784     for (JitBufferIntegrityLevel level = MIN_LEVEL;
785         level <= MAX_LEVEL; level = static_cast<JitBufferIntegrityLevel>(
786         static_cast<int>(level) + 1)) {
787         signer = CreateJitCodeSigner();
788         EXPECT_EQ(ResetJitCode(nullptr, 0), CS_ERR_JIT_MEMORY);
789         EXPECT_EQ(CopyToJitCode(signer, nullptr, g_testInstructionBuf, 0), CS_ERR_JIT_MEMORY);
790 
791         delete signer;
792         signer = nullptr;
793     }
794 }
795 
796 /**
797  * @tc.name: JitCodeSignTest_0023
798  * @tc.desc: sign instructions and verify succuss
799  * @tc.type: Func
800  * @tc.require: I9O6PK
801  */
802 HWTEST_F(JitCodeSignTest, JitCodeSignTest_0023, TestSize.Level0)
803 {
804     JitCodeSigner *signer = nullptr;
805     for (JitBufferIntegrityLevel level = MIN_LEVEL;
806         level <= MAX_LEVEL; level = static_cast<JitBufferIntegrityLevel>(
807         static_cast<int>(level) + 1)) {
808         signer = CreateJitCodeSigner();
809         for (int i = 0; i < INSTRUCTIONS_SET_SIZE_BYTES; i++) {
810             uint32_t tmpBuffer[INSTRUCTIONS_SET_SIZE];
811             (void) memcpy_s(tmpBuffer, INSTRUCTIONS_SET_SIZE_BYTES, g_testInstructionBuf, INSTRUCTIONS_SET_SIZE_BYTES);
812 
813             for (int j = 0; j < INSTRUCTIONS_SET_SIZE; j++) {
814                 AppendInstruction(signer, tmpBuffer[j]);
815             }
816             *(reinterpret_cast<Byte *>(tmpBuffer) + i) = 0;
817 
818             EXPECT_EQ(CopyToJitCode(signer, g_jitMemory, tmpBuffer,
819                 INSTRUCTIONS_SET_SIZE_BYTES), CS_ERR_VALIDATE_CODE);
820         }
821 
822         delete signer;
823         signer = nullptr;
824     }
825 }
826 
827 /**
828  * @tc.name: JitCodeSignTest_0024
829  * @tc.desc: pac sign with auth
830  * @tc.type: Func
831  * @tc.require: IAKH9D
832  */
833 HWTEST_F(JitCodeSignTest, JitCodeSignTest_0024, TestSize.Level0)
834 {
835     PACSignCtx signCtx(CTXPurpose::SIGN);
836     signCtx.InitSalt();
837     signCtx.Init(0);
838     uint32_t signature[INSTRUCTIONS_SET_SIZE];
839     int i;
840     for (i = 0; i < INSTRUCTIONS_SET_SIZE; i++) {
841         signature[i] = signCtx.Update(g_testInstructionSet[i]);
842     }
843     PACSignCtx verifyCtx(CTXPurpose::VERIFY, signCtx.GetSalt());
844     verifyCtx.Init(0);
845     for (i = 0; i < INSTRUCTIONS_SET_SIZE; i++) {
846         EXPECT_EQ(signature[i], verifyCtx.Update(g_testInstructionSet[i]));
847     }
848 }
849 }
850 }
851 }
852