• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }