Fix unpack double free#4045
Conversation
|
This should be ready for review. PTAL! |
|
This looks good to me. @carlosmn - are there any subtleties in fixing thin packs? |
|
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. |
|
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 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 :( |
|
Is this a security hole? |
|
@DemiMarie yes, if you feed untrusted/arbitrary packfile data into the @carlosmn sorry for the delay (almost a year!?). i think we can get away without doing significant refactoring by either:
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. |
|
@carlosmn all right, found a much more elegant solution! PTAAL. |
|
Sorry for the delay - this looks good to me. 😁 |
|
Would you mind squashing this? I'll |
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.
f7fc939 to
c3514b0
Compare
|
I do not mind! Squashed and rebased. |
|
Thanks! 👍 ✨ |
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.