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
33namespace OHOS {
34namespace Security {
35namespace CodeSign {
36using namespace std;
37using namespace testing::ext;
38using namespace testing::mt;
39
40#define CAST_VOID_PTR(buffer) (reinterpret_cast<void *>(buffer))
41
42static Instr g_testInstructionSet[] = {
43    0x11111111,
44    0x22222222,
45    0x33333333, // patched -> 0x66666666
46    0x44444444, // patched -> 0x77777777
47    0x55555555
48};
49
50static Instr g_afterPatchInstructionSet[] = {
51    0x11111111,
52    0x22222222,
53    0x66666666,
54    0x77777777,
55    0x55555555
56};
57
58static Instr g_testPatchInstructionSet[] = {
59    0x66666666,
60    0x77777777
61};
62
63static constexpr uint32_t MULTI_THREAD_NUM = 10;
64static constexpr int INSTRUCTIONS_SET_SIZE =
65    sizeof(g_testInstructionSet) / sizeof(g_testInstructionSet[0]);
66static constexpr int INSTRUCTIONS_SET_SIZE_BYTES = sizeof(g_testInstructionSet);
67static constexpr int TEST_PATCH_INDEX = 2;
68
69static constexpr int PATCH_INSTRUCTIONS_SET_SIZE =
70    sizeof(g_testPatchInstructionSet) / sizeof(g_testPatchInstructionSet[0]);
71
72static void *g_testInstructionBuf = CAST_VOID_PTR(g_testInstructionSet);
73static void *g_afterPatchInstructionBuf = CAST_VOID_PTR(g_afterPatchInstructionSet);
74static void *g_testPatchInstructionBuf = CAST_VOID_PTR(g_testPatchInstructionSet);
75static void *g_jitMemory = nullptr;
76
77void *g_mapJitBase = CAST_VOID_PTR(0x800000000);
78void *g_mapJitBase2 = CAST_VOID_PTR(0x800001000);
79constexpr size_t PAGE_SIZE = 4096;
80constexpr int BUFFER_SIZE = 4096;
81
82#define JITFORT_PRCTL_OPTION 0x6a6974
83#define JITFORT_CREATE_COPGTABLE    5
84#define MAP_JIT 0x1000
85
86const JitBufferIntegrityLevel MIN_LEVEL = JitBufferIntegrityLevel::Level0;
87const JitBufferIntegrityLevel MAX_LEVEL = JitBufferIntegrityLevel::Level1;
88
89std::mutex g_jitMemory_mutex;
90
91static 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
104static 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
112static 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
120class JitCodeSignTest : public testing::Test {
121public:
122    JitCodeSignTest() {};
123    virtual ~JitCodeSignTest() {};
124
125    static void SetUpTestCase()
126    {
127        EXPECT_EQ(IsSupportJitCodeSigner(), true);
128        JitFortPrepare();
129        AllocJitMemory();
130    };
131
132    static void TearDownTestCase()
133    {
134        FreeJitMemory();
135    };
136
137    void SetUp() {};
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 */
147HWTEST_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 */
175HWTEST_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 */
198HWTEST_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 */
240HWTEST_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 */
289HWTEST_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 */
312HWTEST_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 */
336HWTEST_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 */
360HWTEST_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 */
385HWTEST_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 */
425HWTEST_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 */
469HWTEST_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 */
495HWTEST_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 */
508HWTEST_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 */
534HWTEST_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 */
564HWMTEST_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 */
601HWTEST_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 */
649HWMTEST_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 */
687HWTEST_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 */
706HWTEST_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 */
719HWTEST_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 */
750HWTEST_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 */
778HWTEST_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 */
799HWTEST_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 */
830HWTEST_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