Skip to content

Fix unpack double free#4045

Merged
ethomson merged 1 commit into
libgit2:masterfrom
lhchavez:fix-unpack-double-free
Dec 23, 2017
Merged

Fix unpack double free#4045
ethomson merged 1 commit into
libgit2:masterfrom
lhchavez:fix-unpack-double-free

Conversation

@lhchavez
Copy link
Copy Markdown
Contributor

If an element has been cached, but then the call to
packfile_unpack_compressed() fails, the very next thing that happens is
that its data is freed and then the element is not removed from the
cache, which frees the data again.

This change sets obj->data to NULL to avoid the double-free. It also
stops trying to resolve deltas after two continuous failed rounds of
resolution, and adds a test for this.

@lhchavez
Copy link
Copy Markdown
Contributor Author

lhchavez commented Jan 1, 2017

This should be ready for review. PTAL!

@ethomson
Copy link
Copy Markdown
Member

This looks good to me. @carlosmn - are there any subtleties in fixing thin packs?

@carlosmn
Copy link
Copy Markdown
Member

There often are subtleties. I'd like us to do the same kind of check that git does in this case in order to detect when no progress can be made. I'd have to get back to the details, but I'm not sure that we can assert we're stuck just because a single round did no yield any progress.

@lhchavez
Copy link
Copy Markdown
Contributor Author

lhchavez commented Jan 30, 2017

IIUC git does this by making sure each unresolved delta is fully resolved before resolving the next one. at its core, there's a check that verifies that progress was made in the last two rounds (similar in spirit to the stuck flag I'm proposing). It's probably doable to restructure libgit2's code to make it behave closer to that, but it might take a bit more work.

I did try to find a good scenario in which to test the double free() that didn't involve a malformed packfile to avoid having the fix depend on the stuck logic (otherwise the test never finishes), but I was unfortunately unable to find anything :(

@DemiMarie
Copy link
Copy Markdown

Is this a security hole?

@lhchavez
Copy link
Copy Markdown
Contributor Author

lhchavez commented Dec 5, 2017

@DemiMarie yes, if you feed untrusted/arbitrary packfile data into the git_indexer_append function.

@carlosmn sorry for the delay (almost a year!?). i think we can get away without doing significant refactoring by either:

  • checking that the inserted object will effectively resolve the delta, or
  • by tagging each delta as having been resolved, and only process each delta once in fix_thin_pack, which avoids having a coarse two-try attempt.

i already have the latter coded with tests passing, but want to explore the former since it seems more robust and might catch more errors.

@lhchavez
Copy link
Copy Markdown
Contributor Author

lhchavez commented Dec 5, 2017

@carlosmn all right, found a much more elegant solution! PTAAL.

@lhchavez
Copy link
Copy Markdown
Contributor Author

@carlosmn @ethomson @pks-t gentle ping? This is the only thing missing before the OSS-Fuzz support can be committed.

@ethomson
Copy link
Copy Markdown
Member

Sorry for the delay - this looks good to me. 😁

@ethomson
Copy link
Copy Markdown
Member

Would you mind squashing this? I'll :shipit:

If an element has been cached, but then the call to
packfile_unpack_compressed() fails, the very next thing that happens is
that its data is freed and then the element is not removed from the
cache, which frees the data again.

This change sets obj->data to NULL to avoid the double-free. It also
stops trying to resolve deltas after two continuous failed rounds of
resolution, and adds a test for this.
@lhchavez lhchavez force-pushed the fix-unpack-double-free branch from f7fc939 to c3514b0 Compare December 23, 2017 14:59
@lhchavez
Copy link
Copy Markdown
Contributor Author

I do not mind! Squashed and rebased.

@ethomson
Copy link
Copy Markdown
Member

Thanks! 👍 ✨ :shipit:

@ethomson ethomson merged commit d734466 into libgit2:master Dec 23, 2017
@pks-t pks-t added the backport label Jan 11, 2018
@pks-t pks-t mentioned this pull request Jan 12, 2018
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.

5 participants