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