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