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