Skip to content

Add casr-lua to casr-libfuzzer #242

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 3 commits into
base: master
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
15 changes: 14 additions & 1 deletion .github/workflows/amd64.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,20 @@ jobs:
- name: Run tests
run: |
sudo apt update && sudo apt install -y gdb pip curl python3-dev llvm \
openjdk-17-jdk ca-certificates gnupg lua5.4
openjdk-17-jdk ca-certificates gnupg libcurl4-gnutls-dev
wget https://www.lua.org/ftp/lua-5.4.7.tar.gz && tar zxf lua-5.4.7.tar.gz && cd lua-5.4.7 && \
sed -i 's/std=gnu99/std=gnu99 -fPIC/1' src/Makefile && \
sed -i 's/Wextra/Wextra -fPIC/1' src/Makefile && make all test && sudo make install
ln -s $(which lua) $(which lua)5.4
wget https://luarocks.org/releases/luarocks-3.11.1.tar.gz && tar zxpf luarocks-3.11.1.tar.gz && \
cd luarocks-3.11.1 && ./configure && make && sudo make install && cd .. && rm -rf luarocks-3.11.1.tar.gz luarocks-3.11.1
luarocks path >> ~/.bashrc
wget https://github.com/tarantool/luajit/archive/refs/tags/v2.1.0-beta3.tar.gz && \
tar zxpf v2.1.0-beta3.tar.gz && rm v2.1.0-beta3.tar.gz && cd luajit-2.1.0-beta3 && \
make && sudo make install && sudo ln -sf luajit-2.1.0-beta3 /usr/local/bin/luajit && cd .. && rm -rf luajit-2.1.0-beta3
git clone https://github.com/ligurio/luzer.git && \
cd luzer && git checkout e1756e509bb29ea6c2f215beec8973d2d3c239f4 && luarocks build --local build && cd ..
export LUA_CPATH="/home/runner/work/casr/casr/luzer/build.luarocks/luzer/?.so;$LUA_CPATH"
# Atheris fails to install on Ubuntu 24.04, see https://github.com/google/atheris/issues/82
# pip3 install atheris
sudo mkdir -p /etc/apt/keyrings
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/coverage.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ jobs:
run: |
rustup component add llvm-tools-preview
cargo +nightly build --all-features --verbose
cargo +nightly test --verbose --lib -- --test-threads 1
cargo +nightly test --verbose --package casr
cargo +nightly test --verbose --lib -- --test-threads 1 --skip test_casr_libfuzzer_luzer
cargo +nightly test --verbose --package casr -- --skip test_casr_libfuzzer_luzer
- name: Collect Coverage
run: |
mkdir target/coverage
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -246,8 +246,9 @@ Triage Jazzer.js crashes with casr-libfuzzer (Jazzer.js installation [guide](htt
Triage luzer crashes with casr-libfuzzer:

$ unzip casr/tests/casr_tests/lua/xml2lua.zip && cd xml2lua && luarocks --local build && cd .. && rm -rf xml2lua
$ git clone https://github.com/ligurio/luzer.git && cd luzer && luarocks --local build && cd .. && rm -rf luzer
$ eval $(luarocks path)
$ git clone https://github.com/azanegin/luzer.git && \
cd luzer && git checkout 77642ba37430eded66d171a68d7e9c3f6347d625 && luarocks --local build && cd .. && rm -rf luzer
$ mkdir -p casr/tests/tmp_tests_casr/casr_libfuzzer_luzer_out
$ casr-libfuzzer -i casr/tests/casr_tests/casrep/luzer_crashes_xml2lua -o casr/tests/tmp_tests_casr/casr_libfuzzer_luzer_out -- casr/tests/casr_tests/lua/stdin_parse_xml.lua

Triage LibAFL crashes with casr-libfuzzer:
Expand Down
2 changes: 1 addition & 1 deletion casr/src/triage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ impl<'a> CrashInfo {
} else {
args.push(format!("{}.casrep", report_path.display()));
}
if self.at_index.is_none() {
if self.at_index.is_none() || self.at_index == Some(0) {
args.push("--stdin".to_string());
args.push(self.path.to_str().unwrap().to_string());
}
Expand Down
120 changes: 120 additions & 0 deletions casr/tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5019,6 +5019,126 @@ fn test_casr_lua() {
}
}

#[test]
#[cfg(target_arch = "x86_64")]
fn test_casr_libfuzzer_luzer() {
use std::collections::HashMap;

let paths = [
abs_path("tests/casr_tests/casrep/luzer_crashes_xml2lua"),
abs_path("tests/tmp_tests_casr/test_casr_libfuzzer_luzer/casr_libfuzzer_luzer_out"),
abs_path("tests/tmp_tests_casr/test_casr_libfuzzer_luzer/stdin_parse_xml.lua"),
abs_path("tests/tmp_tests_casr/test_casr_libfuzzer_luzer/xml2lua"),
];

let _ = fs::remove_dir_all(&paths[1]);
let _ = fs::remove_file(&paths[2]);
let _ = fs::remove_dir_all(&paths[3]);
let _ = fs::create_dir_all(abs_path("tests/tmp_tests_casr/test_casr_libfuzzer_luzer"));

fs::copy(
abs_path("tests/casr_tests/lua/stdin_parse_xml.lua"),
&paths[2],
)
.unwrap();

Command::new("unzip")
.arg(abs_path("tests/casr_tests/lua/xml2lua.zip"))
.current_dir(abs_path("tests/tmp_tests_casr/test_casr_libfuzzer_luzer"))
.stdout(Stdio::null())
.status()
.expect("failed to unzip xml2lua.zip");

let Ok(luarocks_path) = which::which("luarocks") else {
panic!("No luarocks is found.");
};

let luarocks = Command::new(&luarocks_path)
.current_dir(&paths[3])
.args(["--local", "build"])
.output()
.expect("failed to run luarocks build");
assert!(
luarocks.status.success(),
"Stdout: {}.\n Stderr: {}",
String::from_utf8_lossy(&luarocks.stdout),
String::from_utf8_lossy(&luarocks.stderr)
);

let bins = Path::new(EXE_CASR_LIBFUZZER).parent().unwrap();
let mut cmd = Command::new(EXE_CASR_LIBFUZZER);
cmd.args(["-i", &paths[0], "-o", &paths[1], "--", &paths[2]])
.env(
"PATH",
format!("{}:{}", bins.display(), std::env::var("PATH").unwrap()),
);
let output = cmd.output().expect("failed to start casr-libfuzzer");

assert!(
output.status.success(),
"Stdout {}.\n Stderr: {}",
String::from_utf8_lossy(&output.stdout),
String::from_utf8_lossy(&output.stderr)
);
let err = String::from_utf8_lossy(&output.stderr);
println!("{}", err);

assert!(!err.is_empty());

assert!(err.contains("NOT_EXPLOITABLE"));
assert!(err.contains("attempt to perform arithmetic"));
assert!(err.contains("attempt to index"));
assert!(err.contains("bad argument #1 to 'insert'"));
assert!(err.contains("XmlParser.lua"));
assert!(err.contains("tree.lua"));

let re = Regex::new(r"Number of reports after deduplication: (?P<unique>\d+)").unwrap();
let unique_cnt = re
.captures(&err)
.unwrap()
.name("unique")
.map(|x| x.as_str())
.unwrap()
.parse::<u32>()
.unwrap();

assert_eq!(unique_cnt, 3, "Invalid number of deduplicated reports");

let re = Regex::new(r"Number of clusters: (?P<clusters>\d+)").unwrap();
let clusters_cnt = re
.captures(&err)
.unwrap()
.name("clusters")
.map(|x| x.as_str())
.unwrap()
.parse::<u32>()
.unwrap();

assert_eq!(clusters_cnt, 3, "Invalid number of clusters");

let mut storage: HashMap<String, u32> = HashMap::new();
for entry in fs::read_dir(&paths[1]).unwrap() {
let e = entry.unwrap().path();
let fname = e.file_name().unwrap().to_str().unwrap();
if fname.starts_with("cl") && e.is_dir() {
for file in fs::read_dir(e).unwrap() {
let mut e = file.unwrap().path();
if e.is_file() && e.extension().is_some() && e.extension().unwrap() == "casrep" {
e = e.with_extension("");
}
let fname = e.file_name().unwrap().to_str().unwrap();
if let Some(v) = storage.get_mut(fname) {
*v += 1;
} else {
storage.insert(fname.to_string(), 1);
}
}
}
}

assert!(storage.values().all(|x| *x > 1));
}

#[test]
#[cfg(target_arch = "x86_64")]
fn test_casr_js() {
Expand Down
5 changes: 3 additions & 2 deletions docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -707,8 +707,9 @@ Jazzer.js example (Jazzer.js installation [guide](https://github.com/CodeIntelli
Luzer example:

$ unzip casr/tests/casr_tests/lua/xml2lua.zip && cd xml2lua && luarocks --local build && cd .. && rm -rf xml2lua
$ git clone https://github.com/ligurio/luzer.git && cd luzer && luarocks --local build && cd .. && rm -rf luzer
$ eval $(luarocks path)
$ git clone https://github.com/azanegin/luzer.git && \
cd luzer && git checkout 77642ba37430eded66d171a68d7e9c3f6347d625 && luarocks --local build && cd .. && rm -rf luzer
$ mkdir -p casr/tests/tmp_tests_casr/casr_libfuzzer_luzer_out
$ casr-libfuzzer -i casr/tests/casr_tests/casrep/luzer_crashes_xml2lua -o casr/tests/tmp_tests_casr/casr_libfuzzer_luzer_out -- casr/tests/casr_tests/lua/stdin_parse_xml.lua

LibAFL example:
Expand Down
Loading