• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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 #include <MtpDataPacket.h>
18 #include <MtpDevHandle.h>
19 #include <MtpPacketFuzzerUtils.h>
20 #include <MtpProperty.h>
21 #include <fuzzer/FuzzedDataProvider.h>
22 #include <utils/String16.h>
23 
24 using namespace android;
25 
26 constexpr uint16_t kFeasibleTypes[] = {
27         MTP_TYPE_UNDEFINED, MTP_TYPE_INT8,    MTP_TYPE_UINT8,  MTP_TYPE_INT16,   MTP_TYPE_UINT16,
28         MTP_TYPE_INT32,     MTP_TYPE_UINT32,  MTP_TYPE_INT64,  MTP_TYPE_UINT64,  MTP_TYPE_INT128,
29         MTP_TYPE_UINT128,   MTP_TYPE_AINT8,   MTP_TYPE_AUINT8, MTP_TYPE_AINT16,  MTP_TYPE_AUINT16,
30         MTP_TYPE_AINT32,    MTP_TYPE_AUINT32, MTP_TYPE_AINT64, MTP_TYPE_AUINT64, MTP_TYPE_AINT128,
31         MTP_TYPE_AUINT128,  MTP_TYPE_STR,
32 };
33 
34 class MtpPropertyFuzzer : MtpPacketFuzzerUtils {
35   public:
MtpPropertyFuzzer(const uint8_t * data,size_t size)36     MtpPropertyFuzzer(const uint8_t* data, size_t size) : mFdp(data, size) {
37         mUsbDevFsUrb = (struct usbdevfs_urb*)malloc(sizeof(struct usbdevfs_urb) +
38                                                     sizeof(struct usbdevfs_iso_packet_desc));
39     };
~MtpPropertyFuzzer()40     ~MtpPropertyFuzzer() { free(mUsbDevFsUrb); };
41     void process();
42 
43   private:
44     FuzzedDataProvider mFdp;
45 };
46 
process()47 void MtpPropertyFuzzer::process() {
48     MtpProperty* mtpProperty = nullptr;
49     if (mFdp.ConsumeBool()) {
50         mtpProperty = new MtpProperty();
51     } else {
52         uint16_t type = mFdp.ConsumeBool() ? mFdp.ConsumeIntegral<uint16_t>()
53                                            : mFdp.PickValueInArray<uint16_t>(kFeasibleTypes);
54         mtpProperty = new MtpProperty(mFdp.ConsumeIntegral<uint16_t>(), type, mFdp.ConsumeBool(),
55                                       mFdp.ConsumeIntegral<uint16_t>());
56     }
57 
58     while (mFdp.remaining_bytes() > 0) {
59         auto invokeMtpPropertyFuzzer = mFdp.PickValueInArray<const std::function<void()>>({
60                 [&]() {
61                     MtpDataPacket mtpDataPacket;
62                     if (mFdp.ConsumeBool()) {
63                         mtpProperty->read(mtpDataPacket);
64 
65                     } else {
66                         if (mFdp.ConsumeBool()) {
67 #ifdef MTP_DEVICE
68                             android::IMtpHandle* h = new MtpDevHandle();
69                             h->start(mFdp.ConsumeBool());
70                             std::string text = mFdp.ConsumeRandomLengthString(kMaxLength);
71                             char* data = const_cast<char*>(text.c_str());
72                             h->read(static_cast<void*>(data), text.length());
73                             mtpDataPacket.write(h);
74                             h->close();
75                             delete h;
76 #endif
77 
78 #ifdef MTP_HOST
79                             fillFilePath(&mFdp);
80                             int32_t fd = memfd_create(mPath.c_str(), MFD_ALLOW_SEALING);
81                             fillUsbRequest(fd, &mFdp);
82                             mUsbRequest.dev = usb_device_new(mPath.c_str(), fd);
83                             mtpDataPacket.write(&mUsbRequest,
84                                                 mFdp.PickValueInArray<UrbPacketDivisionMode>(
85                                                         kUrbPacketDivisionModes),
86                                                 fd,
87                                                 mFdp.ConsumeIntegralInRange(kMinSize, kMaxSize));
88                             usb_device_close(mUsbRequest.dev);
89 #endif
90                         }
91 
92                         if (mFdp.ConsumeBool()) {
93                             mtpProperty->write(mtpDataPacket);
94                         } else {
95                             mtpProperty->setCurrentValue(mtpDataPacket);
96                         }
97                     }
98                 },
99                 [&]() {
100                     char16_t* data = nullptr;
101                     std::string str = mFdp.ConsumeRandomLengthString(kMaxLength);
102                     android::String16 s(str.c_str());
103                     if (mFdp.ConsumeBool()) {
104                         data = const_cast<char16_t*>(s.string());
105                     }
106 
107                     if (mFdp.ConsumeBool()) {
108                         mtpProperty->setDefaultValue(reinterpret_cast<uint16_t*>(data));
109                     } else if (mFdp.ConsumeBool()) {
110                         mtpProperty->setCurrentValue(reinterpret_cast<uint16_t*>(data));
111                     } else {
112                         mtpProperty->setCurrentValue(str.c_str());
113                     }
114                 },
115                 [&]() {
116                     mtpProperty->setFormRange(mFdp.ConsumeIntegral<int32_t>(),
117                                               mFdp.ConsumeIntegral<int32_t>(),
118                                               mFdp.ConsumeIntegral<int32_t>());
119                 },
120                 [&]() {
121                     std::vector<int32_t> init;
122                     for (size_t idx = 0; idx < mFdp.ConsumeIntegralInRange(kMinSize, kMaxSize);
123                          ++idx) {
124                         init.push_back(mFdp.ConsumeIntegral<int32_t>());
125                     }
126                     mtpProperty->setFormEnum(init.data(), init.size());
127                 },
128         });
129         invokeMtpPropertyFuzzer();
130     }
131 
132     delete (mtpProperty);
133 }
134 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)135 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
136     MtpPropertyFuzzer mtpPropertyFuzzer(data, size);
137     mtpPropertyFuzzer.process();
138     return 0;
139 }
140