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