Merge RQ1A.210105.003 to aosp-master - DO NOT MERGE

Merged-In: I77e4f30cdea1d0e938a0693d70b27796294a75be
Change-Id: I45d2d1b2b51d7714187d23adc9a77ea70fe8581a
diff --git a/Android.bp b/Android.bp
index 11e2767..1aaa7e6 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,33 +1,11 @@
-cc_binary {
-    name: "sgdisk",
-    host_supported: true,
-
-    srcs: [
-        "sgdisk.cc",
-        "gptcl.cc",
-        "crc32.cc",
-        "support.cc",
-        "guid.cc",
-        "gptpart.cc",
-        "mbrpart.cc",
-        "basicmbr.cc",
-        "mbr.cc",
-        "gpt.cc",
-        "bsd.cc",
-        "parttypes.cc",
-        "attributes.cc",
-        "diskio.cc",
-        "diskio-unix.cc",
-        "android_popt.cc",
-    ],
+cc_defaults {
+    name: "gptfdisk_default_flags",
     cflags: [
         "-Wno-unused-parameter",
         "-Wno-pragma-pack",
         "-Werror",
+        "-fPIC",
     ],
-
-    shared_libs: ["libext2_uuid"],
-
     target: {
         darwin: {
             cflags: [
@@ -37,3 +15,56 @@
         },
     },
 }
+
+cc_binary {
+    name: "sgdisk",
+    defaults: ["gptfdisk_default_flags"],
+    host_supported: true,
+
+    srcs: [
+        "sgdisk.cc",
+    ],
+
+    shared_libs: ["libext2_uuid"],
+    static_libs: ["libgptf"],
+}
+
+lib_common_srcs = [
+    "gptcl.cc",
+    "crc32.cc",
+    "support.cc",
+    "guid.cc",
+    "gptpart.cc",
+    "mbrpart.cc",
+    "basicmbr.cc",
+    "mbr.cc",
+    "gpt.cc",
+    "bsd.cc",
+    "parttypes.cc",
+    "attributes.cc",
+    "diskio.cc",
+    "android_popt.cc",
+]
+
+cc_library_static {
+    name: "libgptf",
+    defaults: ["gptfdisk_default_flags"],
+    host_supported: true,
+
+    export_include_dirs: ["."],
+    srcs: lib_common_srcs + ["diskio-unix.cc"],
+
+    shared_libs: ["libext2_uuid"],
+}
+
+cc_library_static {
+    name: "libgptf_fuzzer_lib",
+    defaults: ["gptfdisk_default_flags"],
+    host_supported: true,
+
+    export_include_dirs: ["."],
+    srcs: lib_common_srcs + ["diskio-heap.cc"],
+    cflags: ["-DENABLE_HEAP_DISKIO"],
+
+    shared_libs: ["libext2_uuid"],
+}
diff --git a/METADATA b/METADATA
index b14e38f..e53a6a6 100644
--- a/METADATA
+++ b/METADATA
@@ -10,6 +10,7 @@
     value: "https://git.code.sf.net/p/gptfdisk/code"
   }
   version: "d292ff36a3b350115835c62462911c3d8721704f"
+  license_type: RESTRICTED
   last_upgrade_date {
     year: 2020
     month: 2
diff --git a/NOTICE b/NOTICE
deleted file mode 120000
index 7a694c9..0000000
--- a/NOTICE
+++ /dev/null
@@ -1 +0,0 @@
-LICENSE
\ No newline at end of file
diff --git a/diskio-heap.cc b/diskio-heap.cc
new file mode 100644
index 0000000..3129113
--- /dev/null
+++ b/diskio-heap.cc
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <algorithm>
+
+#include "diskio.h"
+
+using namespace std;
+
+int DiskIO::OpenForRead(const unsigned char* data, size_t size) {
+    this->data = data;
+    this->size = size;
+    this->off = 0;
+    this->isOpen = 1;
+    this->openForWrite = 0;
+    return 1;
+}
+
+void DiskIO::MakeRealName(void) {
+    realFilename = userFilename;
+}
+
+int DiskIO::OpenForRead(void) {
+    return 1;
+}
+
+int DiskIO::OpenForWrite(void) {
+    return 1;
+}
+
+void DiskIO::Close(void) {
+}
+
+int DiskIO::GetBlockSize(void) {
+    return 512;
+}
+
+int DiskIO::GetPhysBlockSize(void) {
+    return 512;
+}
+
+uint32_t DiskIO::GetNumHeads(void) {
+    return 255;
+}
+
+uint32_t DiskIO::GetNumSecsPerTrack(void) {
+    return 63;
+}
+
+int DiskIO::DiskSync(void) {
+    return 1;
+}
+
+int DiskIO::Seek(uint64_t sector) {
+    off_t off = sector * GetBlockSize();
+    if (off >= this->size) {
+        return 0;
+    } else {
+        this->off = off;
+        return 1;
+    }
+}
+
+int DiskIO::Read(void* buffer, int numBytes) {
+    int actualBytes = std::min(static_cast<int>(this->size - this->off), numBytes);
+    memcpy(buffer, this->data + this->off, actualBytes);
+    return actualBytes;
+}
+
+int DiskIO::Write(void*, int) {
+    return 0;
+}
+
+uint64_t DiskIO::DiskSize(int *) {
+    return this->size / GetBlockSize();
+}
diff --git a/diskio.h b/diskio.h
index 0bdaba4..8521b8e 100644
--- a/diskio.h
+++ b/diskio.h
@@ -57,11 +57,19 @@
 #else
       int fd;
 #endif
+#ifdef ENABLE_HEAP_DISKIO
+      const unsigned char* data;
+      size_t size;
+      off_t off;
+#endif
    public:
       DiskIO(void);
       ~DiskIO(void);
 
       void MakeRealName(void);
+#ifdef ENABLE_HEAP_DISKIO
+      int OpenForRead(const unsigned char* data, size_t size);
+#endif
       int OpenForRead(const string & filename);
       int OpenForRead(void);
       int OpenForWrite(const string & filename);
diff --git a/fuzzer/Android.bp b/fuzzer/Android.bp
new file mode 100644
index 0000000..ea92f96
--- /dev/null
+++ b/fuzzer/Android.bp
@@ -0,0 +1,22 @@
+cc_fuzz {
+    name: "libgptf_fuzzer",
+    srcs: ["libgptf_fuzzer.cc"],
+    cflags: ["-DENABLE_HEAP_DISKIO"],
+    host_supported: true,
+    corpus: ["corpus/*"],
+    static_libs: ["libgmock"],
+    target: {
+        android: {
+            static_libs: [
+                "libgptf_fuzzer_lib",
+                "libext2_uuid",
+            ],
+        },
+        host: {
+            static_libs: [
+                "libgptf_fuzzer_lib",
+                "libext2_uuid",
+            ],
+        },
+    },
+}
diff --git a/fuzzer/corpus/typical.bin b/fuzzer/corpus/typical.bin
new file mode 100644
index 0000000..666506e
--- /dev/null
+++ b/fuzzer/corpus/typical.bin
Binary files differ
diff --git a/fuzzer/libgptf_fuzzer.cc b/fuzzer/libgptf_fuzzer.cc
new file mode 100644
index 0000000..688167a
--- /dev/null
+++ b/fuzzer/libgptf_fuzzer.cc
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <fstream>
+#include <iostream>
+
+#include "diskio.h"
+#include "mbr.h"
+#include "gpt.h"
+
+#include <fuzzer/FuzzedDataProvider.h>
+
+std::ofstream silence("/dev/null");
+
+extern "C" int LLVMFuzzerInitialize(int *, char ***) {
+    std::cout.rdbuf(silence.rdbuf());
+    std::cerr.rdbuf(silence.rdbuf());
+    return 0;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+    DiskIO disk;
+    disk.OpenForRead(static_cast<const unsigned char*>(data), size);
+
+    BasicMBRData mbrData;
+    mbrData.ReadMBRData(&disk);
+
+    GPTData gptData;
+    gptData.SetDisk(disk);
+    gptData.LoadPartitions("/dev/does_not_exist");
+
+    return 0;
+}
diff --git a/gpt.cc b/gpt.cc
index 2d2e72c..8ab6975 100644
--- a/gpt.cc
+++ b/gpt.cc
@@ -780,6 +780,11 @@
    return allOK;
 } // GPTData::SetDisk()
 
+int GPTData::SetDisk(const DiskIO & disk) {
+   myDisk = disk;
+   return 1;
+} // GPTData::SetDisk()
+
 // Scan for partition data. This function loads the MBR data (regular MBR or
 // protective MBR) and loads BSD disklabel data (which is probably invalid).
 // It also looks for APM data, forces a load of GPT data, and summarizes
diff --git a/gpt.h b/gpt.h
index a5be961..0712a1f 100644
--- a/gpt.h
+++ b/gpt.h
@@ -112,6 +112,7 @@
 
    // Load or save data from/to disk
    int SetDisk(const string & deviceFilename);
+   int SetDisk(const DiskIO & disk);
    DiskIO* GetDisk(void) {return &myDisk;}
    int LoadMBR(const string & f) {return protectiveMBR.ReadMBRData(f);}
    int WriteProtectiveMBR(void) {return protectiveMBR.WriteMBRData(&myDisk);}