Skip to content

Fuzzing in C #30

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

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
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
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "c_fuzzing/cJSON"]
path = c_fuzzing/cJSON
url = https://github.com/DaveGamble/cJSON
13 changes: 13 additions & 0 deletions c_fuzzing/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[package]
name = "c_fuzzing"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
cargo-fuzz = "0.11.2"
serde_json = "1.0.103"

[build-dependencies]
bindgen = "0.65.1"
7 changes: 7 additions & 0 deletions c_fuzzing/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Note on how to make it all work

* clone `cJSON` and run `make`
* cp the `libcjson.dylib.1.7.16` dynamic library to the root dir. There has to be a better way to make this work
* run bindgen `bindgen cJSON/cJSON.h > src/c_json.rs` to create the bindings
* create the `build.rs` file, copying and modifying the file shown in the [docs](https://rust-lang.github.io/rust-bindgen/non-system-libraries.html) seems to work fine

87 changes: 87 additions & 0 deletions c_fuzzing/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
//extern crate bindgen;

use std::env;
use std::path::PathBuf;

use bindgen::CargoCallbacks;

fn main() {
// This is the directory where the `c` library is located.
let libdir_path = PathBuf::from("cJSON")
// Canonicalize the path as `rustc-link-search` requires an absolute
// path.
.canonicalize()
.expect("cannot canonicalize path");

// This is the path to the `c` headers file.
let headers_path = libdir_path.join("cJSON.h");
let headers_path_str = headers_path.to_str().expect("Path is not a valid string");

// This is the path to the intermediate object file for our library.
let obj_path = libdir_path.join("cJSON.o");
// This is the path to the static library file.
let lib_path = libdir_path.join("libcjson.a");

// Tell cargo to look for shared libraries in the specified directory
println!("cargo:rustc-link-search={}", libdir_path.to_str().unwrap());

// Tell cargo to tell rustc to link our `hello` library. Cargo will
// automatically know it must look for a `libhello.a` file.
println!("cargo:rustc-link-lib=cjson");

// Tell cargo to invalidate the built crate whenever the header changes.
println!("cargo:rerun-if-changed={}", headers_path_str);

// Run `clang` to compile the `hello.c` file into a `hello.o` object file.
// Unwrap if it is not possible to spawn the process.
if !std::process::Command::new("clang")
.arg("-c")
.arg("-o")
.arg(&obj_path)
.arg(libdir_path.join("cJSON.c"))
.output()
.expect("could not spawn `clang`")
.status
.success()
{
// Panic if the command was not successful.
panic!("could not compile object file");
}

// Run `ar` to generate the `libhello.a` file from the `hello.o` file.
// Unwrap if it is not possible to spawn the process.
if !std::process::Command::new("ar")
.arg("rcs")
.arg(lib_path)
.arg(obj_path)
.output()
.expect("could not spawn `ar`")
.status
.success()
{
// Panic if the command was not successful.
panic!("could not emit library file");
}

// The bindgen::Builder is the main entry point
// to bindgen, and lets you build up options for
// the resulting bindings.
let bindings = bindgen::Builder::default()
// The input header we would like to generate
// bindings for.
.header(headers_path_str)
// Tell cargo to invalidate the built crate whenever any of the
// included header files changed.
.parse_callbacks(Box::new(CargoCallbacks))
// Finish the builder and generate the bindings.
.generate()
// Unwrap the Result and panic on failure.
.expect("Unable to generate bindings");

// Write the bindings to the $OUT_DIR/bindings.rs file.
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()).join("bindings.rs");
bindings
.write_to_file(out_path)
.expect("Couldn't write bindings!");
}

1 change: 1 addition & 0 deletions c_fuzzing/cJSON
Submodule cJSON added at cb8693
Loading