summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulius Werner <jwerner@chromium.org>2019-10-17 18:01:02 -0700
committerManoj Gupta <manojgupta@chromium.org>2019-10-22 14:24:52 +0000
commit34307d894dfad7fdb962ab1b126d44a2a4a5fd68 (patch)
treecf1f8d3d790c30feffcc9197d432a03ed9f8001d
parent2abf0e7b7038b4ac12ea5edf7db00dad09a8e5c7 (diff)
downloadvboot-34307d894dfad7fdb962ab1b126d44a2a4a5fd68.tar.gz
tests: Add fuzzers for payload and preamble parsing
This patch adds fuzzers for vb2_load_fw_keyblock() and vb2_load_fw_preamble(). I'm new at fuzzing so please let me know if I did something dumb. BRANCH=None BUG=None TEST=Ran them manually with cros_fuzz. Change-Id: Ica39fcf4a3d250e69c51214afcee9e9815667ff8 Signed-off-by: Julius Werner <jwerner@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/1867969 Commit-Queue: Manoj Gupta <manojgupta@chromium.org>
-rw-r--r--Makefile4
-rw-r--r--tests/vb2_keyblock_fuzzer.c98
-rw-r--r--tests/vb2_preamble_fuzzer.c95
3 files changed, 196 insertions, 1 deletions
diff --git a/Makefile b/Makefile
index 93ac67c1..0bb8de90 100644
--- a/Makefile
+++ b/Makefile
@@ -783,7 +783,9 @@ TEST_KEYS = ${SRC_RUN}/tests/testkeys
# Fuzzing binaries
FUZZ_TEST_NAMES = \
- tests/cgpt_fuzzer
+ tests/cgpt_fuzzer \
+ tests/vb2_keyblock_fuzzer \
+ tests/vb2_preamble_fuzzer
FUZZ_TEST_BINS = $(addprefix ${BUILD}/,${FUZZ_TEST_NAMES})
FUZZ_TEST_OBJS += $(addsuffix .o,${FUZZ_TEST_BINS})
diff --git a/tests/vb2_keyblock_fuzzer.c b/tests/vb2_keyblock_fuzzer.c
new file mode 100644
index 00000000..7ac7499c
--- /dev/null
+++ b/tests/vb2_keyblock_fuzzer.c
@@ -0,0 +1,98 @@
+// 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 <assert.h>
+
+#include "2api.h"
+#include "2common.h"
+#include "2misc.h"
+#include "2rsa.h"
+#include "vboot_test.h"
+
+static struct vb2_context ctx;
+__attribute__((aligned(VB2_WORKBUF_ALIGN)))
+static uint8_t workbuf[VB2_FIRMWARE_WORKBUF_RECOMMENDED_SIZE];
+static struct {
+ struct vb2_gbb_header h;
+ uint8_t rootkey[4096];
+} gbb;
+
+static const uint8_t *mock_keyblock;
+static size_t mock_keyblock_size;
+
+/* Limit exposure of code for which we didn't set up the environment right. */
+void vb2api_fail(struct vb2_context *c, uint8_t reason, uint8_t subcode)
+{
+ return;
+}
+
+struct vb2_gbb_header *vb2_get_gbb(struct vb2_context *c)
+{
+ return &gbb.h;
+}
+
+vb2_error_t vb2ex_read_resource(struct vb2_context *c,
+ enum vb2_resource_index index, uint32_t offset,
+ void *buf, uint32_t size)
+{
+ const void *rbase;
+ size_t rsize;
+
+ switch (index) {
+ case VB2_RES_GBB:
+ rbase = &gbb;
+ rsize = sizeof(gbb);
+ break;
+ case VB2_RES_FW_VBLOCK:
+ rbase = mock_keyblock;
+ rsize = mock_keyblock_size;
+ break;
+ default:
+ return VB2_ERROR_EX_READ_RESOURCE_INDEX;
+ }
+
+ if (offset > rsize || rsize - offset < size)
+ return VB2_ERROR_EX_READ_RESOURCE_SIZE;
+
+ memcpy(buf, rbase + offset, size);
+ return VB2_SUCCESS;
+}
+
+/* Pretend that signature checks always succeed so the fuzzer can cover more. */
+vb2_error_t vb2_check_padding(const uint8_t *sig,
+ const struct vb2_public_key *key)
+{
+ return VB2_SUCCESS;
+}
+
+vb2_error_t vb2_safe_memcmp(const void *s1, const void *s2, size_t size)
+{
+ return VB2_SUCCESS;
+}
+
+int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size);
+int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ vb2_error_t rv;
+
+ if (size < sizeof(gbb.rootkey))
+ return 0;
+
+ memset(&gbb.h, 0, sizeof(gbb.h));
+ gbb.h.rootkey_offset = gbb.rootkey - (uint8_t *)&gbb;
+ gbb.h.rootkey_size = sizeof(gbb.rootkey);
+
+ memcpy(gbb.rootkey, data, sizeof(gbb.rootkey));
+ mock_keyblock = data + sizeof(gbb.rootkey);
+ mock_keyblock_size = size - sizeof(gbb.rootkey);
+
+ memset(&ctx, 0, sizeof(ctx));
+ ctx.workbuf = workbuf;
+ ctx.workbuf_size = sizeof(workbuf);
+ rv = vb2_init_context(&ctx);
+ assert(rv == VB2_SUCCESS);
+
+ vb2_load_fw_keyblock(&ctx);
+
+ return 0;
+}
diff --git a/tests/vb2_preamble_fuzzer.c b/tests/vb2_preamble_fuzzer.c
new file mode 100644
index 00000000..0ad2298e
--- /dev/null
+++ b/tests/vb2_preamble_fuzzer.c
@@ -0,0 +1,95 @@
+// 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 <assert.h>
+
+#include "2api.h"
+#include "2common.h"
+#include "2misc.h"
+#include "2rsa.h"
+#include "2secdata.h"
+#include "vboot_test.h"
+
+static struct vb2_context ctx;
+__attribute__((aligned(VB2_WORKBUF_ALIGN)))
+static uint8_t workbuf[VB2_FIRMWARE_WORKBUF_RECOMMENDED_SIZE];
+
+static const uint8_t *mock_preamble;
+static size_t mock_preamble_size;
+
+/* Limit exposure of code for which we didn't set up the environment right. */
+void vb2api_fail(struct vb2_context *c, uint8_t reason, uint8_t subcode)
+{
+ return;
+}
+
+void vb2_secdata_firmware_set(struct vb2_context *c,
+ enum vb2_secdata_firmware_param param,
+ uint32_t value)
+{
+ /* prevent abort from uninitialized secdata */
+}
+
+vb2_error_t vb2ex_read_resource(struct vb2_context *c,
+ enum vb2_resource_index index, uint32_t offset,
+ void *buf, uint32_t size)
+{
+ if (index != VB2_RES_FW_VBLOCK)
+ return VB2_ERROR_EX_READ_RESOURCE_INDEX;
+
+ /* The preamble_offset in our mock shared data is 0, so we can assume
+ that offset here is a direct offset into the preamble. */
+ if (offset > mock_preamble_size || mock_preamble_size - offset < size)
+ return VB2_ERROR_EX_READ_RESOURCE_SIZE;
+
+ memcpy(buf, mock_preamble + offset, size);
+ return VB2_SUCCESS;
+}
+
+/* Pretend that signature checks always succeed so the fuzzer can cover more. */
+vb2_error_t vb2_check_padding(const uint8_t *sig,
+ const struct vb2_public_key *key)
+{
+ return VB2_SUCCESS;
+}
+
+vb2_error_t vb2_safe_memcmp(const void *s1, const void *s2, size_t size)
+{
+ return VB2_SUCCESS;
+}
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+ const size_t datakey_size = 4096; // enough for all our signatures
+ vb2_error_t rv;
+
+ if (size < datakey_size)
+ return 0;
+
+ memset(&ctx, 0, sizeof(ctx));
+ ctx.workbuf = workbuf;
+ ctx.workbuf_size = sizeof(workbuf);
+ rv = vb2_init_context(&ctx);
+ assert(rv == VB2_SUCCESS);
+
+ struct vb2_workbuf wb;
+ vb2_workbuf_from_ctx(&ctx, &wb);
+
+ uint8_t *key = vb2_workbuf_alloc(&wb, datakey_size);
+ assert(key);
+ memcpy(key, data, datakey_size);
+
+ mock_preamble = data + datakey_size;
+ mock_preamble_size = size - datakey_size;
+
+ struct vb2_shared_data *sd = vb2_get_sd(&ctx);
+ sd->data_key_offset = vb2_offset_of(sd, key);
+ sd->data_key_size = datakey_size;
+ vb2_set_workbuf_used(&ctx, sd->data_key_offset + sd->data_key_size);
+
+ sd->vblock_preamble_offset = 0;
+ vb2_load_fw_preamble(&ctx);
+
+ return 0;
+}