Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

fix: prevent index out of range on long frag tables #30

Conversation

willmurphyscode
Copy link
Contributor

@willmurphyscode willmurphyscode commented Nov 26, 2024

Hi! Thanks for a pure-Go implementation of SquashFS reading. I think I found a bug. This PR is a proposed fix I'm curious whether you'd be interested in it. It's a bit of a large diff for such a fix, but I really wanted to get the edge cases of block boundaries, last blocks with an incomplete set of records, etc, under unit test, and this seemed like the best approach to me. If you'd like me to take a different approach, let me know.

For context, I'm a maintainer on Syft (an open source SBOM tool) that depends on a fork of this library (we can't depend on this library directly because of how LZO is licensed). This was reported to Syft on anchore/syft#3390. I'm trying to contribute the fix as far upstream as I can.

Previously, reading fragment 512 would panic with index out of range. Fix that panic by introducing an abstraction over reading blocks of items, caching the intermediate result, and returning an item at a particular index. The primary goal of this abstraction is to make edge cases like requesting items on page boundaries easy to unit test for.

Additionally, fix unit tests by making t.Fatal calls protected by nil checks on the error values.

Questions

  1. Do you agree this is the right approach? If so, would you like me to change the other places in low/reader.go that read a table incrementally to use this approach?
  2. I've done some manual testing in addition to the new unit tests. Are there any specific tests you'd like me to run?
  3. I was a bit surprised to see some unguarded t.Fatal calls in some tests. Is that getting you something I'm not realizing? It seems incorrect to me.

Previously, reading fragment 512 would panic with index out of range.
Fix that panic by introducing an abstraction over reading blocks of
items, caching the intermediate result, and returning an item at a
particular index. The primary goal of this abstraction is to make edge
cases like requesting items on page boundaries easy to unit test for.

Additionally, fix unit tests by making t.Fatal calls protected by
nil checks on the error values.
@CalebQ42
Copy link
Owner

This is a VERY heavy handed fix that gives zero regard for performance. This bug can be literally fixed in one code line change (3 if you include the same bug in Id and inodeRef) and that's it. I see no actual benefit to abstracting this; it's not bad code, but it is a bad fix for this bug.

My tests are pretty bad, lol. They aren't really tests and were mostly made to easily run the library to see what things are breaking. The reason a lot of test end with t.Fatal instead of checking the error is simply that if you don't Fatal an error, I've had issues with calls to fmt.Println or t.Log not printing out. I'm not against having proper tests, but to do so I'd also need to setup some proper testing archives, which I've just never got around to doing.

@CalebQ42 CalebQ42 closed this Nov 26, 2024
CalebQ42 added a commit that referenced this pull request Nov 26, 2024
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants