1 /*
2  * Copyright 2020 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 #ifndef BT_STACK_FUZZ_A2DP_CODECINFO_FUNCTIONS_H_
18 #define BT_STACK_FUZZ_A2DP_CODECINFO_FUNCTIONS_H_
19 
20 #include <fuzzer/FuzzedDataProvider.h>
21 
22 #include <vector>
23 
24 #include "a2dp_codec_api.h"
25 #include "fuzzers/a2dp/codec/a2dpCodecHelperFunctions.h"
26 #include "fuzzers/a2dp/codec/a2dpCodecInfoFuzzHelpers.h"
27 #include "fuzzers/common/commonFuzzHelpers.h"
28 #include "stack/include/bt_hdr.h"
29 
30 #define MAX_PACKET_SIZE 2048
31 
32 /* This is a vector of lambda functions the fuzzer will pull from.
33  *  This is done so new functions can be added to the fuzzer easily
34  *  without requiring modifications to the main fuzzer file. This also
35  *  allows multiple fuzzers to include this file, if functionality is needed.
36  */
37 std::vector<std::function<void(FuzzedDataProvider*, uint8_t*)>>
38     a2dp_codec_info_operations = {
39         // A2DP_InitDefaultCodec
40         [](FuzzedDataProvider* fdp, uint8_t*) -> void {
41           // Allocate space for a new codec & add it to our tracking vector
42           uint8_t* codec_info = new uint8_t[AVDT_CODEC_SIZE];
43           a2dp_codec_info_vect.push_back(codec_info);
44 
45           A2DP_InitDefaultCodec(codec_info);
46         },
47 
48         // Delete a codec_info object
49         [](FuzzedDataProvider* fdp, uint8_t*) -> void {
50           if (a2dp_codec_info_vect.empty()) {
51             return;
52           }
53           // Get random vector index
54           size_t index = fdp->ConsumeIntegralInRange<size_t>(
55               0, a2dp_codec_info_vect.size() - 1);
56           // delete codec
57           delete a2dp_codec_info_vect.at(index);
58           // Remove from vector
59           a2dp_codec_info_vect.erase(a2dp_codec_info_vect.begin() + index);
60         },
61 
62         // A2DP_GetCodecType
63         [](FuzzedDataProvider* fdp, uint8_t* codec_info) -> void {
64           A2DP_GetCodecType(codec_info);
65         },
66 
67         // A2DP_IsSourceCodecValid
68         [](FuzzedDataProvider* fdp, uint8_t* codec_info) -> void {
69           A2DP_IsSourceCodecValid(codec_info);
70         },
71 
72         // A2DP_IsSinkCodecValid
73         [](FuzzedDataProvider* fdp, uint8_t* codec_info) -> void {
74           A2DP_IsSinkCodecValid(codec_info);
75         },
76 
77         // A2DP_IsPeerSourceCodecValid
78         [](FuzzedDataProvider* fdp, uint8_t* codec_info) -> void {
79           A2DP_IsPeerSourceCodecValid(codec_info);
80         },
81 
82         // A2DP_IsPeerSinkCodecValid
83         [](FuzzedDataProvider* fdp, uint8_t* codec_info) -> void {
84           A2DP_IsPeerSinkCodecValid(codec_info);
85         },
86 
87         // A2DP_IsSinkCodecSupported
88         [](FuzzedDataProvider* fdp, uint8_t* codec_info) -> void {
89           A2DP_IsSinkCodecSupported(codec_info);
90         },
91 
92         // A2DP_IsPeerSourceCodecSupported
93         [](FuzzedDataProvider* fdp, uint8_t* codec_info) -> void {
94           A2DP_IsPeerSourceCodecSupported(codec_info);
95         },
96 
97         // A2DP_UsesRtpHeader
98         [](FuzzedDataProvider* fdp, uint8_t* codec_info) -> void {
99           A2DP_UsesRtpHeader(fdp->ConsumeBool(), codec_info);
100         },
101 
102         // A2DP_GetMediaType
103         [](FuzzedDataProvider* fdp, uint8_t* codec_info) -> void {
104           A2DP_GetMediaType(codec_info);
105         },
106 
107         // A2DP_CodecName
108         [](FuzzedDataProvider* fdp, uint8_t* codec_info) -> void {
109           A2DP_CodecName(codec_info);
110         },
111 
112         // A2DP_CodecTypeEquals
113         [](FuzzedDataProvider* fdp, uint8_t* codec_info) -> void {
114           uint8_t* codec_info_2 =
115               getArbitraryVectorElement(fdp, a2dp_codec_info_vect, false);
116           if (codec_info_2) {
117             A2DP_CodecTypeEquals(codec_info, codec_info_2);
118           }
119         },
120 
121         // A2DP_CodecEquals
122         [](FuzzedDataProvider* fdp, uint8_t* codec_info) -> void {
123           uint8_t* codec_info_2 =
124               getArbitraryVectorElement(fdp, a2dp_codec_info_vect, false);
125           if (codec_info_2) {
126             A2DP_CodecEquals(codec_info, codec_info_2);
127           }
128         },
129 
130         // A2DP_GetTrackSampleRate
131         [](FuzzedDataProvider* fdp, uint8_t* codec_info) -> void {
132           A2DP_GetTrackSampleRate(codec_info);
133         },
134 
135         // A2DP_GetTrackBitsPerSample
136         [](FuzzedDataProvider* fdp, uint8_t* codec_info) -> void {
137           A2DP_GetTrackBitsPerSample(codec_info);
138         },
139 
140         // A2DP_GetTrackChannelCount
141         [](FuzzedDataProvider* fdp, uint8_t* codec_info) -> void {
142           A2DP_GetTrackChannelCount(codec_info);
143         },
144 
145         // A2DP_GetSinkTrackChannelType
146         [](FuzzedDataProvider* fdp, uint8_t* codec_info) -> void {
147           A2DP_GetSinkTrackChannelType(codec_info);
148         },
149 
150         // A2DP_GetPacketTimestamp
151         [](FuzzedDataProvider* fdp, uint8_t* codec_info) -> void {
152           uint32_t timestamp_retval;
153           size_t packet_size =
154               fdp->ConsumeIntegralInRange<size_t>(0, MAX_PACKET_SIZE);
155           std::vector<uint8_t> bytes = fdp->ConsumeBytes<uint8_t>(packet_size);
156           // Timestamp will fail if p_data is < 4 bytes, due to a cast & deref
157           // to a uint32_t*
158           if (bytes.size() < 4) {
159             return;
160           }
161           const uint8_t* p_data = bytes.data();
162 
163           A2DP_GetPacketTimestamp(codec_info, p_data, &timestamp_retval);
164         },
165 
166         // A2DP_BuildCodecHeader
167         [](FuzzedDataProvider* fdp, uint8_t* codec_info) -> void {
168           std::shared_ptr<BT_HDR> p_buf = getArbitraryBtHdr(fdp);
169           if (p_buf) {
170             uint16_t frames_per_packet = fdp->ConsumeIntegral<uint16_t>();
171             A2DP_BuildCodecHeader(codec_info, p_buf.get(), frames_per_packet);
172           }
173         },
174 
175         // A2DP_GetEncoderInterface
176         [](FuzzedDataProvider* fdp, uint8_t* codec_info) -> void {
177           A2DP_GetEncoderInterface(codec_info);
178         },
179 
180         // A2DP_GetDecoderInterface
181         [](FuzzedDataProvider* fdp, uint8_t* codec_info) -> void {
182           A2DP_GetDecoderInterface(codec_info);
183         },
184 
185         // A2DP_AdjustCodec
186         [](FuzzedDataProvider* fdp, uint8_t* codec_info) -> void {
187           A2DP_AdjustCodec(codec_info);
188         },
189 
190         // A2DP_SourceCodecIndex
191         [](FuzzedDataProvider* fdp, uint8_t* codec_info) -> void {
192           A2DP_SourceCodecIndex(codec_info);
193         },
194 
195         // A2DP_SinkCodecIndex
196         [](FuzzedDataProvider* fdp, uint8_t* codec_info) -> void {
197           A2DP_SinkCodecIndex(codec_info);
198         },
199 
200         // A2DP_CodecIndexStr
201         [](FuzzedDataProvider* fdp, uint8_t*) -> void {
202           A2DP_CodecIndexStr(getArbitraryBtavCodecIndex(fdp));
203         },
204 
205         // A2DP_InitCodecConfig
206         [](FuzzedDataProvider* fdp, uint8_t*) -> void {
207           AvdtpSepConfig cfg_retval;
208           A2DP_InitCodecConfig(getArbitraryBtavCodecIndex(fdp), &cfg_retval);
209         },
210 
211         // A2DP_GetEecoderEffectiveFrameSize
212         [](FuzzedDataProvider* fdp, uint8_t* codec_info) -> void {
213           A2DP_GetEecoderEffectiveFrameSize(codec_info);
214         },
215 
216         // A2DP_CodecInfoString
217         [](FuzzedDataProvider* fdp, uint8_t* codec_info) -> void {
218           A2DP_CodecInfoString(codec_info);
219         }};
220 
221 #endif  // BT_STACK_FUZZ_A2DP_CODECINFO_FUNCTIONS_H_
222