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 #include "daemonstub_fuzzer.h"
16 
17 #include <cstddef>
18 #include <cstdint>
19 #include <cstring>
20 #include <string>
21 
22 #include "daemon_stub.h"
23 #include "distributed_file_daemon_ipc_interface_code.h"
24 #include "ipc_skeleton.h"
25 #include "message_option.h"
26 #include "message_parcel.h"
27 #include "securec.h"
28 #include "accesstoken_kit.h"
29 #include "utils_log.h"
30 #include "nativetoken_kit.h"
31 #include "token_setproc.h"
32 
33 namespace OHOS {
34 constexpr pid_t DATA_UID = 3012;
35 constexpr pid_t DAEMON_UID = 1009;
36 static pid_t UID = DAEMON_UID;
37 #ifdef CONFIG_IPC_SINGLE
38 using namespace IPC_SINGLE;
39 #endif
GetCallingUid()40 pid_t IPCSkeleton::GetCallingUid()
41 {
42     return UID;
43 }
44 }
45 
46 namespace OHOS {
47 
48 constexpr size_t FOO_MAX_LEN = 1024;
49 constexpr size_t U32_AT_SIZE = 4;
50 
51 using namespace OHOS::Storage::DistributedFile;
52 
53 class DaemonStubImpl : public DaemonStub {
54 public:
55     DaemonStubImpl() = default;
~DaemonStubImpl()56     ~DaemonStubImpl() override {}
OpenP2PConnection(const DistributedHardware::DmDeviceInfo & deviceInfo)57     int32_t OpenP2PConnection(const DistributedHardware::DmDeviceInfo &deviceInfo) override
58     {
59         return 0;
60     }
61 
CloseP2PConnection(const DistributedHardware::DmDeviceInfo & deviceInfo)62     int32_t CloseP2PConnection(const DistributedHardware::DmDeviceInfo &deviceInfo) override
63     {
64         return 0;
65     }
66 
OpenP2PConnectionEx(const std::string & networkId,sptr<IFileDfsListener> remoteReverseObj)67     int32_t OpenP2PConnectionEx(const std::string &networkId, sptr<IFileDfsListener> remoteReverseObj) override
68     {
69         return 0;
70     }
71 
CloseP2PConnectionEx(const std::string & networkId)72     int32_t CloseP2PConnectionEx(const std::string &networkId) override
73     {
74         return 0;
75     }
76 
PrepareSession(const std::string & srcUri,const std::string & dstUri,const std::string & srcDeviceId,const sptr<IRemoteObject> & listener,HmdfsInfo & info)77     int32_t PrepareSession(const std::string &srcUri,
78                            const std::string &dstUri,
79                            const std::string &srcDeviceId,
80                            const sptr<IRemoteObject> &listener,
81                            HmdfsInfo &info) override
82     {
83         return 0;
84     }
85 
CancelCopyTask(const std::string & sessionName)86     int32_t CancelCopyTask(const std::string &sessionName) override
87     {
88         return 0;
89     }
90 
RequestSendFile(const std::string & srcUri,const std::string & dstPath,const std::string & remoteDeviceId,const std::string & sessionName)91     int32_t RequestSendFile(const std::string &srcUri,
92                             const std::string &dstPath,
93                             const std::string &remoteDeviceId,
94                             const std::string &sessionName) override
95     {
96         return 0;
97     }
98 
GetRemoteCopyInfo(const std::string & srcUri,bool & isFile,bool & isDir)99     int32_t GetRemoteCopyInfo(const std::string &srcUri, bool &isFile, bool &isDir) override
100     {
101         return 0;
102     }
103 
PushAsset(int32_t userId,const sptr<AssetObj> & assetObj,const sptr<IAssetSendCallback> & sendCallback)104     int32_t PushAsset(int32_t userId,
105                       const sptr<AssetObj> &assetObj,
106                       const sptr<IAssetSendCallback> &sendCallback) override
107     {
108         return 0;
109     }
110 
RegisterAssetCallback(const sptr<IAssetRecvCallback> & recvCallback)111     int32_t RegisterAssetCallback(const sptr<IAssetRecvCallback> &recvCallback) override
112     {
113         return 0;
114     }
115 
UnRegisterAssetCallback(const sptr<IAssetRecvCallback> & recvCallback)116     int32_t UnRegisterAssetCallback(const sptr<IAssetRecvCallback> &recvCallback) override
117     {
118         return 0;
119     }
120 };
121 
HandleOpenP2PConnectionFuzzTest(std::shared_ptr<DaemonStub> daemonStubPtr,const uint8_t * data,size_t size)122 void HandleOpenP2PConnectionFuzzTest(std::shared_ptr<DaemonStub> daemonStubPtr,
123                                      const uint8_t *data,
124                                      size_t size)
125 {
126     uint32_t code = static_cast<uint32_t>(DistributedFileDaemonInterfaceCode::DISTRIBUTED_FILE_OPEN_P2P_CONNECTION);
127     MessageParcel datas;
128     datas.WriteInterfaceToken(DaemonStub::GetDescriptor());
129     datas.WriteBuffer(data, size);
130     datas.RewindRead(0);
131     MessageParcel reply;
132     MessageOption option;
133 
134     daemonStubPtr->OnRemoteRequest(code, datas, reply, option);
135 }
136 
HandleCloseP2PConnectionFuzzTest(std::shared_ptr<DaemonStub> daemonStubPtr,const uint8_t * data,size_t size)137 void HandleCloseP2PConnectionFuzzTest(std::shared_ptr<DaemonStub> daemonStubPtr,
138                                       const uint8_t *data,
139                                       size_t size)
140 {
141     uint32_t code = static_cast<uint32_t>(DistributedFileDaemonInterfaceCode::DISTRIBUTED_FILE_CLOSE_P2P_CONNECTION);
142     MessageParcel datas;
143     datas.WriteInterfaceToken(DaemonStub::GetDescriptor());
144     datas.WriteBuffer(data, size);
145     datas.RewindRead(0);
146     MessageParcel reply;
147     MessageOption option;
148 
149     daemonStubPtr->OnRemoteRequest(code, datas, reply, option);
150 }
151 
HandleOpenP2PConnectionExFuzzTest(std::shared_ptr<DaemonStub> daemonStubPtr,const uint8_t * data,size_t size)152 void HandleOpenP2PConnectionExFuzzTest(std::shared_ptr<DaemonStub> daemonStubPtr,
153                                        const uint8_t *data,
154                                        size_t size)
155 {
156     uint32_t code = static_cast<uint32_t>(DistributedFileDaemonInterfaceCode::DISTRIBUTED_FILE_OPEN_P2P_CONNECTION_EX);
157     MessageParcel datas;
158     datas.WriteInterfaceToken(DaemonStub::GetDescriptor());
159     datas.WriteBuffer(data, size);
160     datas.RewindRead(0);
161     MessageParcel reply;
162     MessageOption option;
163 
164     daemonStubPtr->OnRemoteRequest(code, datas, reply, option);
165 }
166 
HandleCloseP2PConnectionExFuzzTest(std::shared_ptr<DaemonStub> daemonStubPtr,const uint8_t * data,size_t size)167 void HandleCloseP2PConnectionExFuzzTest(std::shared_ptr<DaemonStub> daemonStubPtr,
168                                         const uint8_t *data,
169                                         size_t size)
170 {
171     uint32_t code = static_cast<uint32_t>(DistributedFileDaemonInterfaceCode::DISTRIBUTED_FILE_CLOSE_P2P_CONNECTION_EX);
172     MessageParcel datas;
173     datas.WriteInterfaceToken(DaemonStub::GetDescriptor());
174     datas.WriteBuffer(data, size);
175     datas.RewindRead(0);
176     MessageParcel reply;
177     MessageOption option;
178 
179     daemonStubPtr->OnRemoteRequest(code, datas, reply, option);
180 }
181 
HandlePrepareSessionFuzzTest(std::shared_ptr<DaemonStub> daemonStubPtr,const uint8_t * data,size_t size)182 void HandlePrepareSessionFuzzTest(std::shared_ptr<DaemonStub> daemonStubPtr, const uint8_t *data, size_t size)
183 {
184     uint32_t code = static_cast<uint32_t>(DistributedFileDaemonInterfaceCode::DISTRIBUTED_FILE_PREPARE_SESSION);
185     MessageParcel datas;
186     datas.WriteInterfaceToken(DaemonStub::GetDescriptor());
187     datas.WriteBuffer(data, size);
188     datas.RewindRead(0);
189     MessageParcel reply;
190     MessageOption option;
191 
192     daemonStubPtr->OnRemoteRequest(code, datas, reply, option);
193 }
194 
HandleCancelCopyTaskFuzzTest(std::shared_ptr<DaemonStub> daemonStubPtr,const uint8_t * data,size_t size)195 void HandleCancelCopyTaskFuzzTest(std::shared_ptr<DaemonStub> daemonStubPtr, const uint8_t *data, size_t size)
196 {
197     uint32_t code = static_cast<uint32_t>(DistributedFileDaemonInterfaceCode::DISTRIBUTED_FILE_CANCEL_COPY_TASK);
198     MessageParcel datas;
199     datas.WriteInterfaceToken(DaemonStub::GetDescriptor());
200     datas.WriteBuffer(data, size);
201     datas.RewindRead(0);
202     MessageParcel reply;
203     MessageOption option;
204 
205     daemonStubPtr->OnRemoteRequest(code, datas, reply, option);
206 }
207 
HandleRequestSendFileFuzzTest(std::shared_ptr<DaemonStub> daemonStubPtr,const uint8_t * data,size_t size)208 void HandleRequestSendFileFuzzTest(std::shared_ptr<DaemonStub> daemonStubPtr,
209                                    const uint8_t *data,
210                                    size_t size)
211 {
212     OHOS::UID = DAEMON_UID;
213     uint32_t code = static_cast<uint32_t>(DistributedFileDaemonInterfaceCode::DISTRIBUTED_FILE_REQUEST_SEND_FILE);
214     MessageParcel datas;
215     datas.WriteInterfaceToken(DaemonStub::GetDescriptor());
216     datas.WriteBuffer(data, size);
217     datas.RewindRead(0);
218     MessageParcel reply;
219     MessageOption option;
220 
221     daemonStubPtr->OnRemoteRequest(code, datas, reply, option);
222 }
223 
HandleGetRemoteCopyInfoFuzzTest(std::shared_ptr<DaemonStub> daemonStubPtr,const uint8_t * data,size_t size)224 void HandleGetRemoteCopyInfoFuzzTest(std::shared_ptr<DaemonStub> daemonStubPtr,
225                                      const uint8_t *data,
226                                      size_t size)
227 {
228     OHOS::UID = DAEMON_UID;
229     uint32_t code = static_cast<uint32_t>(DistributedFileDaemonInterfaceCode::DISTRIBUTED_FILE_GET_REMOTE_COPY_INFO);
230     MessageParcel datas;
231     datas.WriteInterfaceToken(DaemonStub::GetDescriptor());
232     datas.WriteBuffer(data, size);
233     datas.RewindRead(0);
234     MessageParcel reply;
235     MessageOption option;
236 
237     daemonStubPtr->OnRemoteRequest(code, datas, reply, option);
238 }
239 
HandlePushAssetFuzzTest(std::shared_ptr<DaemonStub> daemonStubPtr,const uint8_t * data,size_t size)240 void HandlePushAssetFuzzTest(std::shared_ptr<DaemonStub> daemonStubPtr, const uint8_t *data, size_t size)
241 {
242     OHOS::UID = DATA_UID;
243     uint32_t code = static_cast<uint32_t>(DistributedFileDaemonInterfaceCode::DISTRIBUTED_FILE_PUSH_ASSET);
244     MessageParcel datas;
245     datas.WriteInterfaceToken(DaemonStub::GetDescriptor());
246     datas.WriteBuffer(data, size);
247     datas.RewindRead(0);
248     MessageParcel reply;
249     MessageOption option;
250 
251     daemonStubPtr->OnRemoteRequest(code, datas, reply, option);
252 }
253 
HandleRegisterRecvCallbackFuzzTest(std::shared_ptr<DaemonStub> daemonStubPtr,const uint8_t * data,size_t size)254 void HandleRegisterRecvCallbackFuzzTest(std::shared_ptr<DaemonStub> daemonStubPtr,
255                                         const uint8_t *data,
256                                         size_t size)
257 {
258     OHOS::UID = DATA_UID;
259     uint32_t code = static_cast<uint32_t>(DistributedFileDaemonInterfaceCode::DISTRIBUTED_FILE_REGISTER_ASSET_CALLBACK);
260     MessageParcel datas;
261     datas.WriteInterfaceToken(DaemonStub::GetDescriptor());
262     datas.WriteBuffer(data, size);
263     datas.RewindRead(0);
264     MessageParcel reply;
265     MessageOption option;
266 
267     daemonStubPtr->OnRemoteRequest(code, datas, reply, option);
268 }
269 
HandleUnRegisterRecvCallbackFuzzTest(std::shared_ptr<DaemonStub> daemonStubPtr,const uint8_t * data,size_t size)270 void HandleUnRegisterRecvCallbackFuzzTest(std::shared_ptr<DaemonStub> daemonStubPtr,
271                                           const uint8_t *data,
272                                           size_t size)
273 {
274     OHOS::UID = DATA_UID;
275     uint32_t code =
276         static_cast<uint32_t>(DistributedFileDaemonInterfaceCode::DISTRIBUTED_FILE_UN_REGISTER_ASSET_CALLBACK);
277     MessageParcel datas;
278     datas.WriteInterfaceToken(DaemonStub::GetDescriptor());
279     datas.WriteBuffer(data, size);
280     datas.RewindRead(0);
281     MessageParcel reply;
282     MessageOption option;
283 
284     daemonStubPtr->OnRemoteRequest(code, datas, reply, option);
285 }
286 
SetAccessTokenPermission()287 void SetAccessTokenPermission()
288 {
289     uint64_t tokenId;
290     const char *perms[1];
291     perms[0] = "ohos.permission.DISTRIBUTED_DATASYNC";
292 
293     NativeTokenInfoParams infoInstance = {
294         .dcapsNum = 0,
295         .permsNum = 1,
296         .aclsNum = 0,
297         .dcaps = nullptr,
298         .perms = perms,
299         .acls = nullptr,
300         .processName = "distributdFileDaemonstubFuzzer",
301         .aplStr = "system_basic",
302     };
303     tokenId = GetAccessTokenId(&infoInstance);
304     if (tokenId == 0) {
305         LOGE("Get Acess Token Id Failed");
306         return;
307     }
308     int ret = SetSelfTokenID(tokenId);
309     if (ret != 0) {
310         LOGE("Set Acess Token Id Failed");
311         return;
312     }
313     ret = Security::AccessToken::AccessTokenKit::ReloadNativeTokenInfo();
314     if (ret < 0) {
315         LOGE("Reload Native Token Info Failed");
316         return;
317     }
318 }
319 } // namespace OHOS
320 
321 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)322 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
323 {
324     /* Run your code on data */
325     if (data == nullptr) {
326         return 0;
327     }
328 
329     /* Validate the length of size */
330     if (size < OHOS::U32_AT_SIZE || size > OHOS::FOO_MAX_LEN) {
331         return 0;
332     }
333     OHOS::SetAccessTokenPermission();
334     auto daemonStubPtr = std::make_shared<OHOS::DaemonStubImpl>();
335     OHOS::HandleOpenP2PConnectionFuzzTest(daemonStubPtr, data, size);
336     OHOS::HandleCloseP2PConnectionFuzzTest(daemonStubPtr, data, size);
337     OHOS::HandlePrepareSessionFuzzTest(daemonStubPtr, data, size);
338     OHOS::HandleRequestSendFileFuzzTest(daemonStubPtr, data, size);
339     OHOS::HandleOpenP2PConnectionExFuzzTest(daemonStubPtr, data, size);
340     OHOS::HandleCloseP2PConnectionExFuzzTest(daemonStubPtr, data, size);
341     OHOS::HandleCancelCopyTaskFuzzTest(daemonStubPtr, data, size);
342     OHOS::HandleGetRemoteCopyInfoFuzzTest(daemonStubPtr, data, size);
343     OHOS::HandlePushAssetFuzzTest(daemonStubPtr, data, size);
344     OHOS::HandleRegisterRecvCallbackFuzzTest(daemonStubPtr, data, size);
345     OHOS::HandleUnRegisterRecvCallbackFuzzTest(daemonStubPtr, data, size);
346     return 0;
347 }
348