1 /*
2 * Copyright (c) 2024-2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <fstream>
17 #include "audio_input_thread.h"
18 #include "audio_log.h"
19 #include "audio_pnp_server.h"
20 #include "audio_socket_thread.h"
21 using namespace std;
22
23 namespace OHOS {
24 namespace AudioStandard {
25
26 class TestAudioPnpDeviceChangeCallback : public AudioPnpDeviceChangeCallback {
27 public:
~TestAudioPnpDeviceChangeCallback()28 virtual ~TestAudioPnpDeviceChangeCallback() {};
OnPnpDeviceStatusChanged(const std::string & info)29 void OnPnpDeviceStatusChanged(const std::string &info) {};
OnMicrophoneBlocked(const std::string & info)30 void OnMicrophoneBlocked(const std::string &info) {};
31 };
32
33 const int32_t NUM_2 = 2;
34 AudioPnpServer *audioPnpServer_ = &AudioPnpServer::GetAudioPnpServer();
35 typedef void (*TestPtr)(const uint8_t *, size_t);
36
37 const vector<PnpEventType> g_testPnpEventTypes = {
38 PNP_EVENT_DEVICE_ADD,
39 PNP_EVENT_DEVICE_REMOVE,
40 PNP_EVENT_LOAD_SUCCESS,
41 PNP_EVENT_LOAD_FAILURE,
42 PNP_EVENT_UNLOAD,
43 PNP_EVENT_SERVICE_VALID,
44 PNP_EVENT_SERVICE_INVALID,
45 PNP_EVENT_CAPTURE_THRESHOLD,
46 PNP_EVENT_UNKNOWN,
47 PNP_EVENT_MIC_BLOCKED,
48 PNP_EVENT_MIC_UNBLOCKED,
49 };
50
51 const vector<PnpDeviceType> g_testPnpDeviceTypes = {
52 PNP_DEVICE_LINEOUT,
53 PNP_DEVICE_HEADPHONE,
54 PNP_DEVICE_HEADSET,
55 PNP_DEVICE_USB_HEADSET,
56 PNP_DEVICE_USB_HEADPHONE,
57 PNP_DEVICE_USBA_HEADSET,
58 PNP_DEVICE_USBA_HEADPHONE,
59 PNP_DEVICE_PRIMARY_DEVICE,
60 PNP_DEVICE_USB_DEVICE,
61 PNP_DEVICE_A2DP_DEVICE,
62 PNP_DEVICE_HDMI_DEVICE,
63 PNP_DEVICE_ADAPTER_DEVICE,
64 PNP_DEVICE_DP_DEVICE,
65 PNP_DEVICE_MIC,
66 PNP_DEVICE_ACCESSORY,
67 PNP_DEVICE_UNKNOWN,
68 };
69
70 template<class T>
GetArrLength(T & arr)71 uint32_t GetArrLength(T& arr)
72 {
73 if (arr == nullptr) {
74 AUDIO_INFO_LOG("%{public}s: The array length is equal to 0", __func__);
75 return 0;
76 }
77 return sizeof(arr) / sizeof(arr[0]);
78 }
79
AudioPnpServerUnRegisterPnpStatusListenerFuzzTest(const uint8_t * rawData,size_t size)80 void AudioPnpServerUnRegisterPnpStatusListenerFuzzTest(const uint8_t *rawData, size_t size)
81 {
82 audioPnpServer_->UnRegisterPnpStatusListener();
83 }
84
AudioPnpServerOnPnpDeviceStatusChangedFuzzTest(const uint8_t * rawData,size_t size)85 void AudioPnpServerOnPnpDeviceStatusChangedFuzzTest(const uint8_t *rawData, size_t size)
86 {
87 std::string info = "test_info";
88 std::shared_ptr<AudioPnpDeviceChangeCallback> pnpCallback =
89 std::make_shared<TestAudioPnpDeviceChangeCallback>();
90 audioPnpServer_->pnpCallback_ = pnpCallback;
91 audioPnpServer_->OnPnpDeviceStatusChanged(info);
92 }
93
AudioPnpServerOnMicrophoneBlockedFuzzTest(const uint8_t * rawData,size_t size)94 void AudioPnpServerOnMicrophoneBlockedFuzzTest(const uint8_t *rawData, size_t size)
95 {
96 MicrophoneBlocked::GetInstance().OnMicrophoneBlocked("test_info", *audioPnpServer_);
97 }
98
AudioSocketThreadIsUpdatePnpDeviceStateFuzzTest(const uint8_t * rawData,size_t size)99 void AudioSocketThreadIsUpdatePnpDeviceStateFuzzTest(const uint8_t *rawData, size_t size)
100 {
101 uint32_t index = static_cast<uint32_t>(size);
102 AudioSocketThread audioSocketThread;
103 PnpEventType pnpEventType = g_testPnpEventTypes[index % g_testPnpEventTypes.size()];
104 PnpDeviceType pnpDeviceType = g_testPnpDeviceTypes[index % g_testPnpDeviceTypes.size()];
105 AudioEvent event;
106 event.eventType = static_cast<uint32_t>(pnpEventType);
107 event.deviceType = static_cast<uint32_t>(pnpDeviceType);
108 event.name = "Device1";
109 event.address = "Address1";
110 event.anahsName = "AnahsName1";
111
112 audioSocketThread.UpdatePnpDeviceState(&event);
113 audioSocketThread.IsUpdatePnpDeviceState(&event);
114 }
115
AudioSocketThreadSetAudioPnpServerEventValueFuzzTest(const uint8_t * rawData,size_t size)116 void AudioSocketThreadSetAudioPnpServerEventValueFuzzTest(const uint8_t *rawData, size_t size)
117 {
118 static const vector<string> testSubSystem = {
119 "audio",
120 "switch",
121 };
122 static const vector<string> testSwitchState = {
123 "0",
124 "1",
125 "2",
126 "3",
127 "4",
128 };
129 uint32_t index = static_cast<uint32_t>(size);
130 AudioSocketThread audioSocketThread;
131 PnpEventType pnpEventType = g_testPnpEventTypes[index % g_testPnpEventTypes.size()];
132 PnpDeviceType pnpDeviceType = g_testPnpDeviceTypes[index % g_testPnpDeviceTypes.size()];
133 AudioEvent event;
134 event.eventType = static_cast<uint32_t>(pnpEventType);
135 event.deviceType = static_cast<uint32_t>(pnpDeviceType);
136 event.name = "Device1";
137 event.address = "Address1";
138 event.anahsName = "AnahsName1";
139 AudioPnpUevent uevent = {
140 .action = "change",
141 .name = "headset",
142 .state = "MICROPHONE=0",
143 .devType = "extcon3",
144 .subSystem = testSubSystem[index % testSubSystem.size()].c_str(),
145 .switchName = "h2w",
146 .switchState = testSwitchState[index % testSwitchState.size()].c_str(),
147 .hidName = "hid",
148 .devName = "TestDevName",
149 .anahsName = "anahs"
150 };
151
152 audioSocketThread.SetAudioPnpServerEventValue(&event, &uevent);
153 }
154
AudioSocketThreadSetAudioAnahsEventValueFuzzTest(const uint8_t * rawData,size_t size)155 void AudioSocketThreadSetAudioAnahsEventValueFuzzTest(const uint8_t *rawData, size_t size)
156 {
157 static const vector<string> testAnahsNames = {
158 "INSERT",
159 "REMOVE",
160 };
161 uint32_t index = static_cast<uint32_t>(size);
162 AudioSocketThread audioSocketThread;
163 PnpEventType pnpEventType = g_testPnpEventTypes[index % g_testPnpEventTypes.size()];
164 PnpDeviceType pnpDeviceType = g_testPnpDeviceTypes[index % g_testPnpDeviceTypes.size()];
165 AudioEvent event;
166 event.eventType = static_cast<uint32_t>(pnpEventType);
167 event.deviceType = static_cast<uint32_t>(pnpDeviceType);
168 event.name = "Device1";
169 event.address = "Address1";
170 event.anahsName = "AnahsName1";
171 AudioPnpUevent uevent = {
172 .subSystem = "platform",
173 .anahsName = testAnahsNames[index % testAnahsNames.size()].c_str(),
174 };
175
176 audioSocketThread.SetAudioAnahsEventValue(&event, &uevent);
177 }
178
AudioSocketThreadAudioNnDetectDeviceFuzzTest(const uint8_t * rawData,size_t size)179 void AudioSocketThreadAudioNnDetectDeviceFuzzTest(const uint8_t *rawData, size_t size)
180 {
181 static const vector<string> testNames = {
182 "send_nn_state0",
183 "send_nn_state1",
184 "send_nn_state2",
185 "send_nn_state3",
186 };
187 uint32_t index = static_cast<uint32_t>(size);
188 AudioSocketThread audioSocketThread;
189 AudioPnpUevent uevent = {
190 .action = "change",
191 .name = testNames[index % testNames.size()].c_str(),
192 };
193
194 audioSocketThread.AudioNnDetectDevice(&uevent);
195 }
196
AudioSocketThreadAudioDpDetectDeviceFuzzTest(const uint8_t * rawData,size_t size)197 void AudioSocketThreadAudioDpDetectDeviceFuzzTest(const uint8_t *rawData, size_t size)
198 {
199 static const vector<string> testSwitchStates = {
200 "0",
201 "1",
202 "2",
203 };
204 uint32_t index = static_cast<uint32_t>(size);
205 AudioSocketThread audioSocketThread;
206 AudioPnpUevent uevent = {
207 .subSystem = "switch",
208 .switchName = "hdmi_audio",
209 .action = "change",
210 .switchState = testSwitchStates[index % testSwitchStates.size()].c_str(),
211 };
212 audioSocketThread.AudioDpDetectDevice(&uevent);
213 }
214
AudioSocketThreadAudioMicBlockDeviceFuzzTest(const uint8_t * rawData,size_t size)215 void AudioSocketThreadAudioMicBlockDeviceFuzzTest(const uint8_t *rawData, size_t size)
216 {
217 static const vector<string> testAudioPnpUeventName = {
218 "mic_blocked",
219 "mic_un_blocked",
220 "test_name",
221 };
222 auto audioSocketThread = std::make_shared<AudioSocketThread>();
223
224 bool testBool = static_cast<bool>(static_cast<uint32_t>(size) % NUM_2);
225 struct AudioPnpUevent audioPnpUevent;
226 audioPnpUevent.name = testAudioPnpUeventName[static_cast<uint32_t>(size) % testAudioPnpUeventName.size()].c_str();
227 struct AudioPnpUevent *audioPnpUeventPtr = &audioPnpUevent;
228 if (testBool) {
229 audioPnpUeventPtr = nullptr;
230 }
231 audioSocketThread->AudioMicBlockDevice(audioPnpUeventPtr);
232 }
233
AudioSocketThreadUpdateDeviceStateFuzzTest(const uint8_t * rawData,size_t size)234 void AudioSocketThreadUpdateDeviceStateFuzzTest(const uint8_t *rawData, size_t size)
235 {
236 auto audioSocketThread = std::make_shared<AudioSocketThread>();
237 AudioEvent updateEvent = {
238 static_cast<uint32_t>(size) % NUM_2,
239 static_cast<uint32_t>(size) % NUM_2 + 1,
240 "device",
241 "address",
242 "anahs",
243 };
244
245 audioSocketThread->UpdateDeviceState(updateEvent);
246 }
247
AudioSocketThreadReadAndScanDpNameFuzzTest(const uint8_t * rawData,size_t size)248 void AudioSocketThreadReadAndScanDpNameFuzzTest(const uint8_t *rawData, size_t size)
249 {
250 auto audioSocketThread = std::make_shared<AudioSocketThread>();
251 std::string testPath = "/tmp/test_path";
252 std::string testName = "test_name";
253 std::ofstream file(testPath);
254 file << testName;
255 file.close();
256 std::string name;
257 audioSocketThread->ReadAndScanDpName(testPath, name);
258 }
259
260 } // namespace AudioStandard
261 } // namesapce OHOS
262
263 OHOS::AudioStandard::TestPtr g_testPtrs[] = {
264 OHOS::AudioStandard::AudioPnpServerUnRegisterPnpStatusListenerFuzzTest,
265 OHOS::AudioStandard::AudioPnpServerOnPnpDeviceStatusChangedFuzzTest,
266 OHOS::AudioStandard::AudioPnpServerOnMicrophoneBlockedFuzzTest,
267 OHOS::AudioStandard::AudioSocketThreadIsUpdatePnpDeviceStateFuzzTest,
268 OHOS::AudioStandard::AudioSocketThreadSetAudioPnpServerEventValueFuzzTest,
269 OHOS::AudioStandard::AudioSocketThreadSetAudioAnahsEventValueFuzzTest,
270 OHOS::AudioStandard::AudioSocketThreadAudioNnDetectDeviceFuzzTest,
271 OHOS::AudioStandard::AudioSocketThreadAudioDpDetectDeviceFuzzTest,
272 OHOS::AudioStandard::AudioSocketThreadAudioMicBlockDeviceFuzzTest,
273 OHOS::AudioStandard::AudioSocketThreadUpdateDeviceStateFuzzTest,
274 OHOS::AudioStandard::AudioSocketThreadReadAndScanDpNameFuzzTest,
275 };
276
277 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)278 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
279 {
280 /* Run your code on data */
281 if (data == nullptr || size <= 1) {
282 return 0;
283 }
284 uint32_t len = OHOS::AudioStandard::GetArrLength(g_testPtrs);
285 if (len > 0) {
286 uint8_t firstByte = *data % len;
287 if (firstByte >= len) {
288 return 0;
289 }
290 data = data + 1;
291 size = size - 1;
292 g_testPtrs[firstByte](data, size);
293 }
294 return 0;
295 }