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*)>> 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>(0, a2dp_codec_info_vect.size() - 1);
54           // delete codec
55           delete a2dp_codec_info_vect.at(index);
56           // Remove from vector
57           a2dp_codec_info_vect.erase(a2dp_codec_info_vect.begin() + index);
58         },
59 
60         // A2DP_GetCodecType
61         [](FuzzedDataProvider* /*fdp*/, uint8_t* codec_info) -> void {
62           A2DP_GetCodecType(codec_info);
63         },
64 
65         // A2DP_IsSourceCodecValid
66         [](FuzzedDataProvider* /*fdp*/, uint8_t* codec_info) -> void {
67           A2DP_IsSourceCodecValid(codec_info);
68         },
69 
70         // A2DP_IsPeerSourceCodecValid
71         [](FuzzedDataProvider* /*fdp*/, uint8_t* codec_info) -> void {
72           A2DP_IsPeerSourceCodecValid(codec_info);
73         },
74 
75         // A2DP_IsPeerSinkCodecValid
76         [](FuzzedDataProvider* /*fdp*/, uint8_t* codec_info) -> void {
77           A2DP_IsPeerSinkCodecValid(codec_info);
78         },
79 
80         // A2DP_IsSinkCodecSupported
81         [](FuzzedDataProvider* /*fdp*/, uint8_t* codec_info) -> void {
82           A2DP_IsSinkCodecSupported(codec_info);
83         },
84 
85         // A2DP_UsesRtpHeader
86         [](FuzzedDataProvider* fdp, uint8_t* codec_info) -> void {
87           A2DP_UsesRtpHeader(fdp->ConsumeBool(), codec_info);
88         },
89 
90         // A2DP_GetMediaType
91         [](FuzzedDataProvider* /*fdp*/, uint8_t* codec_info) -> void {
92           A2DP_GetMediaType(codec_info);
93         },
94 
95         // A2DP_CodecName
96         [](FuzzedDataProvider* /*fdp*/, uint8_t* codec_info) -> void {
97           A2DP_CodecName(codec_info);
98         },
99 
100         // A2DP_CodecTypeEquals
101         [](FuzzedDataProvider* fdp, uint8_t* codec_info) -> void {
102           uint8_t* codec_info_2 = getArbitraryVectorElement(fdp, a2dp_codec_info_vect, false);
103           if (codec_info_2) {
104             A2DP_CodecTypeEquals(codec_info, codec_info_2);
105           }
106         },
107 
108         // A2DP_CodecEquals
109         [](FuzzedDataProvider* fdp, uint8_t* codec_info) -> void {
110           uint8_t* codec_info_2 = getArbitraryVectorElement(fdp, a2dp_codec_info_vect, false);
111           if (codec_info_2) {
112             A2DP_CodecEquals(codec_info, codec_info_2);
113           }
114         },
115 
116         // A2DP_GetTrackSampleRate
117         [](FuzzedDataProvider* /*fdp*/, uint8_t* codec_info) -> void {
118           A2DP_GetTrackSampleRate(codec_info);
119         },
120 
121         // A2DP_GetTrackBitsPerSample
122         [](FuzzedDataProvider* /*fdp*/, uint8_t* codec_info) -> void {
123           A2DP_GetTrackBitsPerSample(codec_info);
124         },
125 
126         // A2DP_GetTrackChannelCount
127         [](FuzzedDataProvider* /*fdp*/, uint8_t* codec_info) -> void {
128           A2DP_GetTrackChannelCount(codec_info);
129         },
130 
131         // A2DP_GetSinkTrackChannelType
132         [](FuzzedDataProvider* /*fdp*/, uint8_t* codec_info) -> void {
133           A2DP_GetSinkTrackChannelType(codec_info);
134         },
135 
136         // A2DP_GetPacketTimestamp
137         [](FuzzedDataProvider* fdp, uint8_t* codec_info) -> void {
138           uint32_t timestamp_retval;
139           size_t packet_size = fdp->ConsumeIntegralInRange<size_t>(0, MAX_PACKET_SIZE);
140           std::vector<uint8_t> bytes = fdp->ConsumeBytes<uint8_t>(packet_size);
141           // Timestamp will fail if p_data is < 4 bytes, due to a cast & deref
142           // to a uint32_t*
143           if (bytes.size() < 4) {
144             return;
145           }
146           const uint8_t* p_data = bytes.data();
147 
148           A2DP_GetPacketTimestamp(codec_info, p_data, &timestamp_retval);
149         },
150 
151         // A2DP_BuildCodecHeader
152         [](FuzzedDataProvider* fdp, uint8_t* codec_info) -> void {
153           std::shared_ptr<BT_HDR> p_buf = getArbitraryBtHdr(fdp);
154           if (p_buf) {
155             uint16_t frames_per_packet = fdp->ConsumeIntegral<uint16_t>();
156             A2DP_BuildCodecHeader(codec_info, p_buf.get(), frames_per_packet);
157           }
158         },
159 
160         // A2DP_GetEncoderInterface
161         [](FuzzedDataProvider* /*fdp*/, uint8_t* codec_info) -> void {
162           A2DP_GetEncoderInterface(codec_info);
163         },
164 
165         // A2DP_GetDecoderInterface
166         [](FuzzedDataProvider* /*fdp*/, uint8_t* codec_info) -> void {
167           A2DP_GetDecoderInterface(codec_info);
168         },
169 
170         // A2DP_AdjustCodec
171         [](FuzzedDataProvider* /*fdp*/, uint8_t* codec_info) -> void {
172           A2DP_AdjustCodec(codec_info);
173         },
174 
175         // A2DP_SourceCodecIndex
176         [](FuzzedDataProvider* /*fdp*/, uint8_t* codec_info) -> void {
177           A2DP_SourceCodecIndex(codec_info);
178         },
179 
180         // A2DP_SinkCodecIndex
181         [](FuzzedDataProvider* /*fdp*/, uint8_t* codec_info) -> void {
182           A2DP_SinkCodecIndex(codec_info);
183         },
184 
185         // A2DP_CodecIndexStr
186         [](FuzzedDataProvider* fdp, uint8_t*) -> void {
187           A2DP_CodecIndexStr(getArbitraryBtavCodecIndex(fdp));
188         },
189 
190         // A2DP_InitCodecConfig
191         [](FuzzedDataProvider* fdp, uint8_t*) -> void {
192           AvdtpSepConfig cfg_retval;
193           A2DP_InitCodecConfig(getArbitraryBtavCodecIndex(fdp), &cfg_retval);
194         },
195 
196         // A2DP_GetEecoderEffectiveFrameSize
197         [](FuzzedDataProvider* /*fdp*/, uint8_t* codec_info) -> void {
198           A2DP_GetEecoderEffectiveFrameSize(codec_info);
199         },
200 
201         // A2DP_CodecInfoString
202         [](FuzzedDataProvider* /*fdp*/, uint8_t* codec_info) -> void {
203           A2DP_CodecInfoString(codec_info);
204         }};
205 
206 #endif  // BT_STACK_FUZZ_A2DP_CODECINFO_FUNCTIONS_H_
207