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