Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions smitebot/src/commands/bench_exec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use crate::commands::build::{BuildInputs, run_build};
use crate::config::CampaignConfig;
use crate::latency_stats::{LatencyStats, avg_duration, mean_stddev};
use crate::libnyx::{Libnyx, NyxReturn, PAYLOAD_HEADER_SIZE};
use crate::utils::{pin_to_cpu, setup_nyx};
use crate::utils::{afl_bin_dir, pin_to_cpu, setup_nyx};

/// Default number of timed executions when `--iterations` is not given.
const DEFAULT_ITERATIONS: u64 = 1000;
Expand Down Expand Up @@ -487,7 +487,7 @@ fn locate_libnyx(config: &CampaignConfig) -> Option<PathBuf> {
return None;
}

let libnyx_path = config.aflpp_path.join("libnyx.so");
let libnyx_path = afl_bin_dir(&config.aflpp_path).join("libnyx.so");
if !libnyx_path.exists() {
log::error!(
"{} not found; build AFL++ with Nyx support (see nyx_mode/README.md)",
Expand Down
4 changes: 2 additions & 2 deletions smitebot/src/commands/corpus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use std::process::Command;
use clap::{Args, Subcommand};

use crate::state::CampaignState;
use crate::utils::{find_in_path, is_executable};
use crate::utils::{afl_bin_dir, find_in_path, is_executable};

/// Command handler for `smitebot corpus`.
pub struct CorpusCommand;
Expand Down Expand Up @@ -373,7 +373,7 @@ fn output_dir_occupied(output: &Path) -> bool {
/// searching `$PATH`.
fn find_afl_cmin(aflpp_path: Option<&Path>) -> Option<PathBuf> {
if let Some(path) = aflpp_path {
let candidate = path.join("afl-cmin");
let candidate = afl_bin_dir(path).join("afl-cmin");
if is_executable(&candidate) {
return Some(candidate);
}
Expand Down
14 changes: 7 additions & 7 deletions smitebot/src/commands/doctor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use clap::Args;
use serde::Serialize;

use crate::config::CampaignConfig;
use crate::utils::{find_in_path, is_executable};
use crate::utils::{afl_bin_dir, find_in_path, is_executable};

/// AFL++ binaries required for campaign execution and corpus minimization.
const AFL_TOOLS: &[&str] = &["afl-fuzz", "afl-cmin", "afl-tmin", "afl-whatsup"];
Expand Down Expand Up @@ -178,7 +178,7 @@ impl DoctorCommand {
None => None,
};
let inputs = DoctorInputs::resolve(config.as_ref(), args);
let aflpp_root = &inputs.aflpp_root;
let afl_bin = afl_bin_dir(&inputs.aflpp_root);
let smite_dir = &inputs.smite_dir;

// Keep a predictable order for operator readability and stable JSON output.
Expand All @@ -190,14 +190,14 @@ impl DoctorCommand {
),
DoctorCheck::new("/dev/kvm accessible", check_kvm_access()),
DoctorCheck::new("Docker daemon reachable", check_docker_daemon()),
DoctorCheck::new("AFL++ built with Nyx support", check_libnyx(aflpp_root)),
DoctorCheck::new("AFL++ built with Nyx support", check_libnyx(&afl_bin)),
DoctorCheck::new("VMware backdoor enabled", check_vmware_backdoor_enabled()),
];

for &tool in AFL_TOOLS {
checks.push(DoctorCheck::new(
tool,
require_executable(&aflpp_root.join(tool)),
require_executable(&afl_bin.join(tool)),
));
}

Expand Down Expand Up @@ -315,9 +315,9 @@ fn check_docker_daemon() -> Result<(), CheckFailure> {
}
}

/// Checks whether `libnyx.so` exists under the AFL++ root used for fuzzing.
fn check_libnyx(aflpp_root: &Path) -> Result<(), CheckFailure> {
if aflpp_root.join("libnyx.so").exists() {
/// Checks whether `libnyx.so` exists in AFL++'s binary directory.
fn check_libnyx(afl_bin: &Path) -> Result<(), CheckFailure> {
if afl_bin.join("libnyx.so").exists() {
Ok(())
} else {
Err(CheckFailure::LibnyxNotFound)
Expand Down
4 changes: 2 additions & 2 deletions smitebot/src/commands/start.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use crate::commands::build::{BuildInputs, run_build};
use crate::config::CampaignConfig;
use crate::state::{CampaignState, RunnerState, Status};
use crate::tmux;
use crate::utils::{command_stdout, docker_image_id, setup_nyx, shell_quote};
use crate::utils::{afl_bin_dir, command_stdout, docker_image_id, setup_nyx, shell_quote};

/// How long to wait for `fuzzer_stats` before treating alive runners as started.
///
Expand Down Expand Up @@ -503,7 +503,7 @@ fn build_runner_shell_cmd(
seed_dir: &Path,
testcache_mb: Option<u64>,
) -> String {
let afl_fuzz = config.aflpp_path.join("afl-fuzz");
let afl_fuzz = afl_bin_dir(&config.aflpp_path).join("afl-fuzz");
// -L (MOpt) is incompatible with custom mutators; runner_strategy skips it
// when an IR scenario or the user's afl_env supplies AFL_CUSTOM_MUTATOR_LIBRARY.
let has_custom_mutator = config.scenario.starts_with("ir")
Expand Down
29 changes: 29 additions & 0 deletions smitebot/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,19 @@ pub fn is_executable(path: &Path) -> bool {
fs::metadata(path).is_ok_and(|metadata| metadata.permissions().mode() & 0o111 != 0)
}

/// Returns the directory holding AFL++'s binaries and `libnyx.so`.
///
/// A source build keeps them at the tree root; an installed package puts them
/// under `bin/`.
pub fn afl_bin_dir(aflpp_path: &Path) -> PathBuf {
let bin = aflpp_path.join("bin");
if bin.join("afl-fuzz").is_file() {
bin
} else {
aflpp_path.to_path_buf()
}
}

/// Wraps a string in single quotes for safe interpolation into a shell command.
///
/// Embedded single quotes are escaped with the standard `'\''` idiom. Used for
Expand Down Expand Up @@ -201,6 +214,22 @@ mod tests {
assert!(found.is_none());
}

#[test]
fn afl_bin_dir_is_root_for_source_tree() {
let tempdir = tempfile::tempdir().unwrap();
fs::write(tempdir.path().join("afl-fuzz"), "").unwrap();
assert_eq!(afl_bin_dir(tempdir.path()), tempdir.path());
}

#[test]
fn afl_bin_dir_is_bin_for_installed_package() {
let tempdir = tempfile::tempdir().unwrap();
let bin = tempdir.path().join("bin");
fs::create_dir(&bin).unwrap();
fs::write(bin.join("afl-fuzz"), "").unwrap();
assert_eq!(afl_bin_dir(tempdir.path()), bin);
}

#[test]
fn shell_quote_wraps_in_single_quotes() {
assert_eq!(shell_quote("hello"), "'hello'");
Expand Down
Loading