xref: /aosp_15_r20/external/gptfdisk/fuzzer/basicmbr_fuzzer.cc (revision 57696d54d05c64fd1b1787f8371dbcf104911cfb)
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