xref: /aosp_15_r20/external/vboot_reference/tests/cgpt_fuzzer.c (revision 8617a60d3594060b7ecbd21bc622a7c14f3cf2bc)
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(&params, 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