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

[libcasr] cargo-fuzz support #132

Merged
merged 7 commits into from
Sep 16, 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
17 changes: 17 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,23 @@ jobs:
cargo install cargo-fuzz
cargo test --release --verbose

ubuntu-fuzz:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- name: Fuzzing
run: |
curl https://sh.rustup.rs -o rustup.sh && chmod +x rustup.sh && \
./rustup.sh -y && rm rustup.sh
rustup install nightly
export PATH=/root/.cargo/bin:$PATH
cargo install cargo-fuzz
cd libcasr/fuzz
mkdir corpus
cargo +nightly fuzz run parse_stacktrace corpus init_corpus -- -max_total_time=600

ubuntu-aarch64:

runs-on: ubuntu-latest
Expand Down
2 changes: 1 addition & 1 deletion libcasr/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ repository = "https://github.com/ispras/casr.git"
documentation = "https://docs.rs/libcasr"
edition = "2021"
license = "Apache-2.0"
exclude = ["/tests"]
SweetVishnya marked this conversation as resolved.
Show resolved Hide resolved
exclude = ["/fuzz"]

[dependencies]
regex = "1"
Expand Down
4 changes: 4 additions & 0 deletions libcasr/fuzz/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
target
corpus
artifacts
coverage
28 changes: 28 additions & 0 deletions libcasr/fuzz/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
[package]
name = "libcasr-fuzz"
version = "0.1.0"
authors = ["Andrey Fedotov [email protected]"]
publish = false
edition = "2021"

[package.metadata]
cargo-fuzz = true

[dependencies]
libfuzzer-sys = "0.4"

[dependencies.libcasr]
path = ".."

# Prevent this from interfering with workspaces
[workspace]
members = ["."]

[profile.release]
debug = 1

[[bin]]
name = "parse_stacktrace"
path = "fuzz_targets/parse_stacktrace.rs"
test = false
doc = false
73 changes: 73 additions & 0 deletions libcasr/fuzz/fuzz_targets/parse_stacktrace.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#![no_main]

use libfuzzer_sys::fuzz_target;

use libcasr::{
asan::AsanStacktrace,
constants::{
STACK_FRAME_FILEPATH_IGNORE_REGEXES_CPP, STACK_FRAME_FILEPATH_IGNORE_REGEXES_GO,
STACK_FRAME_FILEPATH_IGNORE_REGEXES_JAVA, STACK_FRAME_FILEPATH_IGNORE_REGEXES_PYTHON,
STACK_FRAME_FILEPATH_IGNORE_REGEXES_RUST, STACK_FRAME_FUNCTION_IGNORE_REGEXES_CPP,
STACK_FRAME_FUNCTION_IGNORE_REGEXES_GO, STACK_FRAME_FUNCTION_IGNORE_REGEXES_JAVA,
STACK_FRAME_FUNCTION_IGNORE_REGEXES_PYTHON, STACK_FRAME_FUNCTION_IGNORE_REGEXES_RUST,
},
gdb::GdbStacktrace,
go::GoStacktrace,
init_ignored_frames,
java::JavaStacktrace,
python::PythonStacktrace,
stacktrace::{
CrashLineExt, ParseStacktrace, STACK_FRAME_FILEPATH_IGNORE_REGEXES,
STACK_FRAME_FUNCTION_IGNORE_REGEXES,
},
};

fuzz_target!(|data: &[u8]| {
SweetVishnya marked this conversation as resolved.
Show resolved Hide resolved
if data.len() < 2 {
return;
}
let s = String::from_utf8_lossy(&data[1..]);
init_ignored_frames!("cpp", "rust", "python", "go", "java");
match data[0] % 5 {
anfedotoff marked this conversation as resolved.
Show resolved Hide resolved
0 => {
// Asan
SweetVishnya marked this conversation as resolved.
Show resolved Hide resolved
if let Ok(raw) = AsanStacktrace::extract_stacktrace(&s) {
if let Ok(st) = AsanStacktrace::parse_stacktrace(&raw) {
let _ = st.crash_line();
}
}
anfedotoff marked this conversation as resolved.
Show resolved Hide resolved
}
1 => {
// Go
if let Ok(raw) = GoStacktrace::extract_stacktrace(&s) {
if let Ok(st) = GoStacktrace::parse_stacktrace(&raw) {
let _ = st.crash_line();
}
}
}
2 => {
// Python
if let Ok(raw) = PythonStacktrace::extract_stacktrace(&s) {
if let Ok(st) = PythonStacktrace::parse_stacktrace(&raw) {
let _ = st.crash_line();
}
}
}
3 => {
// Java
if let Ok(raw) = JavaStacktrace::extract_stacktrace(&s) {
if let Ok(st) = JavaStacktrace::parse_stacktrace(&raw) {
let _ = st.crash_line();
}
}
}
_ => {
// Gdb
if let Ok(raw) = GdbStacktrace::extract_stacktrace(&s) {
if let Ok(st) = GdbStacktrace::parse_stacktrace(&raw) {
let _ = st.crash_line();
}
}
}
}
});
Binary file added libcasr/fuzz/init_corpus/asan
Binary file not shown.
9 changes: 9 additions & 0 deletions libcasr/fuzz/init_corpus/gdb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
 #0 0x00000000005e3099 in xlnt::detail::compound_document::read_directory (this=0x7fffffffcee0) at /xlnt/source/detail/cryptography/compound_document.cpp:975
#1 0x00000000005e2956 in xlnt::detail::compound_document::compound_document (this=0x7fffffffcee0, in=...) at /xlnt/source/detail/cryptography/compound_document.cpp:517
#2 0x000000000048a45c in (anonymous namespace)::decrypt_xlsx (bytes=std::vector of length 18655, capacity 32768 = {...}, password=u\"VelvetSweatshop\") at /xlnt/source/detail/cryptography/xlsx_crypto_consumer.cpp:320
#3 0x000000000048a2d9 in xlnt::detail::decrypt_xlsx (data=std::vector of length 18655, capacity 32768 = {...}, password=) at /xlnt/source/detail/cryptography/xlsx_crypto_consumer.cpp:339
#4 0x000000000048a7f6 in xlnt::detail::xlsx_consumer::read (this=0x7fffffffd8f0, source=..., password=) at /xlnt/source/detail/cryptography/xlsx_crypto_consumer.cpp:345
#5 0x000000000040ddd6 in xlnt::workbook::load (this=0x7fffffffdbc8, stream=...) at /xlnt/source/workbook/workbook.cpp:901
#6 0x00000000004142af in xlnt::workbook::load (this=0x7fffffffdbc8, data=std::vector of length 18655, capacity 18655 = {...}) at /xlnt/source/workbook/workbook.cpp:919
#7 0x00000000004073bd in LLVMFuzzerTestOneInput (data=<optimized out>, data@entry=0x6ec0a0 \"\\320\\317\\021\\340\\241\\261\", <incomplete sequence \\341>, size=<optimized out>, size@entry=18655) at /home/avgor46/test_threads_casr/xlnt/load_sydr.cc:13
#8 0x00000000004074cb in main (argc=<optimized out>, argv=<optimized out>) at /home/avgor46/test_threads_casr/xlnt/load_sydr.cc:39
103 changes: 103 additions & 0 deletions libcasr/fuzz/init_corpus/go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
runtime stack:
runtime.throw({0x565860?, 0x400000?})
runtime/panic.go:1047 +0x5f fp=0x7fffffffdb40 sp=0x7fffffffdb10 pc=0x49745f
runtime.sysMapOS(0xc000400000, 0x1b82b8000000?)
runtime/mem_linux.go:187 +0x11b fp=0x7fffffffdb88 sp=0x7fffffffdb40 pc=0x47a93b
runtime.sysMap(0xff9e40?, 0x7ffff7a1b000?, 0x48dc00?)
runtime/mem.go:142 +0x35 fp=0x7fffffffdbb8 sp=0x7fffffffdb88 pc=0x47a315
runtime.(*mheap).grow(0xff9e40, 0xdc15be77?)
runtime/mheap.go:1459 +0x23d fp=0x7fffffffdc28 sp=0x7fffffffdbb8 pc=0x48acbd
runtime.(*mheap).allocSpan(0xff9e40, 0xdc15be77, 0x0, 0x1)
runtime/mheap.go:1191 +0x1be fp=0x7fffffffdcc0 sp=0x7fffffffdc28 pc=0x48a3fe
runtime.(*mheap).alloc.func1()
runtime/mheap.go:910 +0x65 fp=0x7fffffffdd08 sp=0x7fffffffdcc0 pc=0x489e85
runtime.systemstack()
runtime/asm_amd64.s:492 +0x46 fp=0x7fffffffdd10 sp=0x7fffffffdd08 pc=0x4c0ae6

goroutine 17 [running, locked to thread]:
runtime.systemstack_switch()
runtime/asm_amd64.s:459 fp=0xc00005ca98 sp=0xc00005ca90 pc=0x4c0a80
runtime.(*mheap).alloc(0x4c7485?, 0x641d60?, 0x0?)
runtime/mheap.go:904 +0x65 fp=0xc00005cae0 sp=0xc00005ca98 pc=0x489dc5
runtime.(*mcache).allocLarge(0x5bfa08?, 0x1b82b7cec246, 0x1)
runtime/mcache.go:233 +0x85 fp=0xc00005cb30 sp=0xc00005cae0 pc=0x4792a5
runtime.mallocgc(0x1b82b7cec246, 0x5a54e0, 0x1)
runtime/malloc.go:1029 +0x57e fp=0xc00005cba8 sp=0xc00005cb30 pc=0x470ebe
runtime.makeslice(0xc00010c1b0?, 0xc00001c0a0?, 0x8?)
runtime/slice.go:103 +0x52 fp=0xc00005cbd0 sp=0xc00005cba8 pc=0x4ac4d2
golang.org/x/image/webp.readAlpha({0x5bfa68, 0xc0000140b0}, 0x1c0a0?, 0xc0?, 0x1?)
/image/webp/decode.go:157 +0x409 fp=0xc00005cc68 sp=0xc00005cbd0 pc=0x521509
golang.org/x/image/webp.decode({0x5bf9e8?, 0xc00010c1b0?}, 0x0)
/image/webp/decode.go:68 +0x64a fp=0xc00005cd80 sp=0xc00005cc68 pc=0x52070a
golang.org/x/image/webp.Decode({0x5bf9e8?, 0xc00010c1b0?})
/image/webp/decode.go:255 +0x45 fp=0xc00005cda8 sp=0xc00005cd80 pc=0x521ca5
golang.org/x/image.FuzzWebp({0x102a550, 0xc7, 0xc7})
/image/fuzz.go:22 +0x1d8 fp=0xc00005cdd0 sp=0xc00005cda8 pc=0x553098
main.LLVMFuzzerTestOneInput(0x0?, 0xc000006601?)
golang.org/x/image/go.fuzz.main/main.go:35 +0x47 fp=0xc00005ce10 sp=0xc00005cdd0 pc=0x5531c7
_cgoexp_b3dc3ff32902_LLVMFuzzerTestOneInput(0x7fffffffdd80)
_cgo_gotypes.go:58 +0x28 fp=0xc00005ce30 sp=0xc00005ce10 pc=0x5532a8
runtime.cgocallbackg1(0x553280, 0xc00005cfe0?, 0x0)
runtime/cgocall.go:316 +0x2c2 fp=0xc00005cf00 sp=0xc00005ce30 pc=0x468942
runtime.cgocallbackg(0x0?, 0x0?, 0x0?)
runtime/cgocall.go:235 +0x109 fp=0xc00005cf90 sp=0xc00005cf00 pc=0x4685c9
runtime.cgocallbackg(0x553280, 0x7fffffffdd80, 0x0)
<autogenerated>:1 +0x31 fp=0xc00005cfb8 sp=0xc00005cf90 pc=0x4c5011
runtime.cgocallback(0x0, 0x0, 0x0)
runtime/asm_amd64.s:994 +0xb3 fp=0xc00005cfe0 sp=0xc00005cfb8 pc=0x4c2ad3
runtime.goexit()
runtime/asm_amd64.s:1594 +0x1 fp=0xc00005cfe8 sp=0xc00005cfe0 pc=0x4c2d21

goroutine 2 [force gc (idle)]:
runtime.gopark(0x0?, 0x0?, 0x0?, 0x0?, 0x0?)
runtime/proc.go:363 +0xd6 fp=0xc00004afb0 sp=0xc00004af90 pc=0x49a076
runtime.goparkunlock(...)
runtime/proc.go:369
runtime.forcegchelper()
runtime/proc.go:302 +0xad fp=0xc00004afe0 sp=0xc00004afb0 pc=0x499f0d
runtime.goexit()
runtime/asm_amd64.s:1594 +0x1 fp=0xc00004afe8 sp=0xc00004afe0 pc=0x4c2d21
created by runtime.init.6
runtime/proc.go:290 +0x25

goroutine 3 [GC sweep wait]:
runtime.gopark(0x0?, 0x0?, 0x0?, 0x0?, 0x0?)
runtime/proc.go:363 +0xd6 fp=0xc00004b790 sp=0xc00004b770 pc=0x49a076
runtime.goparkunlock(...)
runtime/proc.go:369
runtime.bgsweep(0x0?)
runtime/mgcsweep.go:278 +0x8e fp=0xc00004b7c8 sp=0xc00004b790 pc=0x486e2e
runtime.gcenable.func1()
runtime/mgc.go:178 +0x26 fp=0xc00004b7e0 sp=0xc00004b7c8 pc=0x47bcc6
runtime.goexit()
runtime/asm_amd64.s:1594 +0x1 fp=0xc00004b7e8 sp=0xc00004b7e0 pc=0x4c2d21
created by runtime.gcenable
runtime/mgc.go:178 +0x6b

goroutine 4 [GC scavenge wait]:
runtime.gopark(0xc000074000?, 0x587370?, 0x1?, 0x0?, 0x0?)
runtime/proc.go:363 +0xd6 fp=0xc00004bf70 sp=0xc00004bf50 pc=0x49a076
runtime.goparkunlock(...)
runtime/proc.go:369
runtime.(*scavengerState).park(0xfe1700)
runtime/mgcscavenge.go:389 +0x53 fp=0xc00004bfa0 sp=0xc00004bf70 pc=0x484ed3
runtime.bgscavenge(0x0?)
runtime/mgcscavenge.go:617 +0x45 fp=0xc00004bfc8 sp=0xc00004bfa0 pc=0x4854a5
runtime.gcenable.func2()
runtime/mgc.go:179 +0x26 fp=0xc00004bfe0 sp=0xc00004bfc8 pc=0x47bc66
runtime.goexit()
runtime/asm_amd64.s:1594 +0x1 fp=0xc00004bfe8 sp=0xc00004bfe0 pc=0x4c2d21
created by runtime.gcenable
runtime/mgc.go:179 +0xaa

goroutine 5 [finalizer wait]:
runtime.gopark(0xfe1b00?, 0xc000007860?, 0x0?, 0x0?, 0xc00004a770?)
runtime/proc.go:363 +0xd6 fp=0xc00004a628 sp=0xc00004a608 pc=0x49a076
runtime.goparkunlock(...)
runtime/proc.go:369
runtime.runfinq()
runtime/mfinal.go:180 +0x10f fp=0xc00004a7e0 sp=0xc00004a628 pc=0x47adcf
runtime.goexit()
runtime/asm_amd64.s:1594 +0x1 fp=0xc00004a7e8 sp=0xc00004a7e0 pc=0x4c2d21
created by runtime.createfing
runtime/mfinal.go:157 +0x45
9 changes: 9 additions & 0 deletions libcasr/fuzz/init_corpus/java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
== Java Exception: java.lang.IndexOutOfBoundsException: start 328, end 292, length 441
at java.base/java.lang.AbstractStringBuilder.checkRange(AbstractStringBuilder.java:1802)
at java.base/java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:680)
at java.base/java.lang.StringBuilder.append(StringBuilder.java:218)
at com.google.json.JsonSanitizer.elide(JsonSanitizer.java:717)
at com.google.json.JsonSanitizer.normalizeNumber(JsonSanitizer.java:864)
at com.google.json.JsonSanitizer.sanitize(JsonSanitizer.java:440)
at com.google.json.JsonSanitizer.sanitize(JsonSanitizer.java:122)
at DenylistFuzzer.fuzzerTestOneInput(DenylistFuzzer.java:27)
19 changes: 19 additions & 0 deletions libcasr/fuzz/init_corpus/python
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
Traceback (most recent call last):
File "../../yaml_fuzzer.py", line 40, in TestOneInput
for _ in iterator:
File "/home/hkctkuy/.local/lib/python3.8/site-packages/ruamel/yaml/main.py", line 461, in load_all
yield constructor.get_data()
File "/home/hkctkuy/.local/lib/python3.8/site-packages/ruamel/yaml/constructor.py", line 114, in get_data
return self.construct_document(self.composer.get_node())
File "/home/hkctkuy/.local/lib/python3.8/site-packages/ruamel/yaml/composer.py", line 66, in get_node
return self.compose_document()
File "/home/hkctkuy/.local/lib/python3.8/site-packages/ruamel/yaml/composer.py", line 99, in compose_document
node = self.compose_node(None, None)
File "/home/hkctkuy/.local/lib/python3.8/site-packages/ruamel/yaml/composer.py", line 139, in compose_node
node = self.compose_scalar_node(anchor)
File "/home/hkctkuy/.local/lib/python3.8/site-packages/ruamel/yaml/composer.py", line 152, in compose_scalar_node
tag = self.resolver.resolve(ScalarNode, event.value, event.implicit)
File "/home/hkctkuy/.local/lib/python3.8/site-packages/ruamel/yaml/resolver.py", line 367, in resolve
resolvers = self.versioned_resolver.get("", [])
File "/home/hkctkuy/.local/lib/python3.8/site-packages/ruamel/yaml/resolver.py", line 361, in versioned_resolver
return self._version_implicit_resolver[version]
Loading