1 /*
2  * Copyright (c) 2022-2023 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 "pasteboardservice_fuzzer.h"
17 
18 #include <cstddef>
19 #include <cstdint>
20 #include <map>
21 
22 #include "copy_uri_handler.h"
23 #include "i_pasteboard_service.h"
24 #include "message_parcel.h"
25 #include "paste_data.h"
26 #include "pasteboard_service.h"
27 #include "pasteboard_serv_ipc_interface_code.h"
28 
29 using namespace OHOS::Security::PasteboardServ;
30 using namespace OHOS::MiscServices;
31 using namespace std;
32 
33 namespace OHOS {
34 constexpr size_t THRESHOLD = 10;
35 constexpr int32_t OFFSET = 4;
36 const int32_t SHAREOPTIONSIZE = 3;
37 const std::u16string PASTEBOARDSERVICE_INTERFACE_TOKEN = u"ohos.miscservices.pasteboard.IPasteboardService";
38 
ConvertToUint32(const uint8_t * ptr)39 uint32_t ConvertToUint32(const uint8_t *ptr)
40 {
41     if (ptr == nullptr) {
42         return 0;
43     }
44     uint32_t bigVar = (ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | (ptr[3]);
45     return bigVar;
46 }
47 
48 template<class T>
TypeCast(const uint8_t * data,int * pos=nullptr)49 T TypeCast(const uint8_t *data, int *pos = nullptr)
50 {
51     if (pos) {
52         *pos += sizeof(T);
53     }
54     return *(reinterpret_cast<const T*>(data));
55 }
56 
FuzzPasteboardService(const uint8_t * rawData,size_t size)57 bool FuzzPasteboardService(const uint8_t *rawData, size_t size)
58 {
59     uint32_t code = ConvertToUint32(rawData);
60     rawData = rawData + OFFSET;
61     size = size - OFFSET;
62 
63     MessageParcel data;
64     data.WriteInterfaceToken(PASTEBOARDSERVICE_INTERFACE_TOKEN);
65     data.WriteInt32(size);
66     data.WriteBuffer(rawData, size);
67     data.RewindRead(0);
68     MessageParcel reply;
69     MessageOption option;
70 
71     std::make_shared<PasteboardService>()->OnRemoteRequest(code, data, reply, option);
72 
73     return true;
74 }
75 
FuzzPasteboardServiceOnSetPasteData(const uint8_t * rawData,size_t size)76 bool FuzzPasteboardServiceOnSetPasteData(const uint8_t *rawData, size_t size)
77 {
78     rawData = rawData + OFFSET;
79     size = size - OFFSET;
80 
81     MessageParcel data;
82     data.WriteInterfaceToken(PASTEBOARDSERVICE_INTERFACE_TOKEN);
83     data.WriteInt32(size);
84     data.WriteBuffer(rawData, size);
85     data.RewindRead(0);
86     MessageParcel reply;
87     MessageOption option;
88 
89     std::make_shared<PasteboardService>()->OnRemoteRequest(
90         static_cast<uint32_t>(PasteboardServiceInterfaceCode::SET_PASTE_DATA), data, reply, option);
91 
92     MessageParcel source;
93     data.RewindRead(0);
94     std::make_shared<PasteboardService>()->OnRemoteRequest(
95         static_cast<uint32_t>(PasteboardServiceInterfaceCode::HAS_PASTE_DATA), source, reply, option);
96     data.RewindRead(0);
97     std::make_shared<PasteboardService>()->OnRemoteRequest(
98         static_cast<uint32_t>(PasteboardServiceInterfaceCode::GET_PASTE_DATA), source, reply, option);
99     return true;
100 }
101 
FuzzPasteboardServiceOnClearPasteData(const uint8_t * rawData,size_t size)102 bool FuzzPasteboardServiceOnClearPasteData(const uint8_t *rawData, size_t size)
103 {
104     MessageParcel data;
105     data.WriteInterfaceToken(PASTEBOARDSERVICE_INTERFACE_TOKEN);
106     MessageParcel reply;
107     MessageOption option;
108     std::make_shared<PasteboardService>()->OnRemoteRequest(
109         static_cast<uint32_t>(PasteboardServiceInterfaceCode::CLEAR_ALL), data, reply, option);
110     return true;
111 }
112 
FuzzPasteOnIsRemoteData(const uint8_t * rawData,size_t size)113 bool FuzzPasteOnIsRemoteData(const uint8_t *rawData, size_t size)
114 {
115     rawData = rawData + OFFSET;
116     size = size - OFFSET;
117 
118     MessageParcel data;
119     data.WriteInterfaceToken(PASTEBOARDSERVICE_INTERFACE_TOKEN);
120     data.WriteInt32(size);
121     data.WriteBuffer(rawData, size);
122     data.RewindRead(0);
123     MessageParcel reply;
124     MessageOption option;
125 
126     std::make_shared<PasteboardService>()->OnRemoteRequest(
127         static_cast<uint32_t>(PasteboardServiceInterfaceCode::IS_REMOTE_DATA), data, reply, option);
128     data.RewindRead(0);
129     std::make_shared<PasteboardService>()->OnRemoteRequest(
130         static_cast<uint32_t>(PasteboardServiceInterfaceCode::GET_DATA_SOURCE), data, reply, option);
131     data.RewindRead(0);
132     std::make_shared<PasteboardService>()->OnRemoteRequest(
133         static_cast<uint32_t>(PasteboardServiceInterfaceCode::HAS_DATA_TYPE), data, reply, option);
134 
135     return true;
136 }
137 
FuzzPasteOnSubscribeObserver(const uint8_t * rawData,size_t size)138 bool FuzzPasteOnSubscribeObserver(const uint8_t *rawData, size_t size)
139 {
140     MessageParcel data;
141     data.WriteInterfaceToken(PASTEBOARDSERVICE_INTERFACE_TOKEN);
142     data.WriteUint32(ConvertToUint32(rawData));
143     sptr<IRemoteObject> obj = new (std::nothrow) IPCObjectStub();
144     data.WriteRemoteObject(obj);
145     data.RewindRead(0);
146     MessageParcel reply;
147     MessageOption option;
148 
149     std::make_shared<PasteboardService>()->OnRemoteRequest(
150         static_cast<uint32_t>(PasteboardServiceInterfaceCode::SUBSCRIBE_OBSERVER), data, reply, option);
151     data.RewindRead(0);
152     std::make_shared<PasteboardService>()->OnRemoteRequest(
153         static_cast<uint32_t>(PasteboardServiceInterfaceCode::UNSUBSCRIBE_OBSERVER), data, reply, option);
154     data.RewindRead(0);
155     std::make_shared<PasteboardService>()->OnRemoteRequest(
156         static_cast<uint32_t>(PasteboardServiceInterfaceCode::UNSUBSCRIBE_ALL_OBSERVER), data, reply, option);
157 
158     return true;
159 }
160 
FuzzPasteOnSetGlobalShareOption(const uint8_t * rawData,size_t size)161 bool FuzzPasteOnSetGlobalShareOption(const uint8_t *rawData, size_t size)
162 {
163     uint32_t tokenId = ConvertToUint32(rawData);
164     rawData = rawData + OFFSET;
165     size = size - OFFSET;
166 
167     MessageParcel data;
168     data.WriteInterfaceToken(PASTEBOARDSERVICE_INTERFACE_TOKEN);
169     data.WriteInt32(1);
170     data.WriteUint32(tokenId);
171     data.WriteInt32(static_cast<int32_t>(tokenId % SHAREOPTIONSIZE));
172 
173     data.RewindRead(0);
174     MessageParcel reply;
175     MessageOption option;
176 
177     std::make_shared<PasteboardService>()->OnRemoteRequest(
178         static_cast<uint32_t>(PasteboardServiceInterfaceCode::SET_GLOBAL_SHARE_OPTION), data, reply, option);
179     return true;
180 }
181 
FuzzPasteOnGetGlobalShareOption(const uint8_t * rawData,size_t size)182 bool FuzzPasteOnGetGlobalShareOption(const uint8_t *rawData, size_t size)
183 {
184     uint32_t tokenId = ConvertToUint32(rawData);
185     rawData = rawData + OFFSET;
186     size = size - OFFSET;
187 
188     std::vector<uint32_t> vec;
189     vec.push_back(tokenId);
190     tokenId = ConvertToUint32(rawData);
191     vec.push_back(tokenId);
192 
193     MessageParcel data;
194     data.WriteInterfaceToken(PASTEBOARDSERVICE_INTERFACE_TOKEN);
195     data.WriteUInt32Vector(vec);
196     data.RewindRead(0);
197     MessageParcel reply;
198     MessageOption option;
199 
200     std::make_shared<PasteboardService>()->OnRemoteRequest(
201         static_cast<uint32_t>(PasteboardServiceInterfaceCode::GET_GLOBAL_SHARE_OPTION), data, reply, option);
202     data.RewindRead(0);
203     std::make_shared<PasteboardService>()->OnRemoteRequest(
204         static_cast<uint32_t>(PasteboardServiceInterfaceCode::REMOVE_GLOBAL_SHARE_OPTION), data, reply, option);
205     return true;
206 }
207 
FuzzPasteOnSetAppShareOptions(const uint8_t * rawData,size_t size)208 bool FuzzPasteOnSetAppShareOptions(const uint8_t *rawData, size_t size)
209 {
210     MessageParcel data;
211     data.WriteInterfaceToken(PASTEBOARDSERVICE_INTERFACE_TOKEN);
212     int32_t shareOptions = TypeCast<int32_t>(rawData);
213     data.WriteInt32(shareOptions);
214     data.RewindRead(0);
215     MessageParcel reply;
216     MessageOption option;
217     std::make_shared<PasteboardService>()->OnRemoteRequest(
218         static_cast<uint32_t>(PasteboardServiceInterfaceCode::SET_APP_SHARE_OPTIONS), data, reply, option);
219     return true;
220 }
221 
FuzzPasteOnRemoveAppShareOptions(const uint8_t * rawData,size_t size)222 bool FuzzPasteOnRemoveAppShareOptions(const uint8_t *rawData, size_t size)
223 {
224     MessageParcel data;
225     data.WriteInterfaceToken(PASTEBOARDSERVICE_INTERFACE_TOKEN);
226     MessageParcel reply;
227     MessageOption option;
228     std::make_shared<PasteboardService>()->OnRemoteRequest(
229         static_cast<uint32_t>(PasteboardServiceInterfaceCode::REMOVE_APP_SHARE_OPTIONS), data, reply, option);
230     return true;
231 }
232 
FuzzPasteOnPasteStart(const uint8_t * rawData,size_t size)233 bool FuzzPasteOnPasteStart(const uint8_t *rawData, size_t size)
234 {
235     MessageParcel data;
236     data.WriteInterfaceToken(PASTEBOARDSERVICE_INTERFACE_TOKEN);
237     data.WriteString(string(reinterpret_cast<const char*>(rawData), size));
238     MessageParcel reply;
239     MessageOption option;
240     std::make_shared<PasteboardService>()->OnRemoteRequest(
241         static_cast<uint32_t>(PasteboardServiceInterfaceCode::PASTE_START), data, reply, option);
242     return true;
243 }
244 
FuzzPasteOnPasteComplete(const uint8_t * rawData,size_t size)245 bool FuzzPasteOnPasteComplete(const uint8_t *rawData, size_t size)
246 {
247     MessageParcel data;
248     data.WriteInterfaceToken(PASTEBOARDSERVICE_INTERFACE_TOKEN);
249     int len = size >> 1;
250     data.WriteString(string(reinterpret_cast<const char*>(rawData), len));
251     data.WriteString(string(reinterpret_cast<const char*>(rawData + len), size - len));
252     MessageParcel reply;
253     MessageOption option;
254     std::make_shared<PasteboardService>()->OnRemoteRequest(
255         static_cast<uint32_t>(PasteboardServiceInterfaceCode::PASTE_COMPLETE), data, reply, option);
256     return true;
257 }
258 
FuzzPasteOnRegisterClientDeathObserver(const uint8_t * rawData,size_t size)259 bool FuzzPasteOnRegisterClientDeathObserver(const uint8_t *rawData, size_t size)
260 {
261     MessageParcel data;
262     data.WriteInterfaceToken(PASTEBOARDSERVICE_INTERFACE_TOKEN);
263     sptr<IRemoteObject> obj = new (std::nothrow) IPCObjectStub();
264     data.WriteRemoteObject(obj);
265     MessageParcel reply;
266     MessageOption option;
267     std::make_shared<PasteboardService>()->OnRemoteRequest(
268         static_cast<uint32_t>(PasteboardServiceInterfaceCode::REGISTER_CLIENT_DEATH_OBSERVER), data, reply, option);
269     return true;
270 }
271 } // namespace OHOS
272 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)273 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
274 {
275     if (size < OHOS::THRESHOLD) {
276         return 0;
277     }
278     /* Run your code on data */
279     OHOS::FuzzPasteboardService(data, size);
280     OHOS::FuzzPasteboardServiceOnSetPasteData(data, size);
281     OHOS::FuzzPasteboardServiceOnClearPasteData(data, size);
282     OHOS::FuzzPasteOnIsRemoteData(data, size);
283     OHOS::FuzzPasteOnSubscribeObserver(data, size);
284     OHOS::FuzzPasteOnSetGlobalShareOption(data, size);
285     OHOS::FuzzPasteOnGetGlobalShareOption(data, size);
286     OHOS::FuzzPasteOnSetAppShareOptions(data, size);
287     OHOS::FuzzPasteOnRemoveAppShareOptions(data, size);
288     OHOS::FuzzPasteOnPasteStart(data, size);
289     OHOS::FuzzPasteOnRegisterClientDeathObserver(data, size);
290     return 0;
291 }
292