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 "device/include/esco_parameters.h"
23 #include "device/include/interop.h"
24 #include "device/include/interop_config.h"
25 
26 // TODO(b/369381361) Enfore -Wmissing-prototypes
27 #pragma GCC diagnostic ignored "-Wmissing-prototypes"
28 
29 using namespace std;
30 constexpr size_t kNumAddressOctets = 6;
31 constexpr size_t kMaxStringLength = 10;
32 constexpr interop_feature_t kInteropFeature[] = {
33         interop_feature_t::INTEROP_DISABLE_LE_SECURE_CONNECTIONS,
34         interop_feature_t::INTEROP_AUTO_RETRY_PAIRING,
35         interop_feature_t::INTEROP_DISABLE_ABSOLUTE_VOLUME,
36         interop_feature_t::INTEROP_DISABLE_AUTO_PAIRING,
37         interop_feature_t::INTEROP_KEYBOARD_REQUIRES_FIXED_PIN,
38         interop_feature_t::INTEROP_2MBPS_LINK_ONLY,
39         interop_feature_t::INTEROP_DISABLE_SDP_AFTER_PAIRING,
40         interop_feature_t::INTEROP_REMOVE_HID_DIG_DESCRIPTOR,
41         interop_feature_t::INTEROP_DISABLE_SNIFF_DURING_SCO,
42         interop_feature_t::INTEROP_HID_PREF_CONN_SUP_TIMEOUT_3S,
43         interop_feature_t::INTEROP_GATTC_NO_SERVICE_CHANGED_IND,
44         interop_feature_t::INTEROP_INCREASE_AG_CONN_TIMEOUT,
45         interop_feature_t::INTEROP_DISABLE_LE_CONN_PREFERRED_PARAMS,
46         interop_feature_t::INTEROP_DISABLE_AAC_CODEC,
47         interop_feature_t::INTEROP_DISABLE_AAC_VBR_CODEC,
48         interop_feature_t::INTEROP_ENABLE_AAC_CODEC,
49         interop_feature_t::INTEROP_DISABLE_ROLE_SWITCH_POLICY,
50         interop_feature_t::INTEROP_HFP_1_7_DENYLIST,
51         interop_feature_t::INTEROP_HFP_1_8_DENYLIST,
52         interop_feature_t::INTEROP_ADV_PBAP_VER_1_1,
53         interop_feature_t::INTEROP_UPDATE_HID_SSR_MAX_LAT,
54         interop_feature_t::INTEROP_DISABLE_AUTH_FOR_HID_POINTING,
55         interop_feature_t::INTEROP_DISABLE_AVDTP_RECONFIGURE,
56         interop_feature_t::INTEROP_DYNAMIC_ROLE_SWITCH,
57         interop_feature_t::INTEROP_DISABLE_HF_INDICATOR,
58         interop_feature_t::INTEROP_DISABLE_ROLE_SWITCH,
59         interop_feature_t::INTEROP_DELAY_SCO_FOR_MT_CALL,
60         interop_feature_t::INTEROP_DISABLE_CODEC_NEGOTIATION,
61         interop_feature_t::INTEROP_DISABLE_PLAYER_APPLICATION_SETTING_CMDS,
62         interop_feature_t::INTEROP_DISABLE_CONNECTION_AFTER_COLLISION,
63         interop_feature_t::INTEROP_DISABLE_LE_CONN_UPDATES,
64         interop_feature_t::INTEROP_ADV_PBAP_VER_1_2,
65         interop_feature_t::INTEROP_DISABLE_PCE_SDP_AFTER_PAIRING,
66         interop_feature_t::INTEROP_AVRCP_BROWSE_OPEN_CHANNEL_COLLISION,
67         interop_feature_t::INTEROP_DISABLE_SNIFF_LINK_DURING_SCO,
68         interop_feature_t::INTEROP_DISABLE_SNIFF_DURING_CALL,
69         interop_feature_t::INTEROP_HID_HOST_LIMIT_SNIFF_INTERVAL,
70         interop_feature_t::INTEROP_DISABLE_REFRESH_ACCEPT_SIG_TIMER,
71         interop_feature_t::INTEROP_SKIP_INCOMING_STATE,
72         interop_feature_t::INTEROP_NOT_UPDATE_AVRCP_PAUSED_TO_REMOTE,
73         interop_feature_t::INTEROP_PHONE_POLICY_INCREASED_DELAY_CONNECT_OTHER_PROFILES,
74         interop_feature_t::INTEROP_DISABLE_NAME_REQUEST,
75         interop_feature_t::INTEROP_AVRCP_1_4_ONLY,
76         interop_feature_t::INTEROP_DISABLE_SNIFF,
77         interop_feature_t::INTEROP_DISABLE_AVDTP_SUSPEND,
78         interop_feature_t::INTEROP_SLC_SKIP_BIND_COMMAND,
79         interop_feature_t::INTEROP_AVRCP_1_3_ONLY,
80         interop_feature_t::INTEROP_PHONE_POLICY_REDUCED_DELAY_CONNECT_OTHER_PROFILES,
81         interop_feature_t::INTEROP_HFP_FAKE_INCOMING_CALL_INDICATOR,
82         interop_feature_t::INTEROP_HFP_SEND_CALL_INDICATORS_BACK_TO_BACK,
83         interop_feature_t::INTEROP_SETUP_SCO_WITH_NO_DELAY_AFTER_SLC_DURING_CALL,
84         interop_feature_t::INTEROP_ENABLE_PREFERRED_CONN_PARAMETER,
85         interop_feature_t::INTEROP_RETRY_SCO_AFTER_REMOTE_REJECT_SCO,
86         interop_feature_t::INTEROP_DELAY_SCO_FOR_MO_CALL,
87         interop_feature_t::INTEROP_CHANGE_HID_VID_PID,
88         interop_feature_t::INTEROP_DISABLE_ROLE_SWITCH_DURING_CONNECTION,
89         interop_feature_t::INTEROP_DISABLE_ROBUST_CACHING,
90         interop_feature_t::INTEROP_HFP_1_7_ALLOWLIST,
91         interop_feature_t::INTEROP_IGNORE_DISC_BEFORE_SIGNALLING_TIMEOUT,
92 };
93 constexpr esco_codec_t kEscoCodec[] = {
94         esco_codec_t::SCO_CODEC_CVSD_D1,  esco_codec_t::ESCO_CODEC_CVSD_S3,
95         esco_codec_t::ESCO_CODEC_CVSD_S4, esco_codec_t::ESCO_CODEC_MSBC_T1,
96         esco_codec_t::ESCO_CODEC_MSBC_T2, esco_codec_t::ESCO_CODEC_LC3_T1,
97         esco_codec_t::ESCO_CODEC_LC3_T2,
98 };
99 
generateString(FuzzedDataProvider & fdp,string & addressString)100 void generateString(FuzzedDataProvider& fdp, string& addressString) {
101   addressString.clear();
102   if (fdp.ConsumeBool()) {
103     for (size_t i = 0; i < kNumAddressOctets; ++i) {
104       addressString.append(fdp.ConsumeBytesAsString(sizeof(uint8_t)));
105       if (i != kNumAddressOctets - 1) {
106         addressString.append(":");
107       }
108     }
109   } else {
110     addressString = fdp.ConsumeRandomLengthString(kMaxStringLength);
111   }
112 }
113 
114 extern module_t interop_module;
115 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)116 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
117   FuzzedDataProvider mFuzzedDataProvider = FuzzedDataProvider(data, size);
118   RawAddress fuzzAddress;
119   string addressString;
120   module_init(&interop_module);
121 
122   while (mFuzzedDataProvider.remaining_bytes()) {
123     auto invokeBtDeviceApi = mFuzzedDataProvider.PickValueInArray<const std::function<void()>>({
124             [&]() {
125               generateString(mFuzzedDataProvider, addressString);
126               RawAddress::FromString(addressString, fuzzAddress);
127               interop_match_addr(
128                       mFuzzedDataProvider.PickValueInArray(kInteropFeature) /* feature */,
129                       &fuzzAddress);
130             },
131             [&]() {
132               interop_match_name(
133                       mFuzzedDataProvider.PickValueInArray(kInteropFeature) /* feature */,
134                       mFuzzedDataProvider.ConsumeRandomLengthString(kMaxStringLength)
135                               .c_str() /* name */
136               );
137             },
138             [&]() {
139               interop_match_manufacturer(
140                       mFuzzedDataProvider.PickValueInArray(kInteropFeature) /* feature */,
141                       mFuzzedDataProvider.ConsumeIntegral<int32_t>() /* manufacturer */
142               );
143             },
144             [&]() {
145               interop_match_vendor_product_ids(
146                       mFuzzedDataProvider.PickValueInArray(kInteropFeature) /* feature */,
147                       mFuzzedDataProvider.ConsumeIntegral<int16_t>() /* vendor_id */,
148                       mFuzzedDataProvider.ConsumeIntegral<int16_t>() /* product_id */
149               );
150             },
151             [&]() {
152               generateString(mFuzzedDataProvider, addressString);
153               RawAddress::FromString(addressString, fuzzAddress);
154               interop_database_add(
155                       mFuzzedDataProvider.PickValueInArray(kInteropFeature) /* feature */,
156                       &fuzzAddress,
157                       mFuzzedDataProvider.ConsumeIntegralInRange<int32_t>(
158                               1, RawAddress::kLength - 1) /* length */
159               );
160             },
161             [&]() { interop_database_clear(); },
162             [&]() {
163               interop_database_match_version(
164                       mFuzzedDataProvider.PickValueInArray(kInteropFeature) /* feature */,
165                       mFuzzedDataProvider.ConsumeIntegral<int32_t>() /* version */
166               );
167             },
168             [&]() {
169               generateString(mFuzzedDataProvider, addressString);
170               RawAddress::FromString(addressString, fuzzAddress);
171               uint16_t max_lat = 0;
172               interop_match_addr_get_max_lat(
173                       mFuzzedDataProvider.PickValueInArray(kInteropFeature) /* feature */,
174                       &fuzzAddress, &max_lat);
175             },
176             [&]() {
177               generateString(mFuzzedDataProvider, addressString);
178               RawAddress::FromString(addressString, fuzzAddress);
179               interop_feature_name_to_feature_id(addressString.c_str());
180             },
181             [&]() {
182               esco_parameters_for_codec(
183                       mFuzzedDataProvider.PickValueInArray(kEscoCodec) /* codec */, true);
184             },
185             [&]() {
186               interop_database_add_manufacturer(
187                       mFuzzedDataProvider.PickValueInArray(kInteropFeature) /* feature */,
188                       mFuzzedDataProvider.ConsumeIntegral<uint16_t>() /* manufacturer */);
189             },
190             [&]() {
191               interop_database_add_vndr_prdt(
192                       mFuzzedDataProvider.PickValueInArray(kInteropFeature) /* feature */,
193                       mFuzzedDataProvider.ConsumeIntegral<uint16_t>() /* vendor_id */,
194                       mFuzzedDataProvider.ConsumeIntegral<uint16_t>() /* product_id */);
195             },
196             [&]() {
197               generateString(mFuzzedDataProvider, addressString);
198               RawAddress::FromString(addressString, fuzzAddress);
199               interop_database_add_addr_max_lat(
200                       mFuzzedDataProvider.PickValueInArray(kInteropFeature) /* feature */,
201                       &fuzzAddress, mFuzzedDataProvider.ConsumeIntegral<uint16_t>() /* max_lat */);
202             },
203             [&]() {
204               interop_database_add_version(
205                       mFuzzedDataProvider.PickValueInArray(kInteropFeature) /* feature */,
206                       mFuzzedDataProvider.ConsumeIntegral<uint16_t>() /* version */);
207             },
208             [&]() {
209               interop_database_add_addr_lmp_version(
210                       mFuzzedDataProvider.PickValueInArray(kInteropFeature) /* feature */,
211                       &fuzzAddress, mFuzzedDataProvider.ConsumeIntegral<uint8_t>() /* lmp_ver */,
212                       mFuzzedDataProvider.ConsumeIntegral<uint16_t>() /* lmp_sub_ver */);
213             },
214             [&]() {
215               uint8_t lmp_ver = 0;
216               uint16_t lmp_sub_ver = 0;
217               interop_database_match_addr_get_lmp_ver(
218                       mFuzzedDataProvider.PickValueInArray(kInteropFeature) /* feature */,
219                       &fuzzAddress, &lmp_ver, &lmp_sub_ver);
220             },
221             [&]() {
222               interop_database_remove_manufacturer(
223                       mFuzzedDataProvider.PickValueInArray(kInteropFeature) /* feature */,
224                       mFuzzedDataProvider.ConsumeIntegral<uint16_t>() /* manufacturer */);
225             },
226             [&]() {
227               interop_database_remove_vndr_prdt(
228                       mFuzzedDataProvider.PickValueInArray(kInteropFeature) /* feature */,
229                       mFuzzedDataProvider.ConsumeIntegral<uint16_t>() /* vendor_id */,
230                       mFuzzedDataProvider.ConsumeIntegral<uint16_t>() /* product_id */);
231             },
232             [&]() {
233               generateString(mFuzzedDataProvider, addressString);
234               RawAddress::FromString(addressString, fuzzAddress);
235               interop_database_remove_addr_max_lat(
236                       mFuzzedDataProvider.PickValueInArray(kInteropFeature) /* feature */,
237                       &fuzzAddress, mFuzzedDataProvider.ConsumeIntegral<uint16_t>() /* max_lat */);
238             },
239             [&]() {
240               interop_database_remove_version(
241                       mFuzzedDataProvider.PickValueInArray(kInteropFeature) /* feature */,
242                       mFuzzedDataProvider.ConsumeIntegral<uint16_t>() /*version*/);
243             },
244             [&]() {
245               interop_database_remove_addr_lmp_version(
246                       mFuzzedDataProvider.PickValueInArray(kInteropFeature) /* feature */,
247                       &fuzzAddress, mFuzzedDataProvider.ConsumeIntegral<uint8_t>() /* lmp_ver */,
248                       mFuzzedDataProvider.ConsumeIntegral<uint16_t>() /* lmp_sub_ver */);
249             },
250     });
251     invokeBtDeviceApi();
252   }
253   module_clean_up(&interop_module);
254   return 0;
255 }
256