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