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

Fuzzing via honggfuzz #101

Merged
merged 17 commits into from
Nov 4, 2023
Merged

Fuzzing via honggfuzz #101

merged 17 commits into from
Nov 4, 2023

Conversation

Nereuxofficial
Copy link
Contributor

Originally i was not aware of the crate, so i wanted to implement JPEG-XL parsing in Rust myself, then i discovered this crate and decided to improve the existing crate(which seems very well designed).

I noticed that it did not have a fuzzing setup and decided to add one and fuzzed it while i was at it.

I discovered two crashes and added tests for them:

  1. Integer overflow in a multiplication in compute_default_width
  2. Very large memory allocation(probably related to Req: set max memory for decoding #54 )
    Additionally i did not find a security policy inplace so i will just report it via this PR.

I would love to fix the first one, but would like to coordinate as this would probably make compute_default_width return a result.

I found out later there is another PR adding Fuzzing support, however development seems to have stalled. However i plan on implementing more fuzzing coverage and a corpus, as seen in that PR and would also be fine with further improving that one, if AFL seems like the better solution. (See #31 )

@Nereuxofficial
Copy link
Contributor Author

Upon further fuzzing to have higher coverage(now 28% compared to 12% previously) i found another issue. The PR will be updated shortly with a test for it.

There is an out of bounds index access in dequant.rs here.

Copy link
Owner

@tirr-c tirr-c left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for contributing! Having a fuzzer would be nice.

Regarding compute_default_width: the computed width should be within u32 range, as height <= (1 << 30) (from 1 + u(30), meaning that it reads 30 bits and adds 1) and the aspect ratio is at most 2. Casting height to u64 will do the thing. Maybe add an assertion to height?

crates/jxl-oxide/fuzz/Cargo.toml Outdated Show resolved Hide resolved
crates/jxl-oxide/fuzz/fuzz_targets/decode.rs Outdated Show resolved Hide resolved
<0x00007ffff7caccd0> [func:UNKNOWN file: line:0 module:/usr/lib/libc.so.6]
<0x00007ffff7cacd8a> [func:UNKNOWN file: line:0 module:/usr/lib/libc.so.6]
<0x0000555555567b95> [func:UNKNOWN file: line:0 module:/home/benedikt/RustroverProjects/jxl-oxide/crates/jxl-oxide/fuzz/hfuzz_target/x86_64-unknown-linux-gnu/release/fuzz_decode]
=====================================================================
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this shouldn't be included. Maybe ignore hfuzz_workspace if we can specify custom corpus directory?

Copy link
Contributor Author

@Nereuxofficial Nereuxofficial Nov 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes that is possible. The report will be ignored, however the other files with the admittedly random seeming names have to be included unless the crash files are moved by the developer.(Maybe there is also a way to specify the crash file directory?)

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can use the crash report and input files to create an issue (which can be automated by some scheduled fuzzer run) or write tests. The workspace directory can be .gitignore-ed if we do this; I don't see any reason to leave and commit the directory as is.

crates/jxl-oxide/fuzz/Cargo.toml Outdated Show resolved Hide resolved
Copy link
Owner

@tirr-c tirr-c left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might want to move test_findings.rs to the parent directory; only files directly put inside tests directory will run as tests. See the section about integration tests in the Rust Book for details.

@Nereuxofficial
Copy link
Contributor Author

Nereuxofficial commented Nov 4, 2023

I moved the tests to the integration tests, made a macro for testing them, removed the duplicates from the findings and added a Readme to the fuzz dir to guide new developers.

One thing that is still bothering me is that the fuzz_decode function is now duplicate, since it is needed in the tests of another crate and i do not want to change the public interface of jxl-oxide. Any idea how to elegantly solve this?

Additionally i could make a github workflow to fuzz the crate with a configurable timeout, which reports new findings via an issue but i would make a new PR for that, since the changes are fairly independent.

I'm now looking into the corpus

@tirr-c
Copy link
Owner

tirr-c commented Nov 4, 2023

Uh, another Cargo.lock should not happen... Does cargo hfuzz create Cargo.lock inside the fuzzer directory?

Copy link
Owner

@tirr-c tirr-c left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing that is still bothering me is that the fuzz_decode function is now duplicate, since it is needed in the tests of another crate and i do not want to change the public interface of jxl-oxide. Any idea how to elegantly solve this?

I feel like some duplicate code is okay, as sometimes the fuzzer and actual test harness do slightly different things.

crates/jxl-oxide/tests/test_fuzz_findings.rs Outdated Show resolved Hide resolved
@Nereuxofficial
Copy link
Contributor Author

Nereuxofficial commented Nov 4, 2023

Uh, another Cargo.lock should not happen... Does cargo hfuzz create Cargo.lock inside the fuzzer directory?

No, it was from the previous directory and i thought it should be committed. But when deleting it and recompiling it now, it is not created

Copy link
Owner

@tirr-c tirr-c left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work! Some nitpicks:

crates/jxl-oxide/tests/test_fuzz_findings.rs Outdated Show resolved Hide resolved
crates/jxl-oxide-fuzz/.gitignore Outdated Show resolved Hide resolved
crates/jxl-oxide-fuzz/Cargo.toml Outdated Show resolved Hide resolved
Nereuxofficial and others added 3 commits November 4, 2023 12:30
Co-authored-by: Wonwoo Choi <chwo9843@gmail.com>
Co-authored-by: Wonwoo Choi <chwo9843@gmail.com>
Copy link
Owner

@tirr-c tirr-c left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now we have some remaining work (which can be done in separate PRs):

  • Fix crashes. Some crashes are from allocation errors, but there's some chance those errors are from previous integer overflow. Needs investigating.
  • Run fuzzer in GitHub Actions workflows.
  • Prepare corpus directory for the fuzzer.

Again, thanks for contributing! I'm going to merge this. Feel free to open another PR for additional work.

@tirr-c tirr-c merged commit 696b878 into tirr-c:main Nov 4, 2023
@tirr-c tirr-c mentioned this pull request Nov 4, 2023
@Nereuxofficial
Copy link
Contributor Author

Now we have some remaining work (which can be done in separate PRs):

  • Fix crashes. Some crashes are from allocation errors, but there's some chance those errors are from previous integer overflow. Needs investigating.
  • Run fuzzer in GitHub Actions workflows.
  • Prepare corpus directory for the fuzzer.

Again, thanks for contributing! I'm going to merge this. Feel free to open another PR for additional work.

Sounds good! Thanks for helping me!

@Nereuxofficial Nereuxofficial deleted the fuzzing branch November 4, 2023 12:15
-0.01716200, -0.03452303, -0.04022174, -0.02921014, -0.00624645,
0.14111091, 0.28896755, 0.00278718, -0.01610267, 0.56661550,
0.03777607, -0.01986694, -0.03144731, -0.01185068, -0.00213539,
-0.01716200,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tirr-c, Shall we use rustfmt for the new code?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh i did not want to format that file. That blew up the lines. Gonna turn autoformatting off in my IDE

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@EugeneVert I'd like to do that, yes. Rustfmt properly handles let-else syntax now, so I guess it's time to do formatting!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants