diff options
author | Mattias Nissler <mnissler@chromium.org> | 2019-10-14 17:03:45 +0200 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-10-17 06:08:24 +0000 |
commit | 089a944d51778640d26a125123e1d1946c828e90 (patch) | |
tree | eb050cd9b57200e79d7daab55c4113a6b57fe3a3 /tests | |
parent | 7be3991ed441865f325182885ea08dc199ddbfd5 (diff) | |
download | vboot-089a944d51778640d26a125123e1d1946c828e90.tar.gz |
tests: Add cgpt fuzzer.stabilize-12607.6.Bstabilize-12607.5.Bstabilize-12607.3.Bstabilize-12607.15.B
This adds a fuzzer binary to exercise GPT parsing.
BUG=chromium:1014101
TEST=Build and run fuzzer.
BRANCH=none
Change-Id: Idecc0ddf491e976d4e01f5778e51a01ac317d961
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/1859595
Reviewed-by: Julius Werner <jwerner@chromium.org>
Tested-by: Manoj Gupta <manojgupta@chromium.org>
Commit-Queue: Manoj Gupta <manojgupta@chromium.org>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/cgpt_fuzzer.c | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/tests/cgpt_fuzzer.c b/tests/cgpt_fuzzer.c new file mode 100644 index 00000000..51ba72a3 --- /dev/null +++ b/tests/cgpt_fuzzer.c @@ -0,0 +1,86 @@ +// Copyright 2019 The Chromium OS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <stddef.h> +#include <stdint.h> + +#include "cgptlib.h" +#include "gpt.h" + +struct MockDisk { + size_t sector_shift; + const uint8_t* data; + size_t size; +}; + +// GPT disk parameters provided by the fuzzer test case. See GptData type +// definition for details. +struct GptDataParams { + uint32_t sector_shift; + uint32_t flags; + uint64_t streaming_drive_sectors; + uint64_t gpt_drive_sectors; +} __attribute__((packed)); + +static struct MockDisk mock_disk; + +vb2_error_t VbExDiskRead(VbExDiskHandle_t h, uint64_t lba_start, + uint64_t lba_count, void *buffer) +{ + size_t lba_size = mock_disk.size >> mock_disk.sector_shift; + if (lba_start > lba_size || lba_size - lba_start < lba_count) { + return VB2_ERROR_UNKNOWN; + } + + size_t start = lba_start << mock_disk.sector_shift; + size_t size = lba_count << mock_disk.sector_shift; + + memcpy(buffer, &mock_disk.data[start], size); + return VB2_SUCCESS; +} + +int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size); + +int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + struct GptDataParams params; + if (size < sizeof(params)) { + return 0; + } + memcpy(¶ms, data, sizeof(params)); + + // Enforce a sane sector size. The sector size must accommodate the GPT + // header (the code assumes this) and large values don't make sense + // either (both in terms of actual hardware parameters and ability for + // the fuzzer to deal with effectively). + if (params.sector_shift < 9) { + params.sector_shift = 9; // 512 byte sectors min. + } + if (params.sector_shift > 12) { + params.sector_shift = 12; // 4K sectors max. + } + + mock_disk.sector_shift = params.sector_shift; + mock_disk.data = data + sizeof(params); + mock_disk.size = size - sizeof(params); + + GptData gpt; + memset(&gpt, 0, sizeof(gpt)); + gpt.sector_bytes = 1ULL << params.sector_shift; + gpt.streaming_drive_sectors = params.streaming_drive_sectors; + gpt.gpt_drive_sectors = params.gpt_drive_sectors; + gpt.flags = params.flags; + + if (0 == AllocAndReadGptData(0, &gpt)) { + int result = GptInit(&gpt); + while (GPT_SUCCESS == result) { + uint64_t part_start, part_size; + result = GptNextKernelEntry(&gpt, &part_start, + &part_size); + } + } + + WriteAndFreeGptData(0, &gpt); + + return 0; +} |