Bug 1584446 - Add an rkv fuzzing test for bug mdb_cursor_put, r=truber

Differential Revision: https://phabricator.services.mozilla.com/D47396

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Victor Porof 2019-10-02 15:17:13 +00:00
Родитель 9f89b08062
Коммит 48062bb200
5 изменённых файлов: 66 добавлений и 39 удалений

1
Cargo.lock сгенерированный
Просмотреть файл

@ -1136,6 +1136,7 @@ version = "0.1.0"
dependencies = [
"libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
"rkv 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
"tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]

Просмотреть файл

@ -5,6 +5,7 @@ authors = ["fuzzing@mozilla.com"]
[dependencies]
libc = "0.2"
tempfile = "3"
[dependencies.rkv]
version = "0.10.2"

Просмотреть файл

@ -8,4 +8,6 @@
int FuzzingInitDummy(int* argc, char*** argv) { return 0; }
MOZ_FUZZING_INTERFACE_RAW(FuzzingInitDummy, fuzz_rkv, Rkv);
MOZ_FUZZING_INTERFACE_RAW(FuzzingInitDummy, fuzz_rkv_db_file, RkvDbFile);
MOZ_FUZZING_INTERFACE_RAW(FuzzingInitDummy, fuzz_rkv_key_write, RkvKeyWrite);
MOZ_FUZZING_INTERFACE_RAW(FuzzingInitDummy, fuzz_rkv_val_write, RkvValWrite);

Просмотреть файл

@ -12,7 +12,9 @@
extern "C" {
int fuzz_rkv(const uint8_t* raw_data, size_t size);
int fuzz_rkv_db_file(const uint8_t* raw_data, size_t size);
int fuzz_rkv_key_write(const uint8_t* raw_data, size_t size);
int fuzz_rkv_val_write(const uint8_t* raw_data, size_t size);
} // extern "C"

Просмотреть файл

@ -3,13 +3,25 @@
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
extern crate libc;
extern crate rkv;
extern crate tempfile;
use std::fs;
use std::fs::File;
use std::io::Write;
use std::path::Path;
use tempfile::Builder;
macro_rules! try_or_ret {
($expr:expr) => {{
match $expr {
Ok(v) => v,
Err(_) => return 0,
}
}};
}
#[no_mangle]
pub extern fn fuzz_rkv(raw_data: *const u8, size: libc::size_t) -> libc::c_int {
pub extern "C" fn fuzz_rkv_db_file(raw_data: *const u8, size: libc::size_t) -> libc::c_int {
let data = unsafe { std::slice::from_raw_parts(raw_data as *const u8, size as usize) };
// First 8192 bytes are for the lock file.
@ -17,41 +29,50 @@ pub extern fn fuzz_rkv(raw_data: *const u8, size: libc::size_t) -> libc::c_int {
return 0;
}
let (lock, db) = data.split_at(8192);
let mut lock_file = match File::create("data.mdb") {
Ok(lock_file) => lock_file,
Err(_) => return 0,
};
match lock_file.write_all(lock) {
Ok(_) => {}
Err(_) => return 0,
};
let mut db_file = match File::create("data.mdb") {
Ok(db_file) => db_file,
Err(_) => return 0,
};
match db_file.write_all(db) {
Ok(_) => {}
Err(_) => return 0,
};
let env = {
let mut builder = rkv::Rkv::environment_builder();
builder.set_max_dbs(2);
match rkv::Rkv::from_env(Path::new("."), builder) {
Ok(env) => env,
Err(_) => return 0,
}
};
let store = match env.open_single("cert_storage", rkv::StoreOptions::create()) {
Ok(store) => store,
Err(_) => return 0,
};
let reader = match env.read() {
Ok(reader) => reader,
Err(_) => return 0,
};
match store.get(&reader, &[0]) {
Ok(_) => {}
Err(_) => {}
};
let mut lock_file = try_or_ret!(File::create("data.lock"));
try_or_ret!(lock_file.write_all(lock));
let mut db_file = try_or_ret!(File::create("data.mdb"));
try_or_ret!(db_file.write_all(db));
let &mut builder = rkv::Rkv::environment_builder().set_max_dbs(2);
let env = try_or_ret!(rkv::Rkv::from_env(Path::new("."), builder));
let store = try_or_ret!(env.open_single("test", rkv::StoreOptions::create()));
let reader = try_or_ret!(env.read());
try_or_ret!(store.get(&reader, &[0]));
0
}
#[no_mangle]
pub extern "C" fn fuzz_rkv_key_write(raw_data: *const u8, size: libc::size_t) -> libc::c_int {
let data = unsafe { std::slice::from_raw_parts(raw_data as *const u8, size as usize) };
let root = try_or_ret!(Builder::new().prefix("fuzz_rkv_key_write").tempdir());
try_or_ret!(fs::create_dir_all(root.path()));
let env = try_or_ret!(rkv::Rkv::new(root.path()));
let store: rkv::SingleStore = try_or_ret!(env.open_single("test", rkv::StoreOptions::create()));
let mut writer = try_or_ret!(env.write());
try_or_ret!(store.put(&mut writer, data, &rkv::Value::Str("val")));
0
}
#[no_mangle]
pub extern "C" fn fuzz_rkv_val_write(raw_data: *const u8, size: libc::size_t) -> libc::c_int {
let data = unsafe { std::slice::from_raw_parts(raw_data as *const u8, size as usize) };
let root = try_or_ret!(Builder::new().prefix("fuzz_rkv_val_write").tempdir());
try_or_ret!(fs::create_dir_all(root.path()));
let env = try_or_ret!(rkv::Rkv::new(root.path()));
let store: rkv::SingleStore = try_or_ret!(env.open_single("test", rkv::StoreOptions::create()));
let mut writer = try_or_ret!(env.write());
let value = rkv::Value::Str(try_or_ret!(std::str::from_utf8(data)));
try_or_ret!(store.put(&mut writer, "key", &value));
0
}