-
Notifications
You must be signed in to change notification settings - Fork 117
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
squashfs: fix directory listings #195
Conversation
Note that the test introduced here won't pass until #193 is merged. Maybe I should have put both commits in the same PR. |
Don't worry about it. We can merge them in order, and when that one is in, rebase this. |
Note that I'm working on a larger patch to fix up the reading of files out of squashfs which is quite broken in places. Its looking a lot better but it isn't there quite yet! |
Do you need to rebase this on #193 now that it is merged in? |
Thank you, I am looking forward to it. Also to how the tests change and see what they missed (or just weren't implemented 😆 ) |
I've rebased this and I've also fixed the test I broke!
I think the tests are very well implemented :-) I've been working on more end-to-end tests so unpacking actual archives created by mksquashfs and there are a lot of corner cases! I'm hoping to get this all passing shortly but if I get stuck I may push it anyway so you can see the progress and maybe give hints! |
I am confused. Don't we need to parse the header? You are saying it is possible to have an empty directory without any header at all (even though the spec says otherwise). Then ho would we know if the directory is valid? |
I think that the lines of code I deleted 57-60 are effectively repeated at 63-66 when go-diskfs/filesystem/squashfs/directory.go Lines 56 to 66 in e5b4940
If you look in the
I don't know for sure whether that fix is correct, there could be a problem somewhere else, but that is what I came up with to fix the error. The spec I've been looking at says
Which I took to mean that the directory shouldn't be empty, but looking at it at face value it says if a header exists then it must have at least one entry. Where the case under discussion here is if the header does not exist. A check for "A header must have at least one entry" would look something like this I think diff --git a/filesystem/squashfs/directory.go b/filesystem/squashfs/directory.go
index b559af5..1e8628f 100644
--- a/filesystem/squashfs/directory.go
+++ b/filesystem/squashfs/directory.go
@@ -60,6 +60,9 @@ func parseDirectory(b []byte) (*directory, error) {
if err != nil {
return nil, fmt.Errorf("could not parse directory header: %v", err)
}
+ if directoryHeader.count == 0 {
+ return nil, fmt.Errorf("corrupted directory, must have at least one entry")
+ }
if directoryHeader.count > maxDirEntries {
return nil, fmt.Errorf("corrupted directory, had %d entries instead of max %d", directoryHeader.count, maxDirEntries)
} However that is almost pointless since go-diskfs/filesystem/squashfs/directory.go Line 147 in e5b4940
I think the directoryHeader being missing is the only way to encode an empty directory otherwise (which squashfs clearly can as the |
Rereading the code, I see that makes sense. Our only code after the (deleted) check is looping through the dir entries, So, yeah, I think you are right. Let's say, "this is the fault of unclear spec writers, we did our best, and now @ncw fixed it for us." 😄 Is this ready to go in? |
This fixes directory listings sometimes giving the error: could not parse directory header: header was 3 bytes, less than minimum 12 This was caused by a check for "at least one directory header" failing on empty directories. On careful examination of the spec, it says that if a directory header is present it must have at least one directory entry, but it is silent on whether a directory header has to exist or not. A non-existent header seems like the only way to sensibly implement empty directories. This adds a check to implement the "at least one directory entry per directory header" check and modifies the bounds check to catch a header with no entries. This also introduces a test checking that we can recurse the test squashfs file correctly - this fails without this patch.
:-)
I've updated the patch to add the extra check in and add a test for that check. While doing that I noticed that the for loop range needed fixing too! I updated the commit message with a summary of what we learnt above (I hadn't thought it through properly until writing the above so I thought it deserved to go in the commit message! It is ready to go now if you are happy :-) |
Looks great. Thanks! |
This fixes directory listings sometimes giving the error
This appears to be because empty directories can indeed have no
entries despite what the spec says.
This introduces a test checking that we can recurse the test squashfs
file correctly - this fails without this patch.