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