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

Re: Potential Null Pointer Dereference detected by static analysis tool

From
Jeff King <peff@peff.net>
Date
Aug 18, 2025, 04:48 UTC
Message-ID
<20250818044807.GA51803@coredump.intra.peff.net>
In-Reply-To
<7f289d4f-0a9d-480d-a5a9-7f4d4d24626b@web.de>
On Sun, Aug 17, 2025 at 11:27:12AM +0200, René Scharfe wrote:
Show 15 quoted lines
> > @@ -546,7 +544,7 @@ static void process_object(struct object *obj, const char *path, void *data)
> >  
> >  	if (oideq(&pcd->looking_for, &obj->oid) && !pcd->dst->len) {
> >  		reset_revision_walk();
> > -		describe_commit(&pcd->current_commit, pcd->dst);
> > +		describe_commit(pcd->current_commit, pcd->dst);
> 
> pcd->current_commit is initialized to NULL below, but
> traverse_commit_list() without a filter must have set it via our
> process_commit() callback before we get to the describe_commit() call.
> 
> Or are there weird repositories (e.g., just a blob, just a tag) that can
> cause traverse_commit_list() to call its show_object() callback without
> ever calling its show_commit() callback?  I don't see how, but may be
> missing some way.

If there are, then I think the current code would segfault, too. It initializes &pcd->current_commit to the null oid, and then describe_commit() resolves that via lookup_commit_reference(). That would return NULL, and the next line dereferencing the result would segfault.

And it would be a counter-example to the claim that the call to lookup_commit_reference() in describe_commit() never fails. ;)

I think your intuition is right that we could get the traversal code to call show_object() without show_commit() in general. E.g. just:

  git init
  git tag foo $(echo bar | git hash-object -w --stdin)
  git rev-list --all --objects

would do so. But in this code our traversal always starts from HEAD, which must be a commit (and this is enforced by the refs code). So you'd have to corrupt your repository like:

  # do this in two steps since redirecting to .git/HEAD breaks the
  # repository for a moment!
  tag=$(git rev-parse foo)
  echo $tag >.git/HEAD

And indeed, the current code does then segfault on "git describe foo" at the spot I mentioned. Even though the repository state here is unexpected and corrupt, I do think we should probably be more defensive and avoid the segfault.

I also find it a bit funny that describing a blob only walks from HEAD (and not say, all refs or ones matching --match/--exclude, etc). It is documented that way, though. Actually, I find the whole feature a bit pointless now that we have the diff "--find-object" option. Reading 15af58c1ad (diffcore: add a pickaxe option to find a specific blob, 2018-01-04), I think the git-describe behavior is mostly considered a mistake (which we have to keep around for historical reasons). I guess another possible candidate for removing in Git 3.0. :)

-Peff
Previous: René ScharfeNext: Jeff King
Message 6 of 28 in “Potential Null Pointer Dereference detected by static analysis tool”
  1. ChengAug 13, 2025
  2. Phillip WoodAug 13, 2025
  3. Jeff KingAug 14, 2025
  4. Phillip WoodAug 15, 2025
  5. René ScharfeAug 17, 2025
  6. Jeff KingAug 18, 2025
  7. Jeff KingAug 18, 2025
  8. René ScharfeAug 18, 2025
  9. Jeff KingAug 18, 2025
  10. Jeff KingAug 18, 2025
  11. 0/5 fix segfault and other oddities describing blobsJeff King, Aug 18, 2025
  12. 1/5 describe: pass oid struct by const pointerJeff King, Aug 18, 2025
  13. Junio C HamanoAug 18, 2025
  14. 2/5 describe: error if blob not foundJeff King, Aug 18, 2025
  15. Junio C HamanoAug 18, 2025
  16. Patrick SteinhardtAug 19, 2025
  17. René ScharfeAug 19, 2025
  18. 3/5 describe: catch unborn branch in describe_blob()Jeff King, Aug 18, 2025
  19. Junio C HamanoAug 18, 2025
  20. Jeff KingAug 18, 2025
  21. 4/5 describe: handle blob traversal with no commitsJeff King, Aug 18, 2025
  22. Patrick SteinhardtAug 19, 2025
  23. Jeff KingAug 19, 2025
  24. Patrick SteinhardtAug 20, 2025
  25. 4/5 describe: handle blob traversal with no commitsJeff King, Aug 20, 2025
  26. 5/5 describe: pass commit to describe_commit()Jeff King, Aug 18, 2025
  27. Patrick SteinhardtAug 19, 2025
  28. Jeff KingAug 19, 2025

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.