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