• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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