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