1 /*
2  * Copyright (c) 2022 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 "systemabilitymanager_fuzzer.h"
17 
18 #include "if_system_ability_manager.h"
19 #include "sam_mock_permission.h"
20 #include "system_ability_manager.h"
21 #include "iservice_registry.h"
22 #include "hisysevent_adapter.h"
23 
24 #include <cinttypes>
25 #include <cstddef>
26 #include <cstdint>
27 #include <unistd.h>
28 #include <cstdlib>
29 #include <fcntl.h>
30 
31 namespace OHOS {
32 namespace Samgr {
33 namespace {
34     constexpr size_t THRESHOLD = 10;
35     constexpr uint8_t MAX_CALL_TRANSACTION = 40;
36     constexpr int32_t OFFSET = 4;
37     constexpr int32_t INIT_TIME = 3;
38     constexpr int32_t RETRY_TIME_OUT_NUMBER = 10;
39     constexpr int32_t SLEEP_INTERVAL_TIME = 200000;
40     constexpr int32_t DISTRIBUTED_HARDWARE_DEVICEMANAGER_SA_ID = 4802;
41     constexpr uint8_t SEAT_ZERO = 0;
42     constexpr uint8_t LIFT_OFFSET_ZERO = 24;
43     constexpr uint8_t SEAT_ONE = 1;
44     constexpr uint8_t LIFT_OFFSET_ONE = 16;
45     constexpr uint8_t SEAT_TWO = 2;
46     constexpr uint8_t LIFT_OFFSET_TWO = 8;
47     constexpr uint8_t SEAT_THREE = 3;
48     constexpr int64_t DURATION = 1;
49     unsigned int g_dumpLevel = 0;
50     const std::u16string SAMGR_INTERFACE_TOKEN = u"ohos.samgr.accessToken";
51     bool g_flag = false;
52 }
53 
Convert2Uint32(const uint8_t * ptr)54 uint32_t Convert2Uint32(const uint8_t* ptr)
55 {
56     if (ptr == nullptr) {
57         return 0;
58     }
59     return (ptr[SEAT_ZERO] << LIFT_OFFSET_ZERO) | (ptr[SEAT_ONE] << LIFT_OFFSET_ONE) |
60         (ptr[SEAT_TWO] << LIFT_OFFSET_TWO) | (ptr[SEAT_THREE]); // this is a general method of converting in fuzz
61 }
62 
IsDmReady()63 bool IsDmReady()
64 {
65     auto dmProxy = SystemAbilityManager::GetInstance()->CheckSystemAbility(
66         DISTRIBUTED_HARDWARE_DEVICEMANAGER_SA_ID);
67     if (dmProxy != nullptr) {
68         IPCObjectProxy* proxy = reinterpret_cast<IPCObjectProxy*>(dmProxy.GetRefPtr());
69         if (proxy != nullptr && !proxy->IsObjectDead()) {
70             return true;
71         }
72     }
73     HILOGE("samgrFuzz:DM isn't ready");
74     return false;
75 }
76 
AddDeviceManager()77 void AddDeviceManager()
78 {
79     if (IsDmReady()) {
80         return;
81     }
82     sptr<ISystemAbilityManager> sm = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
83     if (sm == nullptr) {
84         HILOGE("samgrFuzz:GetSystemAbilityManager fail");
85         return;
86     }
87     int32_t timeout = RETRY_TIME_OUT_NUMBER;
88     int64_t begin = OHOS::GetTickCount();
89     sptr<IRemoteObject> dmAbility = nullptr;
90     do {
91         dmAbility = sm->CheckSystemAbility(DISTRIBUTED_HARDWARE_DEVICEMANAGER_SA_ID);
92         if (dmAbility != nullptr) {
93             break;
94         }
95         usleep(SLEEP_INTERVAL_TIME);
96     } while (timeout--);
97     HILOGI("samgrFuzz:Add DM spend %{public}" PRId64 " ms", OHOS::GetTickCount() - begin);
98     if (dmAbility == nullptr) {
99         HILOGE("samgrFuzz:dmAbility is null");
100         return;
101     }
102     sptr<SystemAbilityManager> fuzzSAManager = SystemAbilityManager::GetInstance();
103     ISystemAbilityManager::SAExtraProp saExtra(false, g_dumpLevel, u"", u"");
104     int32_t ret = fuzzSAManager->AddSystemAbility(DISTRIBUTED_HARDWARE_DEVICEMANAGER_SA_ID, dmAbility, saExtra);
105     if (ret == ERR_OK) {
106         HILOGI("samgrFuzz:Add DM sucess");
107         return;
108     }
109     HILOGE("samgrFuzz:Add DM fail");
110 }
111 
FuzzSystemAbilityManager(const uint8_t * rawData,size_t size)112 void FuzzSystemAbilityManager(const uint8_t* rawData, size_t size)
113 {
114     SamMockPermission::MockPermission();
115     uint32_t code = Convert2Uint32(rawData);
116     rawData = rawData + OFFSET;
117     size = size - OFFSET;
118     MessageParcel data;
119     data.WriteInterfaceToken(SAMGR_INTERFACE_TOKEN);
120     data.WriteBuffer(rawData, size);
121     data.RewindRead(0);
122     MessageParcel reply;
123     MessageOption option;
124     sptr<SystemAbilityManager> manager = SystemAbilityManager::GetInstance();
125     if (!g_flag) {
126         HILOGI("samgrFuzz:Init");
127         manager->Init();
128         g_flag = true;
129         HILOGI("samgrFuzz:Init AddDeviceManager");
130         AddDeviceManager();
131         sleep(INIT_TIME);
132         if (!IsDmReady()) {
133             HILOGE("samgrFuzz:Init CleanFfrt");
134             manager->CleanFfrt();
135             return;
136         }
137     } else {
138         HILOGI("samgrFuzz:AddDeviceManager");
139         AddDeviceManager();
140         if (!IsDmReady()) {
141             HILOGE("samgrFuzz:dm no ready,return");
142             return;
143         }
144         HILOGI("samgrFuzz:SetFfrt");
145         manager->SetFfrt();
146     }
147     HILOGI("samgrFuzz:code=%{public}u", code % MAX_CALL_TRANSACTION);
148     manager->OnRemoteRequest(code % MAX_CALL_TRANSACTION, data, reply, option);
149     HILOGI("samgrFuzz:OnRemoteRequest end,CleanFfrt");
150     manager->CleanFfrt();
151 }
152 }
153 }
154 
155 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)156 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
157 {
158     if (size < OHOS::Samgr::THRESHOLD) {
159         return 0;
160     }
161 
162     OHOS::Samgr::FuzzSystemAbilityManager(data, size);
163 
164     return 0;
165 }
166 
167