|
|
@ -25,10 +25,10 @@ constexpr char db_path[] = "/tmp/testdb"; |
|
|
|
// enum. The goal is to capture sanitizer bugs, so the code should be
|
|
|
|
// enum. The goal is to capture sanitizer bugs, so the code should be
|
|
|
|
// compiled with a given sanitizer (ASan, UBSan, MSan).
|
|
|
|
// compiled with a given sanitizer (ASan, UBSan, MSan).
|
|
|
|
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { |
|
|
|
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { |
|
|
|
rocksdb::DB* db; |
|
|
|
ROCKSDB_NAMESPACE::DB* db; |
|
|
|
rocksdb::Options options; |
|
|
|
ROCKSDB_NAMESPACE::Options options; |
|
|
|
options.create_if_missing = true; |
|
|
|
options.create_if_missing = true; |
|
|
|
rocksdb::Status status = rocksdb::DB::Open(options, db_path, &db); |
|
|
|
ROCKSDB_NAMESPACE::Status status = ROCKSDB_NAMESPACE::DB::Open(options, db_path, &db); |
|
|
|
if (!status.ok()) { |
|
|
|
if (!status.ok()) { |
|
|
|
return 0; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
} |
|
|
@ -43,18 +43,18 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { |
|
|
|
case kPut: { |
|
|
|
case kPut: { |
|
|
|
std::string key = fuzzed_data.ConsumeRandomLengthString(); |
|
|
|
std::string key = fuzzed_data.ConsumeRandomLengthString(); |
|
|
|
std::string val = fuzzed_data.ConsumeRandomLengthString(); |
|
|
|
std::string val = fuzzed_data.ConsumeRandomLengthString(); |
|
|
|
db->Put(rocksdb::WriteOptions(), key, val); |
|
|
|
db->Put(ROCKSDB_NAMESPACE::WriteOptions(), key, val); |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
case kGet: { |
|
|
|
case kGet: { |
|
|
|
std::string key = fuzzed_data.ConsumeRandomLengthString(); |
|
|
|
std::string key = fuzzed_data.ConsumeRandomLengthString(); |
|
|
|
std::string value; |
|
|
|
std::string value; |
|
|
|
db->Get(rocksdb::ReadOptions(), key, &value); |
|
|
|
db->Get(ROCKSDB_NAMESPACE::ReadOptions(), key, &value); |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
case kDelete: { |
|
|
|
case kDelete: { |
|
|
|
std::string key = fuzzed_data.ConsumeRandomLengthString(); |
|
|
|
std::string key = fuzzed_data.ConsumeRandomLengthString(); |
|
|
|
db->Delete(rocksdb::WriteOptions(), key); |
|
|
|
db->Delete(ROCKSDB_NAMESPACE::WriteOptions(), key); |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
case kGetProperty: { |
|
|
|
case kGetProperty: { |
|
|
@ -64,16 +64,16 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
case kIterator: { |
|
|
|
case kIterator: { |
|
|
|
rocksdb::Iterator* it = db->NewIterator(rocksdb::ReadOptions()); |
|
|
|
ROCKSDB_NAMESPACE::Iterator* it = db->NewIterator(ROCKSDB_NAMESPACE::ReadOptions()); |
|
|
|
for (it->SeekToFirst(); it->Valid(); it->Next()) { |
|
|
|
for (it->SeekToFirst(); it->Valid(); it->Next()) { |
|
|
|
} |
|
|
|
} |
|
|
|
delete it; |
|
|
|
delete it; |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
case kSnapshot: { |
|
|
|
case kSnapshot: { |
|
|
|
rocksdb::ReadOptions snapshot_options; |
|
|
|
ROCKSDB_NAMESPACE::ReadOptions snapshot_options; |
|
|
|
snapshot_options.snapshot = db->GetSnapshot(); |
|
|
|
snapshot_options.snapshot = db->GetSnapshot(); |
|
|
|
rocksdb::Iterator* it = db->NewIterator(snapshot_options); |
|
|
|
ROCKSDB_NAMESPACE::Iterator* it = db->NewIterator(snapshot_options); |
|
|
|
db->ReleaseSnapshot(snapshot_options.snapshot); |
|
|
|
db->ReleaseSnapshot(snapshot_options.snapshot); |
|
|
|
delete it; |
|
|
|
delete it; |
|
|
|
break; |
|
|
|
break; |
|
|
@ -81,51 +81,51 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { |
|
|
|
case kOpenClose: { |
|
|
|
case kOpenClose: { |
|
|
|
db->Close(); |
|
|
|
db->Close(); |
|
|
|
delete db; |
|
|
|
delete db; |
|
|
|
status = rocksdb::DB::Open(options, db_path, &db); |
|
|
|
status = ROCKSDB_NAMESPACE::DB::Open(options, db_path, &db); |
|
|
|
if (!status.ok()) { |
|
|
|
if (!status.ok()) { |
|
|
|
rocksdb::DestroyDB(db_path, options); |
|
|
|
ROCKSDB_NAMESPACE::DestroyDB(db_path, options); |
|
|
|
return 0; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
case kColumn: { |
|
|
|
case kColumn: { |
|
|
|
rocksdb::ColumnFamilyHandle* cf; |
|
|
|
ROCKSDB_NAMESPACE::ColumnFamilyHandle* cf; |
|
|
|
rocksdb::Status s; |
|
|
|
ROCKSDB_NAMESPACE::Status s; |
|
|
|
s = db->CreateColumnFamily(rocksdb::ColumnFamilyOptions(), "new_cf", |
|
|
|
s = db->CreateColumnFamily(ROCKSDB_NAMESPACE::ColumnFamilyOptions(), "new_cf", |
|
|
|
&cf); |
|
|
|
&cf); |
|
|
|
s = db->DestroyColumnFamilyHandle(cf); |
|
|
|
s = db->DestroyColumnFamilyHandle(cf); |
|
|
|
db->Close(); |
|
|
|
db->Close(); |
|
|
|
delete db; |
|
|
|
delete db; |
|
|
|
|
|
|
|
|
|
|
|
// open DB with two column families
|
|
|
|
// open DB with two column families
|
|
|
|
std::vector<rocksdb::ColumnFamilyDescriptor> column_families; |
|
|
|
std::vector<ROCKSDB_NAMESPACE::ColumnFamilyDescriptor> column_families; |
|
|
|
// have to open default column family
|
|
|
|
// have to open default column family
|
|
|
|
column_families.push_back(rocksdb::ColumnFamilyDescriptor( |
|
|
|
column_families.push_back(ROCKSDB_NAMESPACE::ColumnFamilyDescriptor( |
|
|
|
rocksdb::kDefaultColumnFamilyName, rocksdb::ColumnFamilyOptions())); |
|
|
|
ROCKSDB_NAMESPACE::kDefaultColumnFamilyName, ROCKSDB_NAMESPACE::ColumnFamilyOptions())); |
|
|
|
// open the new one, too
|
|
|
|
// open the new one, too
|
|
|
|
column_families.push_back(rocksdb::ColumnFamilyDescriptor( |
|
|
|
column_families.push_back(ROCKSDB_NAMESPACE::ColumnFamilyDescriptor( |
|
|
|
"new_cf", rocksdb::ColumnFamilyOptions())); |
|
|
|
"new_cf", ROCKSDB_NAMESPACE::ColumnFamilyOptions())); |
|
|
|
std::vector<rocksdb::ColumnFamilyHandle*> handles; |
|
|
|
std::vector<ROCKSDB_NAMESPACE::ColumnFamilyHandle*> handles; |
|
|
|
s = rocksdb::DB::Open(rocksdb::DBOptions(), db_path, column_families, |
|
|
|
s = ROCKSDB_NAMESPACE::DB::Open(ROCKSDB_NAMESPACE::DBOptions(), db_path, column_families, |
|
|
|
&handles, &db); |
|
|
|
&handles, &db); |
|
|
|
|
|
|
|
|
|
|
|
if (s.ok()) { |
|
|
|
if (s.ok()) { |
|
|
|
std::string key1 = fuzzed_data.ConsumeRandomLengthString(); |
|
|
|
std::string key1 = fuzzed_data.ConsumeRandomLengthString(); |
|
|
|
std::string val1 = fuzzed_data.ConsumeRandomLengthString(); |
|
|
|
std::string val1 = fuzzed_data.ConsumeRandomLengthString(); |
|
|
|
std::string key2 = fuzzed_data.ConsumeRandomLengthString(); |
|
|
|
std::string key2 = fuzzed_data.ConsumeRandomLengthString(); |
|
|
|
s = db->Put(rocksdb::WriteOptions(), handles[1], key1, val1); |
|
|
|
s = db->Put(ROCKSDB_NAMESPACE::WriteOptions(), handles[1], key1, val1); |
|
|
|
std::string value; |
|
|
|
std::string value; |
|
|
|
s = db->Get(rocksdb::ReadOptions(), handles[1], key2, &value); |
|
|
|
s = db->Get(ROCKSDB_NAMESPACE::ReadOptions(), handles[1], key2, &value); |
|
|
|
s = db->DropColumnFamily(handles[1]); |
|
|
|
s = db->DropColumnFamily(handles[1]); |
|
|
|
for (auto handle : handles) { |
|
|
|
for (auto handle : handles) { |
|
|
|
s = db->DestroyColumnFamilyHandle(handle); |
|
|
|
s = db->DestroyColumnFamilyHandle(handle); |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
status = rocksdb::DB::Open(options, db_path, &db); |
|
|
|
status = ROCKSDB_NAMESPACE::DB::Open(options, db_path, &db); |
|
|
|
if (!status.ok()) { |
|
|
|
if (!status.ok()) { |
|
|
|
// At this point there is no saving to do. So we exit
|
|
|
|
// At this point there is no saving to do. So we exit
|
|
|
|
rocksdb::DestroyDB(db_path, rocksdb::Options()); |
|
|
|
ROCKSDB_NAMESPACE::DestroyDB(db_path, ROCKSDB_NAMESPACE::Options()); |
|
|
|
return 0; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -135,15 +135,15 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { |
|
|
|
std::string slice_start = fuzzed_data.ConsumeRandomLengthString(); |
|
|
|
std::string slice_start = fuzzed_data.ConsumeRandomLengthString(); |
|
|
|
std::string slice_end = fuzzed_data.ConsumeRandomLengthString(); |
|
|
|
std::string slice_end = fuzzed_data.ConsumeRandomLengthString(); |
|
|
|
|
|
|
|
|
|
|
|
rocksdb::Slice begin(slice_start); |
|
|
|
ROCKSDB_NAMESPACE::Slice begin(slice_start); |
|
|
|
rocksdb::Slice end(slice_end); |
|
|
|
ROCKSDB_NAMESPACE::Slice end(slice_end); |
|
|
|
rocksdb::CompactRangeOptions options; |
|
|
|
ROCKSDB_NAMESPACE::CompactRangeOptions options; |
|
|
|
rocksdb::Status s = db->CompactRange(options, &begin, &end); |
|
|
|
ROCKSDB_NAMESPACE::Status s = db->CompactRange(options, &begin, &end); |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
case kSeekForPrev: { |
|
|
|
case kSeekForPrev: { |
|
|
|
std::string key = fuzzed_data.ConsumeRandomLengthString(); |
|
|
|
std::string key = fuzzed_data.ConsumeRandomLengthString(); |
|
|
|
auto iter = db->NewIterator(rocksdb::ReadOptions()); |
|
|
|
auto iter = db->NewIterator(ROCKSDB_NAMESPACE::ReadOptions()); |
|
|
|
iter->SeekForPrev(key); |
|
|
|
iter->SeekForPrev(key); |
|
|
|
delete iter; |
|
|
|
delete iter; |
|
|
|
break; |
|
|
|
break; |
|
|
@ -154,6 +154,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { |
|
|
|
// Cleanup DB
|
|
|
|
// Cleanup DB
|
|
|
|
db->Close(); |
|
|
|
db->Close(); |
|
|
|
delete db; |
|
|
|
delete db; |
|
|
|
rocksdb::DestroyDB(db_path, options); |
|
|
|
ROCKSDB_NAMESPACE::DestroyDB(db_path, options); |
|
|
|
return 0; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
} |
|
|
|