1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <fuzzer/FuzzedDataProvider.h>
18 
19 #include <string>
20 
21 #include "btcore/include/module.h"
22 #include "esco_parameters.h"
23 #include "interop.h"
24 #include "interop_config.h"
25 
26 using namespace std;
27 constexpr size_t kNumAddressOctets = 6;
28 constexpr size_t kMaxStringLength = 10;
29 constexpr interop_feature_t kInteropFeature[] = {
30     interop_feature_t::INTEROP_DISABLE_LE_SECURE_CONNECTIONS,
31     interop_feature_t::INTEROP_AUTO_RETRY_PAIRING,
32     interop_feature_t::INTEROP_DISABLE_ABSOLUTE_VOLUME,
33     interop_feature_t::INTEROP_DISABLE_AUTO_PAIRING,
34     interop_feature_t::INTEROP_KEYBOARD_REQUIRES_FIXED_PIN,
35     interop_feature_t::INTEROP_2MBPS_LINK_ONLY,
36     interop_feature_t::INTEROP_DISABLE_SDP_AFTER_PAIRING,
37     interop_feature_t::INTEROP_REMOVE_HID_DIG_DESCRIPTOR,
38     interop_feature_t::INTEROP_DISABLE_SNIFF_DURING_SCO,
39     interop_feature_t::INTEROP_HID_PREF_CONN_SUP_TIMEOUT_3S,
40     interop_feature_t::INTEROP_GATTC_NO_SERVICE_CHANGED_IND,
41     interop_feature_t::INTEROP_INCREASE_AG_CONN_TIMEOUT,
42     interop_feature_t::INTEROP_DISABLE_LE_CONN_PREFERRED_PARAMS,
43     interop_feature_t::INTEROP_DISABLE_AAC_CODEC,
44     interop_feature_t::INTEROP_DISABLE_AAC_VBR_CODEC,
45     interop_feature_t::INTEROP_ENABLE_AAC_CODEC,
46     interop_feature_t::INTEROP_DISABLE_ROLE_SWITCH_POLICY,
47     interop_feature_t::INTEROP_HFP_1_7_DENYLIST,
48     interop_feature_t::INTEROP_HFP_1_8_DENYLIST,
49     interop_feature_t::INTEROP_ADV_PBAP_VER_1_1,
50     interop_feature_t::INTEROP_UPDATE_HID_SSR_MAX_LAT,
51     interop_feature_t::INTEROP_DISABLE_AUTH_FOR_HID_POINTING,
52     interop_feature_t::INTEROP_DISABLE_AVDTP_RECONFIGURE,
53     interop_feature_t::INTEROP_DYNAMIC_ROLE_SWITCH,
54     interop_feature_t::INTEROP_DISABLE_HF_INDICATOR,
55     interop_feature_t::INTEROP_DISABLE_ROLE_SWITCH,
56     interop_feature_t::INTEROP_DELAY_SCO_FOR_MT_CALL,
57     interop_feature_t::INTEROP_DISABLE_CODEC_NEGOTIATION,
58     interop_feature_t::INTEROP_DISABLE_PLAYER_APPLICATION_SETTING_CMDS,
59     interop_feature_t::INTEROP_DISABLE_CONNECTION_AFTER_COLLISION,
60     interop_feature_t::INTEROP_DISABLE_LE_CONN_UPDATES,
61     interop_feature_t::INTEROP_ADV_PBAP_VER_1_2,
62     interop_feature_t::INTEROP_DISABLE_PCE_SDP_AFTER_PAIRING,
63     interop_feature_t::INTEROP_AVRCP_BROWSE_OPEN_CHANNEL_COLLISION,
64     interop_feature_t::INTEROP_DISABLE_SNIFF_LINK_DURING_SCO,
65     interop_feature_t::INTEROP_DISABLE_SNIFF_DURING_CALL,
66     interop_feature_t::INTEROP_HID_HOST_LIMIT_SNIFF_INTERVAL,
67     interop_feature_t::INTEROP_DISABLE_REFRESH_ACCEPT_SIG_TIMER,
68     interop_feature_t::INTEROP_SKIP_INCOMING_STATE,
69     interop_feature_t::INTEROP_NOT_UPDATE_AVRCP_PAUSED_TO_REMOTE,
70     interop_feature_t::
71         INTEROP_PHONE_POLICY_INCREASED_DELAY_CONNECT_OTHER_PROFILES,
72     interop_feature_t::INTEROP_DISABLE_NAME_REQUEST,
73     interop_feature_t::INTEROP_AVRCP_1_4_ONLY,
74     interop_feature_t::INTEROP_DISABLE_SNIFF,
75     interop_feature_t::INTEROP_DISABLE_AVDTP_SUSPEND,
76     interop_feature_t::INTEROP_SLC_SKIP_BIND_COMMAND,
77     interop_feature_t::INTEROP_AVRCP_1_3_ONLY,
78     interop_feature_t::
79         INTEROP_PHONE_POLICY_REDUCED_DELAY_CONNECT_OTHER_PROFILES,
80     interop_feature_t::INTEROP_HFP_FAKE_INCOMING_CALL_INDICATOR,
81     interop_feature_t::INTEROP_HFP_SEND_CALL_INDICATORS_BACK_TO_BACK,
82     interop_feature_t::INTEROP_SETUP_SCO_WITH_NO_DELAY_AFTER_SLC_DURING_CALL,
83     interop_feature_t::INTEROP_ENABLE_PREFERRED_CONN_PARAMETER,
84     interop_feature_t::INTEROP_RETRY_SCO_AFTER_REMOTE_REJECT_SCO,
85     interop_feature_t::INTEROP_DELAY_SCO_FOR_MO_CALL,
86     interop_feature_t::INTEROP_CHANGE_HID_VID_PID,
87     interop_feature_t::INTEROP_DISABLE_ROLE_SWITCH_DURING_CONNECTION,
88     interop_feature_t::INTEROP_DISABLE_ROBUST_CACHING,
89     interop_feature_t::INTEROP_HFP_1_7_ALLOWLIST,
90     interop_feature_t::INTEROP_IGNORE_DISC_BEFORE_SIGNALLING_TIMEOUT,
91 };
92 constexpr esco_codec_t kEscoCodec[] = {
93     esco_codec_t::SCO_CODEC_CVSD_D1,  esco_codec_t::ESCO_CODEC_CVSD_S3,
94     esco_codec_t::ESCO_CODEC_CVSD_S4, esco_codec_t::ESCO_CODEC_MSBC_T1,
95     esco_codec_t::ESCO_CODEC_MSBC_T2, esco_codec_t::ESCO_CODEC_LC3_T1,
96     esco_codec_t::ESCO_CODEC_LC3_T2,
97 };
98 
generateString(FuzzedDataProvider & fdp,string & addressString)99 void generateString(FuzzedDataProvider& fdp, string& addressString) {
100   addressString.clear();
101   if (fdp.ConsumeBool()) {
102     for (size_t i = 0; i < kNumAddressOctets; ++i) {
103       addressString.append(fdp.ConsumeBytesAsString(sizeof(uint8_t)));
104       if (i != kNumAddressOctets - 1) {
105         addressString.append(":");
106       }
107     }
108   } else {
109     addressString = fdp.ConsumeRandomLengthString(kMaxStringLength);
110   }
111 }
112 
113 extern module_t interop_module;
114 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)115 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
116   FuzzedDataProvider mFuzzedDataProvider = FuzzedDataProvider(data, size);
117   RawAddress fuzzAddress;
118   string addressString;
119   module_init(&interop_module);
120 
121   while (mFuzzedDataProvider.remaining_bytes()) {
122     auto invokeBtDeviceApi = mFuzzedDataProvider.PickValueInArray<
123         const std::function<void()>>({
124         [&]() {
125           generateString(mFuzzedDataProvider, addressString);
126           RawAddress::FromString(addressString, fuzzAddress);
127           interop_match_addr(mFuzzedDataProvider.PickValueInArray(
128                                  kInteropFeature) /* feature */,
129                              &fuzzAddress);
130         },
131         [&]() {
132           interop_match_name(
133               mFuzzedDataProvider.PickValueInArray(
134                   kInteropFeature) /* feature */,
135               mFuzzedDataProvider.ConsumeRandomLengthString(kMaxStringLength)
136                   .c_str() /* name */
137           );
138         },
139         [&]() {
140           interop_match_manufacturer(
141               mFuzzedDataProvider.PickValueInArray(
142                   kInteropFeature) /* feature */,
143               mFuzzedDataProvider.ConsumeIntegral<int32_t>() /* manufacturer */
144           );
145         },
146         [&]() {
147           interop_match_vendor_product_ids(
148               mFuzzedDataProvider.PickValueInArray(
149                   kInteropFeature) /* feature */,
150               mFuzzedDataProvider.ConsumeIntegral<int16_t>() /* vendor_id */,
151               mFuzzedDataProvider.ConsumeIntegral<int16_t>() /* product_id */
152           );
153         },
154         [&]() {
155           generateString(mFuzzedDataProvider, addressString);
156           RawAddress::FromString(addressString, fuzzAddress);
157           interop_database_add(
158               mFuzzedDataProvider.PickValueInArray(
159                   kInteropFeature) /* feature */,
160               &fuzzAddress,
161               mFuzzedDataProvider.ConsumeIntegralInRange<int32_t>(
162                   1, RawAddress::kLength - 1) /* length */
163           );
164         },
165         [&]() { interop_database_clear(); },
166         [&]() {
167           interop_database_match_version(
168               mFuzzedDataProvider.PickValueInArray(
169                   kInteropFeature) /* feature */,
170               mFuzzedDataProvider.ConsumeIntegral<int32_t>() /* version */
171           );
172         },
173         [&]() {
174           generateString(mFuzzedDataProvider, addressString);
175           RawAddress::FromString(addressString, fuzzAddress);
176           uint16_t max_lat = 0;
177           interop_match_addr_get_max_lat(mFuzzedDataProvider.PickValueInArray(
178                                              kInteropFeature) /* feature */,
179                                          &fuzzAddress, &max_lat);
180         },
181         [&]() {
182           generateString(mFuzzedDataProvider, addressString);
183           RawAddress::FromString(addressString, fuzzAddress);
184           interop_feature_name_to_feature_id(addressString.c_str());
185         },
186         [&]() {
187           esco_parameters_for_codec(
188               mFuzzedDataProvider.PickValueInArray(kEscoCodec) /* codec */,
189               true);
190         },
191         [&]() {
192           interop_database_add_manufacturer(
193               mFuzzedDataProvider.PickValueInArray(
194                   kInteropFeature) /* feature */,
195               mFuzzedDataProvider
196                   .ConsumeIntegral<uint16_t>() /* manufacturer */);
197         },
198         [&]() {
199           interop_database_add_vndr_prdt(
200               mFuzzedDataProvider.PickValueInArray(
201                   kInteropFeature) /* feature */,
202               mFuzzedDataProvider.ConsumeIntegral<uint16_t>() /* vendor_id */,
203               mFuzzedDataProvider.ConsumeIntegral<uint16_t>() /* product_id */);
204         },
205         [&]() {
206           generateString(mFuzzedDataProvider, addressString);
207           RawAddress::FromString(addressString, fuzzAddress);
208           interop_database_add_addr_max_lat(
209               mFuzzedDataProvider.PickValueInArray(
210                   kInteropFeature) /* feature */,
211               &fuzzAddress,
212               mFuzzedDataProvider.ConsumeIntegral<uint16_t>() /* max_lat */);
213         },
214         [&]() {
215           interop_database_add_version(
216               mFuzzedDataProvider.PickValueInArray(
217                   kInteropFeature) /* feature */,
218               mFuzzedDataProvider.ConsumeIntegral<uint16_t>() /* version */);
219         },
220         [&]() {
221           interop_database_add_addr_lmp_version(
222               mFuzzedDataProvider.PickValueInArray(
223                   kInteropFeature) /* feature */,
224               &fuzzAddress,
225               mFuzzedDataProvider.ConsumeIntegral<uint8_t>() /* lmp_ver */,
226               mFuzzedDataProvider
227                   .ConsumeIntegral<uint16_t>() /* lmp_sub_ver */);
228         },
229         [&]() {
230           uint8_t lmp_ver = 0;
231           uint16_t lmp_sub_ver = 0;
232           interop_database_match_addr_get_lmp_ver(
233               mFuzzedDataProvider.PickValueInArray(
234                   kInteropFeature) /* feature */,
235               &fuzzAddress, &lmp_ver, &lmp_sub_ver);
236         },
237         [&]() {
238           interop_database_remove_manufacturer(
239               mFuzzedDataProvider.PickValueInArray(
240                   kInteropFeature) /* feature */,
241               mFuzzedDataProvider
242                   .ConsumeIntegral<uint16_t>() /* manufacturer */);
243         },
244         [&]() {
245           interop_database_remove_vndr_prdt(
246               mFuzzedDataProvider.PickValueInArray(
247                   kInteropFeature) /* feature */,
248               mFuzzedDataProvider.ConsumeIntegral<uint16_t>() /* vendor_id */,
249               mFuzzedDataProvider.ConsumeIntegral<uint16_t>() /* product_id */);
250         },
251         [&]() {
252           generateString(mFuzzedDataProvider, addressString);
253           RawAddress::FromString(addressString, fuzzAddress);
254           interop_database_remove_addr_max_lat(
255               mFuzzedDataProvider.PickValueInArray(
256                   kInteropFeature) /* feature */,
257               &fuzzAddress,
258               mFuzzedDataProvider.ConsumeIntegral<uint16_t>() /* max_lat */);
259         },
260         [&]() {
261           interop_database_remove_version(
262               mFuzzedDataProvider.PickValueInArray(
263                   kInteropFeature) /* feature */,
264               mFuzzedDataProvider.ConsumeIntegral<uint16_t>() /*version*/);
265         },
266         [&]() {
267           interop_database_remove_addr_lmp_version(
268               mFuzzedDataProvider.PickValueInArray(
269                   kInteropFeature) /* feature */,
270               &fuzzAddress,
271               mFuzzedDataProvider.ConsumeIntegral<uint8_t>() /* lmp_ver */,
272               mFuzzedDataProvider
273                   .ConsumeIntegral<uint16_t>() /* lmp_sub_ver */);
274         },
275     });
276     invokeBtDeviceApi();
277   }
278   module_clean_up(&interop_module);
279   return 0;
280 }
281