1*8617a60dSAndroid Build Coastguard Worker // Copyright 2019 The ChromiumOS Authors
2*8617a60dSAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*8617a60dSAndroid Build Coastguard Worker // found in the LICENSE file.
4*8617a60dSAndroid Build Coastguard Worker
5*8617a60dSAndroid Build Coastguard Worker #include <stddef.h>
6*8617a60dSAndroid Build Coastguard Worker #include <stdint.h>
7*8617a60dSAndroid Build Coastguard Worker
8*8617a60dSAndroid Build Coastguard Worker #include "cgptlib.h"
9*8617a60dSAndroid Build Coastguard Worker #include "gpt.h"
10*8617a60dSAndroid Build Coastguard Worker
11*8617a60dSAndroid Build Coastguard Worker struct MockDisk {
12*8617a60dSAndroid Build Coastguard Worker size_t sector_shift;
13*8617a60dSAndroid Build Coastguard Worker const uint8_t* data;
14*8617a60dSAndroid Build Coastguard Worker size_t size;
15*8617a60dSAndroid Build Coastguard Worker };
16*8617a60dSAndroid Build Coastguard Worker
17*8617a60dSAndroid Build Coastguard Worker // GPT disk parameters provided by the fuzzer test case. See GptData type
18*8617a60dSAndroid Build Coastguard Worker // definition for details.
19*8617a60dSAndroid Build Coastguard Worker struct GptDataParams {
20*8617a60dSAndroid Build Coastguard Worker uint32_t sector_shift;
21*8617a60dSAndroid Build Coastguard Worker uint32_t flags;
22*8617a60dSAndroid Build Coastguard Worker uint64_t streaming_drive_sectors;
23*8617a60dSAndroid Build Coastguard Worker uint64_t gpt_drive_sectors;
24*8617a60dSAndroid Build Coastguard Worker } __attribute__((packed));
25*8617a60dSAndroid Build Coastguard Worker
26*8617a60dSAndroid Build Coastguard Worker static struct MockDisk mock_disk;
27*8617a60dSAndroid Build Coastguard Worker
VbExDiskRead(vb2ex_disk_handle_t h,uint64_t lba_start,uint64_t lba_count,void * buffer)28*8617a60dSAndroid Build Coastguard Worker vb2_error_t VbExDiskRead(vb2ex_disk_handle_t h, uint64_t lba_start,
29*8617a60dSAndroid Build Coastguard Worker uint64_t lba_count, void *buffer)
30*8617a60dSAndroid Build Coastguard Worker {
31*8617a60dSAndroid Build Coastguard Worker size_t lba_size = mock_disk.size >> mock_disk.sector_shift;
32*8617a60dSAndroid Build Coastguard Worker if (lba_start > lba_size || lba_size - lba_start < lba_count) {
33*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_UNKNOWN;
34*8617a60dSAndroid Build Coastguard Worker }
35*8617a60dSAndroid Build Coastguard Worker
36*8617a60dSAndroid Build Coastguard Worker size_t start = lba_start << mock_disk.sector_shift;
37*8617a60dSAndroid Build Coastguard Worker size_t size = lba_count << mock_disk.sector_shift;
38*8617a60dSAndroid Build Coastguard Worker
39*8617a60dSAndroid Build Coastguard Worker memcpy(buffer, &mock_disk.data[start], size);
40*8617a60dSAndroid Build Coastguard Worker return VB2_SUCCESS;
41*8617a60dSAndroid Build Coastguard Worker }
42*8617a60dSAndroid Build Coastguard Worker
43*8617a60dSAndroid Build Coastguard Worker int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size);
44*8617a60dSAndroid Build Coastguard Worker
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)45*8617a60dSAndroid Build Coastguard Worker int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
46*8617a60dSAndroid Build Coastguard Worker struct GptDataParams params;
47*8617a60dSAndroid Build Coastguard Worker if (size < sizeof(params)) {
48*8617a60dSAndroid Build Coastguard Worker return 0;
49*8617a60dSAndroid Build Coastguard Worker }
50*8617a60dSAndroid Build Coastguard Worker memcpy(¶ms, data, sizeof(params));
51*8617a60dSAndroid Build Coastguard Worker
52*8617a60dSAndroid Build Coastguard Worker // Enforce a valid sector size. The sector size must accommodate the GPT
53*8617a60dSAndroid Build Coastguard Worker // header (the code assumes this) and large values don't make sense
54*8617a60dSAndroid Build Coastguard Worker // either (both in terms of actual hardware parameters and ability for
55*8617a60dSAndroid Build Coastguard Worker // the fuzzer to deal with effectively).
56*8617a60dSAndroid Build Coastguard Worker if (params.sector_shift < 9) {
57*8617a60dSAndroid Build Coastguard Worker params.sector_shift = 9; // 512 byte sectors min.
58*8617a60dSAndroid Build Coastguard Worker }
59*8617a60dSAndroid Build Coastguard Worker if (params.sector_shift > 12) {
60*8617a60dSAndroid Build Coastguard Worker params.sector_shift = 12; // 4K sectors max.
61*8617a60dSAndroid Build Coastguard Worker }
62*8617a60dSAndroid Build Coastguard Worker
63*8617a60dSAndroid Build Coastguard Worker mock_disk.sector_shift = params.sector_shift;
64*8617a60dSAndroid Build Coastguard Worker mock_disk.data = data + sizeof(params);
65*8617a60dSAndroid Build Coastguard Worker mock_disk.size = size - sizeof(params);
66*8617a60dSAndroid Build Coastguard Worker
67*8617a60dSAndroid Build Coastguard Worker GptData gpt;
68*8617a60dSAndroid Build Coastguard Worker memset(&gpt, 0, sizeof(gpt));
69*8617a60dSAndroid Build Coastguard Worker gpt.sector_bytes = 1ULL << params.sector_shift;
70*8617a60dSAndroid Build Coastguard Worker gpt.streaming_drive_sectors = params.streaming_drive_sectors;
71*8617a60dSAndroid Build Coastguard Worker gpt.gpt_drive_sectors = params.gpt_drive_sectors;
72*8617a60dSAndroid Build Coastguard Worker gpt.flags = params.flags;
73*8617a60dSAndroid Build Coastguard Worker
74*8617a60dSAndroid Build Coastguard Worker if (0 == AllocAndReadGptData(0, &gpt)) {
75*8617a60dSAndroid Build Coastguard Worker int result = GptInit(&gpt);
76*8617a60dSAndroid Build Coastguard Worker while (GPT_SUCCESS == result) {
77*8617a60dSAndroid Build Coastguard Worker uint64_t part_start, part_size;
78*8617a60dSAndroid Build Coastguard Worker result = GptNextKernelEntry(&gpt, &part_start,
79*8617a60dSAndroid Build Coastguard Worker &part_size);
80*8617a60dSAndroid Build Coastguard Worker }
81*8617a60dSAndroid Build Coastguard Worker }
82*8617a60dSAndroid Build Coastguard Worker
83*8617a60dSAndroid Build Coastguard Worker WriteAndFreeGptData(0, &gpt);
84*8617a60dSAndroid Build Coastguard Worker
85*8617a60dSAndroid Build Coastguard Worker return 0;
86*8617a60dSAndroid Build Coastguard Worker }
87