Skip to content

Proposal to change how cargo-afl manges AFL++ source code #605

@smoelius

Description

@smoelius

Currently, the cargo-afl source tree stores a copy of AFL++'s source code (i.e., as a git submodule).

I propose to eliminate the copy and manage the source code from a well-known directory sourced from AFL++'s repository.

I invite comments on this proposal.

Specifics

Currently, cargo-afl manages two types of directories within the user's $HOME directory. They are the following, where RUST_TOOLCHAIN is a string identifying a Rust toolchain (e.g., rustc-1.86.0-05f9846) and AFL_RS_VERSION is cargo-afl's version:

.local / share / afl.rs / RUST_TOOLCHAIN / AFL_RS_VERSION / afl
.local / share / afl.rs / RUST_TOOLCHAIN / AFL_RS_VERSION / afl-llvm

The afl directories contain the AFL++ installation, most notably, the AFL++ binaries (afl-fuzz, etc.). The afl-llvm directories contain compiled code needed to link fuzzing targets. The contents of these directories are produced by building a copy of AFL++'s source code stored in cargo-afl's source tree.

The proposal is to add:

.local / share / afl.rs / AFLplusplus

The AFLplusplus directory would contain a checkout of AFL++'s stable branch. The contents of the afl and afl-llvm directories would be built from this checkout.

Changes to cargo afl config

A --update flag would be added to the cargo afl config subcommand. Use of the flag would:

  • update the checkout in the AFLplusplus directory to match the head of AFL++'s stable branch (essentially, a git pull)
  • build the checkout and update the contents of the relevant afl and afl-llvm directories (essentially, what cargo afl config --build does now)

And optional --tag [TAG] flag could also be passed to update the checkout to a specific tag instead of the head of the stable branch. This would facilitate updating to a specific release, e.g.:

cargo afl config --update --tag v4.31c

Changes to cargo afl config --build

cargo-afl config --build would no longer build a copy of AFL++'s source code from cargo-afl's source tree (because cargo-afl's source tree would no longer contain a copy of AFL++'s source code).

Instead, cargo afl config --build would:

  • Check whether the following directory (repeated for convenience) exists, and if not, clone it from https://github.com/AFLplusplus/AFLplusplus:
    .local / share / afl.rs / AFLplusplus
    
  • Check whether the relevant afl and afl-llvm directories exist, and if not, build them from the checkout in the AFLplusplus directory.

Like now, the --force flag could be passed to force building the afl and afl-llvm directories' contents, even if the directories already exist.

Note: cargo-afl config --build would not attempt to update the contents of the AFLplusplus directory, or verify its integrity. Rather, cargo-afl config --build would treat the directory "as is". Thus, users could make changes to the directory's contents and run cargo-afl config --build --force to test them.

We would maintain this policy for now, and revisit/update the policy it if needed.

Benefits

  • Users could run new releases of AFL++ without having to wait for a new release of cargo-afl. Because cargo-afl currently uses a copy of AFL++'s source code stored in cargo-afl's source tree, cargo-afl must update whenever a new release of AFL++ is published. The proposed changes would eliminate this requirement.
  • Users would have more freedom to choose the AFL++ versions they run. Currently, each cargo-afl version is tied to a particular AFL++ version. The proposed changes would eliminate this attachment.
  • Experimenting with changes to AFL++ would be easier. Currently, experimenting with changes to AFL++ as used by cargo-afl requires cloning afl.rs. The proposed changes would allow AFL++ to be modified without involving afl.rs or cargo-afl's source code.
  • Maintaining cargo-afl would be easier. I (@smoelius) find git submodules unergonomic and I have botched two afl.rs releases recently because I had the wrong version of the submodule checked out. Eliminating the git submodule would eliminate this problem.

Drawbacks

  • Installing cargo-afl from scratch would require two steps. Downloading remote content during a cargo install is considered bad practice. Hence, users would need to run two commands to install cargo-afl:
    cargo install cargo-afl
    cargo afl config --build
    
    Note that, currently, installing cargo-afl does not have this problem because AFL++ is stored is cargo-afl's source tree. Hence, no remote content must be downloaded.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions