nak: Add an instruction fuzzing tool

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24998>
This commit is contained in:
Faith Ekstrand 2023-01-30 20:53:17 -06:00 committed by Marge Bot
parent 90d3fd10e1
commit 241caaf5ff
2 changed files with 107 additions and 0 deletions

View file

@ -90,6 +90,15 @@ _libnak = static_library(
gnu_symbol_visibility : 'hidden',
)
if with_tools.contains('nouveau')
executable(
'nvfuzz',
files('nvfuzz.rs'),
rust_crate_type : 'bin',
install : true
)
endif
idep_nak = declare_dependency(
include_directories : include_directories('.'),
link_with : _libnak,

View file

@ -0,0 +1,98 @@
/*
* Copyright © 2022 Collabora, Ltd.
* SPDX-License-Identifier: MIT
*/
mod bitset;
mod util;
use crate::bitset::*;
use std::fs;
use std::io::Write;
use std::ops::Range;
use std::path::PathBuf;
use std::process::Command;
const TMP_FILE: &str = "/tmp/nvfuzz";
const SM: &str = "SM75";
fn find_cuda() -> std::io::Result<PathBuf> {
let paths = fs::read_dir("/usr/local")?;
for path in paths {
let mut path = path?.path();
let Some(fname) = path.file_name() else {
continue;
};
let Some(fname) = fname.to_str() else {
continue;
};
if !fname.starts_with("cuda-") {
continue;
}
path.push("bin");
path.push("nvdisasm");
if path.exists() {
return Ok(path)
}
}
Err(std::io::Error::new(
std::io::ErrorKind::NotFound,
"Failed to find nvdisasm",
))
}
//fn write_tmpfile(data: &[u32]) -> std::io::Result<()> {
// let mut file = std::fs::File::create(TMP_FILE)?;
// for dw in data {
// file.write(dw.to_le_bytes())?;
// }
//}
fn main() {
let args: Vec<String> = std::env::args().collect();
let range: Vec<&str> = args[1].split("..").collect();
let range: Range<usize> = Range {
start: range[0].parse().unwrap(),
end: range[1].parse().unwrap(),
};
let mut instr: [u32; 4] = [
u32::from_str_radix(&args[2], 16).unwrap(),
u32::from_str_radix(&args[3], 16).unwrap(),
u32::from_str_radix(&args[4], 16).unwrap(),
u32::from_str_radix(&args[5], 16).unwrap(),
];
let cuda_path = find_cuda().expect("Failed to find CUDA");
for bits in 0..(1_u64 << range.len()) {
BitSetMutView::new(&mut instr).set_field(range.clone(), bits);
print!("With {:#x} in {}..{}:", bits, range.start, range.end);
for dw in instr {
print!(" {:#x}", dw);
}
print!("\n");
let mut data = Vec::new();
for dw in instr {
data.extend(dw.to_le_bytes());
}
std::fs::write(TMP_FILE, data).expect("Failed to write file");
let out = Command::new(cuda_path.as_path())
.arg("-b")
.arg(SM)
.arg(TMP_FILE)
.output()
.expect("failed to execute process");
std::io::stderr().write_all(&out.stderr).expect("IO error");
std::io::stdout().write_all(&out.stdout).expect("IO error");
}
}