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 <MtpStringBuffer.h> 18 #include <fuzzer/FuzzedDataProvider.h> 19 #include <linux/usbdevice_fs.h> 20 #include <sys/mman.h> 21 #include <usbhost/usbhost.h> 22 #include <MtpTypes.h> 23 24 using namespace android; 25 constexpr UrbPacketDivisionMode kUrbPacketDivisionModes[] = {FIRST_PACKET_ONLY_HEADER, 26 FIRST_PACKET_HAS_PAYLOAD}; 27 28 constexpr size_t kMinSize = 0; 29 constexpr size_t kMaxSize = 1000; 30 constexpr size_t kMaxLength = 1000; 31 constexpr size_t kMaxPathLength = 64; 32 33 class MtpPacketFuzzerUtils { 34 protected: 35 struct usb_request mUsbRequest; 36 struct usbdevfs_urb* mUsbDevFsUrb; 37 std::string mPath; 38 fillFd(int32_t & fd,FuzzedDataProvider * fdp)39 void fillFd(int32_t& fd, FuzzedDataProvider* fdp) { 40 if (fdp->ConsumeBool()) { 41 std::string text = fdp->ConsumeRandomLengthString(kMaxLength); 42 write(fd, text.c_str(), text.length()); 43 } 44 }; 45 fillFilePath(FuzzedDataProvider * fdp)46 void fillFilePath(FuzzedDataProvider* fdp) { 47 mPath= fdp->ConsumeRandomLengthString(kMaxPathLength); 48 }; 49 fillUsbDevFsUrb(FuzzedDataProvider * fdp)50 void fillUsbDevFsUrb(FuzzedDataProvider* fdp) { 51 mUsbDevFsUrb->type = fdp->ConsumeIntegral<unsigned char>(); 52 mUsbDevFsUrb->endpoint = fdp->ConsumeIntegral<unsigned char>(); 53 mUsbDevFsUrb->flags = fdp->ConsumeIntegral<uint32_t>(); 54 std::vector<uint8_t> buffer = 55 fdp->ConsumeBytes<uint8_t>(fdp->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize)); 56 mUsbDevFsUrb->buffer = static_cast<void*>(buffer.data()); 57 mUsbDevFsUrb->buffer_length = buffer.size(); 58 mUsbDevFsUrb->actual_length = fdp->ConsumeIntegral<uint32_t>(); 59 mUsbDevFsUrb->start_frame = fdp->ConsumeIntegral<uint32_t>(); 60 mUsbDevFsUrb->number_of_packets = fdp->ConsumeIntegral<uint32_t>(); 61 mUsbDevFsUrb->stream_id = fdp->ConsumeIntegral<uint32_t>(); 62 mUsbDevFsUrb->error_count = fdp->ConsumeIntegral<size_t>(); 63 mUsbDevFsUrb->signr = fdp->ConsumeIntegral<uint32_t>(); 64 std::vector<uint8_t> userBuffer = (fdp->ConsumeBytes<uint8_t>( 65 fdp->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize))); 66 mUsbDevFsUrb->usercontext = static_cast<void*>(userBuffer.data()); 67 mUsbDevFsUrb->iso_frame_desc[0].length = fdp->ConsumeIntegral<uint32_t>(); 68 mUsbDevFsUrb->iso_frame_desc[0].actual_length = fdp->ConsumeIntegral<uint32_t>(); 69 }; 70 fillUsbRequest(int32_t & fd,FuzzedDataProvider * fdp)71 void fillUsbRequest(int32_t& fd, FuzzedDataProvider* fdp) { 72 fillUsbDevFsUrb(fdp); 73 fillFd(fd, fdp); 74 std::vector<uint8_t> buffer = 75 fdp->ConsumeBytes<uint8_t>(fdp->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize)); 76 mUsbRequest.buffer = static_cast<void*>(buffer.data()); 77 mUsbRequest.buffer_length = buffer.size(); 78 mUsbRequest.actual_length = fdp->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize); 79 mUsbRequest.max_packet_size = fdp->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize); 80 mUsbRequest.private_data = static_cast<void*>(mUsbDevFsUrb); 81 mUsbRequest.endpoint = fdp->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize); 82 std::vector<uint8_t> clientBuffer = (fdp->ConsumeBytes<uint8_t>( 83 fdp->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize))); 84 mUsbRequest.client_data = static_cast<void*>(clientBuffer.data()); 85 }; 86 87 template <typename Object> writeHandle(Object obj,FuzzedDataProvider * fdp)88 void writeHandle(Object obj, FuzzedDataProvider* fdp) { 89 MtpDevHandle handle; 90 std::vector<uint8_t> initData = 91 fdp->ConsumeBytes<uint8_t>(fdp->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize)); 92 handle.write(initData.data(), initData.size()); 93 obj->write(&handle); 94 }; 95 }; 96