1  /*
2   * Copyright (c) 2022 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 "usbmgrbulkcancel_fuzzer.h"
17  
18  #include <array>
19  #include <optional>
20  
21  #include "ashmem.h"
22  #include "iremote_object.h"
23  #include "usb_callback_test.h"
24  #include "usb_common_fuzz.h"
25  #include "usb_errors.h"
26  
27  namespace {
28  const uint32_t OFFSET = 4;
29  constexpr size_t THRESHOLD = 10;
30  const uint32_t ASHMEM_MAX_SIZE = 1024;
31  const uint32_t MEM_DATA = 1024 * 1024;
32  }
33  namespace OHOS {
34  namespace USB {
GetSharedMem()35      sptr<Ashmem> GetSharedMem()
36      {
37          sptr<Ashmem> asmptr = Ashmem::CreateAshmem("ttashmem001", MEM_DATA);
38          if (asmptr == nullptr) {
39              USB_HILOGE(MODULE_USB_SERVICE, "InitAshmemOne CreateAshmem failed");
40              return nullptr;
41          }
42  
43          asmptr->MapReadAndWriteAshmem();
44  
45          std::array<uint8_t, ASHMEM_MAX_SIZE> tdata;
46          tdata.fill('Y');
47          uint32_t offset = 0;
48          while (offset < MEM_DATA) {
49              uint32_t tlen = (MEM_DATA - offset) < ASHMEM_MAX_SIZE ? (MEM_DATA - offset) : ASHMEM_MAX_SIZE;
50              asmptr->WriteToAshmem(tdata.data(), tlen, offset);
51              offset += tlen;
52          }
53          return asmptr;
54      }
55  
UsbMgrBulkCancelFuzzTest(const uint8_t * data,size_t)56      bool UsbMgrBulkCancelFuzzTest(const uint8_t* data, size_t /* size */)
57      {
58          auto[res, pipe, interface] = UsbMgrPrepareFuzzEnv();
59          if (!res) {
60              USB_HILOGE(MODULE_USB_SERVICE, "prepare error");
61              return false;
62          }
63  
64          auto& usbSrvClient = UsbSrvClient::GetInstance();
65          sptr<UsbCallbackTest> cb = new UsbCallbackTest();
66          USBEndpoint point = const_cast<UsbInterface &>(interface).GetEndpoints().at(1);
67          auto ret = usbSrvClient.RegBulkCallback(const_cast<USBDevicePipe &>(pipe), point, cb);
68          if (ret != UEC_OK) {
69              USB_HILOGE(MODULE_USB_SERVICE, "RegBulkCallback failed ret=%{public}d", ret);
70              return false;
71          }
72  
73          auto sharedMem = GetSharedMem();
74          if (sharedMem == nullptr) {
75              USB_HILOGE(MODULE_USB_SERVICE, "GetSharedMem failed ret=%{public}d", ret);
76              return false;
77          }
78  
79          ret = usbSrvClient.BulkWrite(const_cast<USBDevicePipe &>(pipe), point, sharedMem);
80          if (ret != UEC_OK) {
81              USB_HILOGE(MODULE_USB_SERVICE, "BulkWrite failed ret=%{public}d", ret);
82              return false;
83          }
84  
85          if (usbSrvClient.BulkCancel(reinterpret_cast<USBDevicePipe &>(data),
86              reinterpret_cast<const USBEndpoint&>(std::move(data + OFFSET))) == UEC_OK) {
87              return false;
88          }
89          return true;
90      }
91  } // USB
92  } // OHOS
93  
94  /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)95  extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
96  {
97      if (size < THRESHOLD) {
98          return 0;
99      }
100      /* Run your code on data */
101      OHOS::USB::UsbMgrBulkCancelFuzzTest(data, size);
102      return 0;
103  }
104