Commit e953205d authored by Max Moroz's avatar Max Moroz Committed by Commit Bot

Implement leveldb_put_get_delete_fuzzer.

TBR=cmumford@chromium.org,pwnall@chromium.org

Bug: 900476
Change-Id: Ib126694fe3a60a9c6447a93b05a5bafe1f95fe09
Reviewed-on: https://chromium-review.googlesource.com/c/1356225
Commit-Queue: Max Moroz <mmoroz@chromium.org>
Reviewed-by: default avatarVictor Costan <pwnall@chromium.org>
Reviewed-by: default avatarMax Moroz <mmoroz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#612939}
parent 07670151
......@@ -2,6 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//testing/libfuzzer/fuzzer_test.gni")
import("//testing/test.gni")
defines = [ "LEVELDB_PLATFORM_CHROMIUM=1" ]
......@@ -452,3 +453,14 @@ if (!is_ios && !is_android) {
]
}
}
fuzzer_test("leveldb_put_get_delete_fuzzer") {
sources = [
"leveldb_put_get_delete_fuzzer.cc",
]
deps = [
":leveldatabase",
":leveldb_testutil",
"//base/test:test_support",
]
}
// Copyright 2018 The Chromium 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 "base/test/fuzzed_data_provider.h"
#include "leveldb/db.h"
#include "leveldb/env.h"
#include "third_party/leveldatabase/src/helpers/memenv/memenv.h"
#include "util/testharness.h"
using leveldb::DB;
using leveldb::Env;
using leveldb::Options;
using leveldb::ReadOptions;
using leveldb::Slice;
using leveldb::Status;
using leveldb::WriteOptions;
// We need to use keys and values both shorter and longer than 128 bytes in
// order to cover both fast and slow paths in DecodeEntry.
static constexpr size_t kMaxKeyLen = 256;
static constexpr size_t kMaxValueLen = 256;
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
Env* mem_env = NewMemEnv(Env::Default());
base::FuzzedDataProvider data_provider(data, size);
Options open_opts;
open_opts.create_if_missing = true;
open_opts.paranoid_checks = data_provider.ConsumeBool();
open_opts.reuse_logs = false;
open_opts.env = mem_env;
ReadOptions read_opts;
read_opts.verify_checksums = data_provider.ConsumeBool();
read_opts.fill_cache = data_provider.ConsumeBool();
WriteOptions write_opts;
write_opts.sync = data_provider.ConsumeBool();
DB* db = nullptr;
Status open_status = DB::Open(open_opts, "leveldbfuzztest", &db);
ASSERT_TRUE(open_status.ok());
// Put a couple constant values which must be successfully written.
ASSERT_OK(db->Put(write_opts, "key1", "val1"));
ASSERT_OK(db->Put(write_opts, "key2", "val2"));
// Split the data into a sequence of (key, value) strings and put those in.
// Also collect both keys and values to be used as keys for retrieval below.
std::vector<std::string> strings_used;
while (data_provider.remaining_bytes()) {
std::string key = data_provider.ConsumeRandomLengthString(kMaxKeyLen);
std::string value = data_provider.ConsumeRandomLengthString(kMaxValueLen);
db->Put(write_opts, key, value);
strings_used.push_back(key);
strings_used.push_back(value);
}
// Use all the strings we have extracted from the data previously as the keys.
for (const auto& key : strings_used) {
std::string db_value;
db->Get(read_opts, Slice(key.data(), key.size()), &db_value);
}
// Delete all keys previously written to the database.
for (const auto& key : strings_used) {
db->Delete(write_opts, Slice(key.data(), key.size()));
}
delete db;
db = nullptr;
delete mem_env;
mem_env = nullptr;
return 0;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment