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 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::INTEROP_PHONE_POLICY_INCREASED_DELAY_CONNECT_OTHER_PROFILES,
71 interop_feature_t::INTEROP_DISABLE_NAME_REQUEST,
72 interop_feature_t::INTEROP_AVRCP_1_4_ONLY,
73 interop_feature_t::INTEROP_DISABLE_SNIFF,
74 interop_feature_t::INTEROP_DISABLE_AVDTP_SUSPEND,
75 interop_feature_t::INTEROP_SLC_SKIP_BIND_COMMAND,
76 interop_feature_t::INTEROP_AVRCP_1_3_ONLY,
77 interop_feature_t::INTEROP_PHONE_POLICY_REDUCED_DELAY_CONNECT_OTHER_PROFILES,
78 interop_feature_t::INTEROP_HFP_FAKE_INCOMING_CALL_INDICATOR,
79 interop_feature_t::INTEROP_HFP_SEND_CALL_INDICATORS_BACK_TO_BACK,
80 interop_feature_t::INTEROP_SETUP_SCO_WITH_NO_DELAY_AFTER_SLC_DURING_CALL,
81 interop_feature_t::INTEROP_ENABLE_PREFERRED_CONN_PARAMETER,
82 interop_feature_t::INTEROP_RETRY_SCO_AFTER_REMOTE_REJECT_SCO,
83 interop_feature_t::INTEROP_DELAY_SCO_FOR_MO_CALL,
84 interop_feature_t::INTEROP_CHANGE_HID_VID_PID,
85 interop_feature_t::INTEROP_DISABLE_ROLE_SWITCH_DURING_CONNECTION,
86 interop_feature_t::INTEROP_DISABLE_ROBUST_CACHING,
87 interop_feature_t::INTEROP_HFP_1_7_ALLOWLIST,
88 interop_feature_t::INTEROP_IGNORE_DISC_BEFORE_SIGNALLING_TIMEOUT,
89 };
90 constexpr esco_codec_t kEscoCodec[] = {
91 esco_codec_t::SCO_CODEC_CVSD_D1, esco_codec_t::ESCO_CODEC_CVSD_S3,
92 esco_codec_t::ESCO_CODEC_CVSD_S4, esco_codec_t::ESCO_CODEC_MSBC_T1,
93 esco_codec_t::ESCO_CODEC_MSBC_T2, esco_codec_t::ESCO_CODEC_LC3_T1,
94 esco_codec_t::ESCO_CODEC_LC3_T2,
95 };
96
generateString(FuzzedDataProvider & fdp,string & addressString)97 void generateString(FuzzedDataProvider& fdp, string& addressString) {
98 addressString.clear();
99 if (fdp.ConsumeBool()) {
100 for (size_t i = 0; i < kNumAddressOctets; ++i) {
101 addressString.append(fdp.ConsumeBytesAsString(sizeof(uint8_t)));
102 if (i != kNumAddressOctets - 1) {
103 addressString.append(":");
104 }
105 }
106 } else {
107 addressString = fdp.ConsumeRandomLengthString(kMaxStringLength);
108 }
109 }
110
111 extern module_t interop_module;
112
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)113 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
114 FuzzedDataProvider mFuzzedDataProvider = FuzzedDataProvider(data, size);
115 RawAddress fuzzAddress;
116 string addressString;
117 module_init(&interop_module);
118
119 while (mFuzzedDataProvider.remaining_bytes()) {
120 auto invokeBtDeviceApi = mFuzzedDataProvider.PickValueInArray<const std::function<void()>>({
121 [&]() {
122 generateString(mFuzzedDataProvider, addressString);
123 RawAddress::FromString(addressString, fuzzAddress);
124 interop_match_addr(
125 mFuzzedDataProvider.PickValueInArray(kInteropFeature) /* feature */,
126 &fuzzAddress);
127 },
128 [&]() {
129 interop_match_name(
130 mFuzzedDataProvider.PickValueInArray(kInteropFeature) /* feature */,
131 mFuzzedDataProvider.ConsumeRandomLengthString(kMaxStringLength)
132 .c_str() /* name */
133 );
134 },
135 [&]() {
136 interop_match_manufacturer(
137 mFuzzedDataProvider.PickValueInArray(kInteropFeature) /* feature */,
138 mFuzzedDataProvider.ConsumeIntegral<int32_t>() /* manufacturer */
139 );
140 },
141 [&]() {
142 interop_match_vendor_product_ids(
143 mFuzzedDataProvider.PickValueInArray(kInteropFeature) /* feature */,
144 mFuzzedDataProvider.ConsumeIntegral<int16_t>() /* vendor_id */,
145 mFuzzedDataProvider.ConsumeIntegral<int16_t>() /* product_id */
146 );
147 },
148 [&]() {
149 generateString(mFuzzedDataProvider, addressString);
150 RawAddress::FromString(addressString, fuzzAddress);
151 interop_database_add(
152 mFuzzedDataProvider.PickValueInArray(kInteropFeature) /* feature */,
153 &fuzzAddress,
154 mFuzzedDataProvider.ConsumeIntegralInRange<int32_t>(
155 1, RawAddress::kLength - 1) /* length */
156 );
157 },
158 [&]() { interop_database_clear(); },
159 [&]() {
160 interop_database_match_version(
161 mFuzzedDataProvider.PickValueInArray(kInteropFeature) /* feature */,
162 mFuzzedDataProvider.ConsumeIntegral<int32_t>() /* version */
163 );
164 },
165 [&]() {
166 generateString(mFuzzedDataProvider, addressString);
167 RawAddress::FromString(addressString, fuzzAddress);
168 uint16_t max_lat = 0;
169 interop_match_addr_get_max_lat(
170 mFuzzedDataProvider.PickValueInArray(kInteropFeature) /* feature */,
171 &fuzzAddress, &max_lat);
172 },
173 [&]() {
174 generateString(mFuzzedDataProvider, addressString);
175 RawAddress::FromString(addressString, fuzzAddress);
176 interop_feature_name_to_feature_id(addressString.c_str());
177 },
178 [&]() {
179 esco_parameters_for_codec(
180 mFuzzedDataProvider.PickValueInArray(kEscoCodec) /* codec */, true);
181 },
182 [&]() {
183 interop_database_add_manufacturer(
184 mFuzzedDataProvider.PickValueInArray(kInteropFeature) /* feature */,
185 mFuzzedDataProvider.ConsumeIntegral<uint16_t>() /* manufacturer */);
186 },
187 [&]() {
188 interop_database_add_vndr_prdt(
189 mFuzzedDataProvider.PickValueInArray(kInteropFeature) /* feature */,
190 mFuzzedDataProvider.ConsumeIntegral<uint16_t>() /* vendor_id */,
191 mFuzzedDataProvider.ConsumeIntegral<uint16_t>() /* product_id */);
192 },
193 [&]() {
194 generateString(mFuzzedDataProvider, addressString);
195 RawAddress::FromString(addressString, fuzzAddress);
196 interop_database_add_addr_max_lat(
197 mFuzzedDataProvider.PickValueInArray(kInteropFeature) /* feature */,
198 &fuzzAddress, mFuzzedDataProvider.ConsumeIntegral<uint16_t>() /* max_lat */);
199 },
200 [&]() {
201 interop_database_add_version(
202 mFuzzedDataProvider.PickValueInArray(kInteropFeature) /* feature */,
203 mFuzzedDataProvider.ConsumeIntegral<uint16_t>() /* version */);
204 },
205 [&]() {
206 interop_database_add_addr_lmp_version(
207 mFuzzedDataProvider.PickValueInArray(kInteropFeature) /* feature */,
208 &fuzzAddress, mFuzzedDataProvider.ConsumeIntegral<uint8_t>() /* lmp_ver */,
209 mFuzzedDataProvider.ConsumeIntegral<uint16_t>() /* lmp_sub_ver */);
210 },
211 [&]() {
212 uint8_t lmp_ver = 0;
213 uint16_t lmp_sub_ver = 0;
214 interop_database_match_addr_get_lmp_ver(
215 mFuzzedDataProvider.PickValueInArray(kInteropFeature) /* feature */,
216 &fuzzAddress, &lmp_ver, &lmp_sub_ver);
217 },
218 [&]() {
219 interop_database_remove_manufacturer(
220 mFuzzedDataProvider.PickValueInArray(kInteropFeature) /* feature */,
221 mFuzzedDataProvider.ConsumeIntegral<uint16_t>() /* manufacturer */);
222 },
223 [&]() {
224 interop_database_remove_vndr_prdt(
225 mFuzzedDataProvider.PickValueInArray(kInteropFeature) /* feature */,
226 mFuzzedDataProvider.ConsumeIntegral<uint16_t>() /* vendor_id */,
227 mFuzzedDataProvider.ConsumeIntegral<uint16_t>() /* product_id */);
228 },
229 [&]() {
230 generateString(mFuzzedDataProvider, addressString);
231 RawAddress::FromString(addressString, fuzzAddress);
232 interop_database_remove_addr_max_lat(
233 mFuzzedDataProvider.PickValueInArray(kInteropFeature) /* feature */,
234 &fuzzAddress, mFuzzedDataProvider.ConsumeIntegral<uint16_t>() /* max_lat */);
235 },
236 [&]() {
237 interop_database_remove_version(
238 mFuzzedDataProvider.PickValueInArray(kInteropFeature) /* feature */,
239 mFuzzedDataProvider.ConsumeIntegral<uint16_t>() /*version*/);
240 },
241 [&]() {
242 interop_database_remove_addr_lmp_version(
243 mFuzzedDataProvider.PickValueInArray(kInteropFeature) /* feature */,
244 &fuzzAddress, mFuzzedDataProvider.ConsumeIntegral<uint8_t>() /* lmp_ver */,
245 mFuzzedDataProvider.ConsumeIntegral<uint16_t>() /* lmp_sub_ver */);
246 },
247 });
248 invokeBtDeviceApi();
249 }
250 module_clean_up(&interop_module);
251 return 0;
252 }
253