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 "gethighestseclevelasync_fuzzer.h"
17
18#include <cstddef>
19#include <cstdint>
20#include <mutex>
21#include <thread>
22
23#include "file_ex.h"
24#include "securec.h"
25#include "nativetoken_kit.h"
26#include "token_setproc.h"
27#include "accesstoken_kit.h"
28#include "dev_slinfo_mgr.h"
29
30#define DELAY_TIME 3000
31
32namespace OHOS {
33static bool g_isForcingFuzz1 = false;
34
35static void NativeTokenGetFuzz1(void)
36{
37    uint64_t tokenId1;
38    const char **permsFuzz1 = new const char *[1];
39    permsFuzz1[0] = "ohos.permission.DISTRIBUTED_DATASYNC";
40    NativeTokenInfoParams infoInstanceFuzz1 = {
41        .dcapsNum = 0,
42        .permsNum = 1,
43        .aclsNum = 0,
44        .dcaps = nullptr,
45        .perms = permsFuzz1,
46        .acls = nullptr,
47        .aplStr = "system_basic",
48    };
49
50    infoInstanceFuzz1.processName = "DevSLMgrTest";
51    tokenId1 = GetAccessTokenId(&infoInstanceFuzz1);
52    SetSelfTokenID(tokenId1);
53    OHOS::Security::AccessToken::AccessTokenKit::ReloadNativeTokenInfo();
54    delete[] permsFuzz1;
55}
56
57static void BeginFuzzCase1(void)
58{
59    std::string isEnforcing;
60    OHOS::LoadStringFromFile("/sys/fs/selinux/enforce", isEnforcing);
61    if (isEnforcing.compare("1") == 0) {
62        g_isForcingFuzz1 = true;
63        OHOS::SaveStringToFile("/sys/fs/selinux/enforce", "0");
64    }
65    NativeTokenGetFuzz1();
66}
67
68static void EndFuzzCase1(void)
69{
70    if (g_isForcingFuzz1) {
71        OHOS::SaveStringToFile("/sys/fs/selinux/enforce", "1");
72    }
73}
74
75static int32_t g_cnt = 0;
76static std::mutex g_mtx;
77static std::condition_variable g_cv;
78
79static void tmpCallbackFuzz1(DEVSLQueryParams *queryParams, int32_t result, uint32_t levelInfo)
80{
81    g_cnt++;
82    (void)queryParams;
83    (void)result;
84    (void)levelInfo;
85    return;
86}
87
88void FuzzDoGetHighestSecLevelAsync(const uint8_t *data, size_t size)
89{
90    if (data == nullptr || size <= MAX_UDID_LENGTH) {
91        return;
92    }
93
94    DEVSLQueryParams queryParams;
95    (void)memset_s(&queryParams, sizeof(DEVSLQueryParams), 0, sizeof(DEVSLQueryParams));
96    queryParams.udidLen = MAX_UDID_LENGTH;
97    (void)memcpy_s(queryParams.udid, MAX_UDID_LENGTH, data, MAX_UDID_LENGTH);
98    BeginFuzzCase1();
99    (void)DATASL_OnStart();
100    (void)DATASL_GetHighestSecLevelAsync(&queryParams, tmpCallbackFuzz1);
101    (void)DATASL_GetHighestSecLevelAsync(nullptr, tmpCallbackFuzz1);
102    (void)DATASL_GetHighestSecLevelAsync(&queryParams, nullptr);
103
104    std::unique_lock<std::mutex> lck(g_mtx);
105    g_cv.wait_for(lck, std::chrono::milliseconds(DELAY_TIME), []() { return (g_cnt == 1); });
106    DATASL_OnStop();
107    EndFuzzCase1();
108}
109}
110
111/* Fuzzer entry point */
112extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
113{
114    /* Run your code on data */
115    OHOS::FuzzDoGetHighestSecLevelAsync(data, size);
116    return 0;
117}