blob: 9e5402816b8d2a2e744f8d388fce53aa0d2e0f6b [file] [log] [blame]
// 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 <base/logging.h>
#include <fuzzer/FuzzedDataProvider.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include "hammerd/fmap_utils.h"
#include "hammerd/update_fw.h"
#include "hammerd/vb21_struct.h"
namespace hammerd {
class Environment {
public:
Environment() { logging::SetMinLogLevel(logging::LOGGING_FATAL); }
};
namespace {
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
static Environment env;
FirmwareUpdater fw_updater_(nullptr); // no endpoint required to load EC
FuzzedDataProvider data_provider(data, size);
const char* ec_ro_name = "EC_RO";
const char* ro_frid_name = "RO_FRID";
const char* ec_rw_name = "EC_RW";
const char* ec_fwid_name = "EC_FWID";
const char* rw_rbver_name = "RW_RBVER";
const char* key_ro_name = "KEY_RO";
// Build a fake EC image.
// - Fake header: 5 bytes
// - fake fmap: sizeof(fmap) bytes
// - 6 fake fmap areas
// - EC_RO
// - RO_FRID
// - EC_RW
// - RW_FWID
// - RW_RBVER
// - KEY_RO
// - RO version string: 32 bytes
// - RW version string: 32 bytes
// - RW rollback version: 4 bytes
// - RO key: sizeof(vb21_packed_key) bytes
std::string ec_image("12345");
fmap fake_map;
fake_map.nareas = data_provider.ConsumeIntegralInRange<uint16_t>(4, 6);
fake_map.size = 5 + sizeof(fmap) + (sizeof(fmap_area) * fake_map.nareas) +
32 + 32 + 4 + sizeof(vb21_packed_key);
memcpy(fake_map.signature, FMAP_SIGNATURE, sizeof(FMAP_SIGNATURE));
ec_image.append(reinterpret_cast<char*>(&fake_map), sizeof(fake_map));
// Setup areas
fmap_area fake_area;
snprintf(reinterpret_cast<char*>(fake_area.name), sizeof(fake_area.name),
"%s", ec_ro_name);
fake_area.offset = data_provider.ConsumeIntegral<uint32_t>();
fake_area.size = data_provider.ConsumeIntegral<uint32_t>();
ec_image.append(reinterpret_cast<char*>(&fake_area), sizeof(fake_area));
snprintf(reinterpret_cast<char*>(fake_area.name), sizeof(fake_area.name),
"%s", ro_frid_name);
fake_area.size = sizeof(SectionInfo::version);
fake_area.offset = data_provider.ConsumeIntegral<uint32_t>();
ec_image.append(reinterpret_cast<char*>(&fake_area), sizeof(fake_area));
snprintf(reinterpret_cast<char*>(fake_area.name), sizeof(fake_area.name),
"%s", ec_rw_name);
fake_area.offset = data_provider.ConsumeIntegral<uint32_t>();
fake_area.size = data_provider.ConsumeIntegral<uint32_t>();
ec_image.append(reinterpret_cast<char*>(&fake_area), sizeof(fake_area));
snprintf(reinterpret_cast<char*>(fake_area.name), sizeof(fake_area.name),
"%s", ec_fwid_name);
fake_area.size = sizeof(SectionInfo::version);
fake_area.offset = data_provider.ConsumeIntegral<uint32_t>();
ec_image.append(reinterpret_cast<char*>(&fake_area), sizeof(fake_area));
if (fake_map.nareas > 4) {
snprintf(reinterpret_cast<char*>(fake_area.name), sizeof(fake_area.name),
"%s", rw_rbver_name);
fake_area.offset = data_provider.ConsumeIntegral<uint32_t>();
fake_area.size = data_provider.ConsumeIntegral<uint32_t>();
ec_image.append(reinterpret_cast<char*>(&fake_area), sizeof(fake_area));
}
if (fake_map.nareas > 5) {
snprintf(reinterpret_cast<char*>(fake_area.name), sizeof(fake_area.name),
"%s", key_ro_name);
fake_area.offset = data_provider.ConsumeIntegral<uint32_t>();
fake_area.size = data_provider.ConsumeIntegral<uint32_t>();
ec_image.append(reinterpret_cast<char*>(&fake_area), sizeof(fake_area));
}
char ro_version[32] = "UNUSED RO FAKE VERSION";
ec_image.append(ro_version, 32);
char rw_version[32] = "UNUSED RW FAKE VERSION";
ec_image.append(rw_version, 32);
int32_t rw_rollback = 35;
ec_image.append(reinterpret_cast<char*>(&rw_rollback), sizeof(rw_rollback));
vb21_packed_key ro_key;
ro_key.key_version = 1;
ec_image.append(reinterpret_cast<char*>(&ro_key), sizeof(ro_key));
fw_updater_.LoadEcImage(ec_image);
return 0;
}
} // namespace
} // namespace hammerd