Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Complete separation of afl and cargo-afl #375

Merged
merged 2 commits into from
Aug 28, 2023
Merged
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
9 changes: 4 additions & 5 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ jobs:
fail-fast: false
matrix:
environment: [ubuntu-latest, macos-latest]
package: [afl, cargo-afl]
toolchain: [stable, nightly]
cc: [cc, clang]
include:
Expand All @@ -56,11 +55,11 @@ jobs:
- name: Build
run: cargo build -vv
- name: Run afl-system-config
run: cargo run -p ${{ matrix.package }} -- afl system-config
run: cargo run -- afl system-config
- name: Build examples (with AFL instrumentation)
run: cargo run -p ${{ matrix.package }} -- afl build --examples -vv
- name: Run tests (with AFL instrumentation)
run: cargo run -p ${{ matrix.package }} -- afl test -vv
run: cargo run -- afl build --examples -vv
- name: Run tests
run: cargo test -p cargo-afl -vv
all-checks:
needs: [lint, build]
runs-on: ubuntu-latest
Expand Down
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[submodule "AFLplusplus"]
path = afl/AFLplusplus
path = cargo-afl/AFLplusplus
url = https://github.com/AFLplusplus/AFLplusplus.git
45 changes: 32 additions & 13 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@

<h4 align="center">Fuzzing <a href="https://www.rust-lang.org">Rust</a> code with <a href="https://aflplus.plus/">AFLplusplus</a></h4>

**Notice:** A future version of afl.rs will require you to install the `cargo-afl` binary with:
**Notice:** Version 0.14.0 of afl.rs requires you to install the `cargo-afl` binary with:

```sh
cargo install cargo-afl
```

You can use the new command now, if you like. If the binary is already installed, you may need to add `--force`.
If the binary is already installed, you may need to add `--force`.

## What is it?

Expand Down
1 change: 0 additions & 1 deletion afl/AFLplusplus
Submodule AFLplusplus deleted from ad2af7
8 changes: 0 additions & 8 deletions afl/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,16 @@ homepage = "https://github.com/rust-fuzz/afl.rs"
edition = "2021"

[build-dependencies]
fs_extra = "1.3"
home = "0.5"
libc = "0.2"
rustc_version = "0.4"
tempfile = "3.8"
xdg = "2.5"

[dependencies]
clap = { version = "4.4", features = ["cargo"] }
lazy_static = { version = "1.4", optional = true }
libc = "0.2"
rustc_version = "0.4"
xdg = "2.5"

[dev-dependencies]
arbitrary = { version = "1", features = ["derive"] }
assert_cmd = "2.0"
tempfile = "3.8"

[features]
reset_lazy_static = ["lazy_static"]
Expand Down
146 changes: 8 additions & 138 deletions afl/build.rs
Original file line number Diff line number Diff line change
@@ -1,148 +1,18 @@
use std::env;
use std::path::{Path, PathBuf};
use std::process::Command;

static AFL_SRC_PATH: &str = "AFLplusplus";

// https://github.com/rust-fuzz/afl.rs/issues/148
#[cfg(target_os = "macos")]
static AR_CMD: &str = "/usr/bin/ar";
#[cfg(not(target_os = "macos"))]
static AR_CMD: &str = "ar";

#[path = "src/common.rs"]
mod common;
use std::path::Path;

fn main() {
let installing = home::cargo_home()
let building_in_cargo_home = home::cargo_home()
.map(|path| Path::new(env!("CARGO_MANIFEST_DIR")).starts_with(path))
.unwrap()
|| env::var("TESTING_INSTALL").is_ok();

let building_cargo_afl = env::var("CARGO_PKG_NAME") == Ok(String::from("cargo-afl"));

let building_on_docs_rs = env::var("DOCS_RS").is_ok();

let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
|| env::var("TESTING_BUILD").is_ok();

if installing && !building_cargo_afl {
println!("cargo:warning=You appear to be installing the `cargo-afl` binary with:");
println!("cargo:warning= cargo install afl");
println!("cargo:warning=A future version of afl.rs will require you to use:");
println!("cargo:warning= cargo install cargo-afl");
println!("cargo:warning=You can use the new command now, if you like.");
println!(
"cargo:warning=Note: If the binary is already installed, you may need to add --force."
);
}

std::fs::write(
out_dir.join("help.txt"),
if building_cargo_afl {
String::new()
} else {
String::from("\n\n") + common::HELP_MSG
},
)
.unwrap();

// smoelius: Build AFLplusplus in a temporary directory when installing or when building on docs.rs.
let work_dir = if installing || building_on_docs_rs {
let tempdir = tempfile::tempdir_in(&out_dir).unwrap();
if Path::new(AFL_SRC_PATH).join(".git").is_dir() {
let status = Command::new("git")
.args(["clone", AFL_SRC_PATH, &*tempdir.path().to_string_lossy()])
.status()
.expect("could not run 'git'");
assert!(status.success());
} else {
fs_extra::dir::copy(
AFL_SRC_PATH,
tempdir.path(),
&fs_extra::dir::CopyOptions {
content_only: true,
..Default::default()
},
)
.unwrap();
}
tempdir.into_path()
} else {
PathBuf::from(AFL_SRC_PATH)
};
let cfg_fuzzing = env::var("CARGO_CFG_FUZZING").is_ok();

let base = if building_on_docs_rs {
Some(out_dir)
} else {
None
};

// smoelius: Lock `work_dir` until the build script exits.
#[cfg(unix)]
let _file = sys::lock_path(&work_dir).unwrap();

build_afl(&work_dir, base.as_deref());
build_afl_llvm_runtime(&work_dir, base.as_deref());
}

fn build_afl(work_dir: &Path, base: Option<&Path>) {
let mut command = Command::new("make");
command
.current_dir(work_dir)
.args(["clean", "all", "install"])
// skip the checks for the legacy x86 afl-gcc compiler
.env("AFL_NO_X86", "1")
// build just the runtime to avoid troubles with Xcode clang on macOS
.env("NO_BUILD", "1")
.env("DESTDIR", common::afl_dir(base))
.env("PREFIX", "")
.env_remove("DEBUG");
let status = command.status().expect("could not run 'make'");
assert!(status.success());
}

fn build_afl_llvm_runtime(work_dir: &Path, base: Option<&Path>) {
std::fs::copy(
work_dir.join("afl-compiler-rt.o"),
common::object_file_path(base),
)
.expect("Couldn't copy object file");

let status = Command::new(AR_CMD)
.arg("r")
.arg(common::archive_file_path(base))
.arg(common::object_file_path(base))
.status()
.expect("could not run 'ar'");
assert!(status.success());
}

#[cfg(unix)]
mod sys {
use std::fs::File;
use std::io::{Error, Result};
use std::os::unix::io::AsRawFd;
use std::path::Path;

pub fn lock_path(path: &Path) -> Result<File> {
let file = File::open(path)?;
lock_exclusive(&file)?;
Ok(file)
}

// smoelius: `lock_exclusive` and `flock` were copied from:
// https://github.com/rust-lang/cargo/blob/ae91d4ed41da98bdfa16041dbc6cd30287920120/src/cargo/util/flock.rs

fn lock_exclusive(file: &File) -> Result<()> {
flock(file, libc::LOCK_EX)
}
let feature_no_fuzzing = env::var("CARGO_FEATURE_NO_FUZZING").is_ok();

fn flock(file: &File, flag: libc::c_int) -> Result<()> {
let ret = unsafe { libc::flock(file.as_raw_fd(), flag) };
if ret < 0 {
Err(Error::last_os_error())
} else {
Ok(())
}
if building_in_cargo_home && !cfg_fuzzing && !feature_no_fuzzing {
println!("cargo:warning=You appear to be building `afl` not under `cargo-afl`.");
println!("cargo:warning=Perhaps you used `cargo build` instead of `cargo afl build`?");
}
}
Loading