git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH 1/3] prune-packed: fix a possible buffer overflow

From
Jeff King <peff@peff.net>
Date
Dec 20, 2013, 09:30 UTC
Message-ID
<20131220093048.GB9637@sigill.intra.peff.net>
In-Reply-To
<52B31FF3.1060102@alum.mit.edu>
On Thu, Dec 19, 2013 at 05:33:55PM +0100, Michael Haggerty wrote:
Show 12 quoted lines
> > But we don't loop on ENOENT. So if the rmdir happens in the middle,
> > after the mkdir but before we call open again, we'd fail, because we
> > don't treat ENOENT specially in the second call to open. That is
> > unlikely to happen, though, as prune would not be removing a directory
> > it did not just enter and clean up an object from (in which case we
> > would not have gotten the first ENOENT in the creator). [...]
> 
> The way I read it, prune tries to delete the directory whether or not
> there were any files in it.  So the race could be triggered by a single
> writer that wants to write an object to a not-yet-existent shard
> directory and a single prune process that encounters the directory
> between when it is created and when the object file is added.

Yes, that's true. It does make the race slightly more difficult than a straight deletion because the prune has to catch it in the moment where it exists but does not yet have an object. But it's still possible.

> But that doesn't mean I disagree with your conclusion:
I think we're in violent agreement at this point. :)
Show 12 quoted lines
> Regarding references:
> 
> > On a similar note, I imagine that a simultaneous "branch foo/bar" and
> > "branch -d foo/baz" could race over the creation/deletion of
> > "refs/heads/foo", but I didn't look into it.
> 
> Deleting a loose reference doesn't cause the directory containing it to
> be deleted.  The directory is only deleted by pack-refs (and then only
> when a reference in the directory was just packed) or when there is an
> attempt to create a new reference that conflicts with the directory.  So
> the question is whether the creation of a loose ref file is robust
> against the disappearance of a directory that it just created.

Ah, right, I forgot we leave the directories sitting around after deletion. So we may run into a collision with another creator, but by definition we would have a D/F conflict with such a creator anyway, so we cannot both succeed.

But we can hit the problem with pack-refs, as you note:
Show 6 quoted lines
> And the answer is "no".  It looks like there are a bunch of places where
> similar races occur involving references.  And probably many others
> elsewhere in the code.  (Any caller of safe_create_leading_directories()
> is a candidate problem point, and in fact that function itself has an
> internal race.)  I've started fixing some of these but it might take a
> while.

Yeah, I think you'd have to teach safe_create_leading_directories to atomically try-to-create-and-check-errno rather than stat+mkdir. And then teach it to backtrack when an expected leading path goes missing after we created it (so mkdir("foo"), then mkdir("foo/bar"), then step back to mkdir("foo") if we got ENOENT).

I don't think the races are a big deal, though. As with the prune case, we will ultimately fail to create the lockfile and get a temporary failure rather than a corruption. So unless we actually have reports of it happening (and I have seen none), it's probably not worth spending much time on.

-Peff
Previous: Michael HaggertyNext: Duy Nguyen
Message 8 of 21 in “Fix two buffer overflows and remove a redundant var”
  1. 0/3 Fix two buffer overflows and remove a redundant varMichael Haggerty, Dec 17, 2013
  2. 1/3 prune-packed: fix a possible buffer overflowMichael Haggerty, Dec 17, 2013
  3. Duy NguyenDec 17, 2013
  4. Junio C HamanoDec 17, 2013
  5. Michael HaggertyDec 18, 2013
  6. Jeff KingDec 19, 2013
  7. Michael HaggertyDec 19, 2013
  8. Jeff KingDec 20, 2013
  9. Duy NguyenDec 19, 2013
  10. 2/3 prune_object_dir(): verify that path fits in the temporary bufferMichael Haggerty, Dec 17, 2013
  11. Junio C HamanoDec 17, 2013
  12. Jeff KingDec 17, 2013
  13. Junio C HamanoDec 18, 2013
  14. Jeff KingDec 18, 2013
  15. Junio C HamanoDec 18, 2013
  16. Jeff KingDec 18, 2013
  17. Junio C HamanoDec 18, 2013
  18. Jeff KingDec 18, 2013
  19. Antoine PelisseDec 17, 2013
  20. 3/3 cmd_repack(): remove redundant local variable "nr_packs"Michael Haggerty, Dec 17, 2013
  21. Stefan BellerDec 17, 2013

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.