1 /*
2 * Copyright (C) 2024 The Android Open Source Project
3 *
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14 #include <fstream>
15 #include <iostream>
16 #include <functional>
17 #include "diskio.h"
18 #include "mbr.h"
19
20 #include <fuzzer/FuzzedDataProvider.h>
21
22 const std::string kTempFile = "/dev/tempfile";
23 const std::string kNull = "/dev/null";
24
25 std::ofstream silence(kNull);
26
27 class BasicMBRFuzzer {
28 public:
BasicMBRFuzzer(const uint8_t * data,size_t size)29 BasicMBRFuzzer(const uint8_t *data, size_t size) : mFdp(data, size) {
30 mDisk.OpenForRead(static_cast<const unsigned char *>(data), size);
31 }
32
~BasicMBRFuzzer()33 ~BasicMBRFuzzer() { mDisk.Close(); }
34
35 void process();
36
37 private:
38 DiskIO mDisk;
39 FuzzedDataProvider mFdp;
40 };
41
process()42 void BasicMBRFuzzer::process() {
43 BasicMBRData mbrData;
44 if (mFdp.ConsumeBool()) {
45 BasicMBRData mbrDataFile(kTempFile);
46 mbrData = mbrDataFile;
47 }
48
49 bool isLegal = false;
50
51 while (mFdp.remaining_bytes()) {
52 auto invokeMBRAPI = mFdp.PickValueInArray<const std::function<void()>>({
53 [&]() {
54 mbrData.SetDisk(&mDisk);
55 },
56 [&]() {
57 if (mDisk.OpenForWrite(kTempFile)) {
58 mbrData.WriteMBRData(kTempFile);
59 }
60 mbrData.ReadMBRData(&mDisk);
61 },
62 [&]() {
63 uint32_t low, high;
64 mbrData.GetPartRange(&low, &high);
65 },
66 [&]() {
67 mbrData.MakeBiggestPart(mFdp.ConsumeIntegral<uint8_t>() /* index */,
68 mFdp.ConsumeIntegral<uint8_t>() /* type */);
69 },
70 [&]() {
71 mbrData.SetPartType(mFdp.ConsumeIntegral<uint8_t>() /* num */,
72 mFdp.ConsumeIntegral<uint8_t>() /* type */);
73 },
74 [&]() {
75 mbrData.FindFirstInFree(mFdp.ConsumeIntegral<uint64_t>() /* start */);
76 },
77 [&]() {
78 mbrData.GetFirstSector(mFdp.ConsumeIntegral<uint8_t>() /* index */);
79 },
80 [&]() {
81 if (!isLegal) {
82 mbrData.MakeItLegal();
83 isLegal = true;
84 }
85 },
86 });
87 invokeMBRAPI();
88 }
89 mbrData.BlankGPTData();
90 }
91
LLVMFuzzerInitialize(int *,char ***)92 extern "C" int LLVMFuzzerInitialize(int *, char ***) {
93 std::cout.rdbuf(silence.rdbuf());
94 std::cerr.rdbuf(silence.rdbuf());
95 return 0;
96 }
97
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)98 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
99 BasicMBRFuzzer basicMBRFuzzer(data, size);
100 basicMBRFuzzer.process();
101 return 0;
102 }
103