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

[PATCH 0/6] fixing double-frees and leaks via setup_revisions()

From
Jeff King <peff@peff.net>
Date
Sep 19, 2025, 22:33 UTC
Message-ID
<20250919223351.GA3906184@coredump.intra.peff.net>
In-Reply-To
<20250919195626.GA2750626@coredump.intra.peff.net>
On Fri, Sep 19, 2025 at 03:56:26PM -0400, Jeff King wrote:
Show 20 quoted lines
> > > But really, I do not know that we need to NULL the whole thing. We have
> > > given the caller the reduced argc. The only argv invariant we are
> > > violating is that argv[argc] should be NULL (or in this case,
> > > argv[left]). Anything after argv+left should be considered
> > > uninitialized. So just:
> > >
> > >   argv[left] = NULL;
> > >
> > > would be enough, I'd think.
> > 
> > Even when strvec was passed and more than one element was eaten
> > after parsing?  strvec_clear() goes by .nr not stopping at the first
> > NULL IIRC.
> 
> Yes, there is a big can of worms here. ;) It turns out that many spots
> with strvecs were relying on leaving these entries untouched, and so
> setting any of them to NULL causes leaks.
> 
> I think I've got it mostly worked out, but that's why I haven't sent
> patches yet. Stay tuned.

OK, here's what I've come up with. It passes the regular test suite, as well as with LSan, ASan, and UBSan. There were definitely some ugly gotchas in there.

It _almost_ makes me think that setup_revisions() should never munge argv at all, and should just produce a separate strvec of unknown options. That keeps the concerns separate, and the extra allocation cast is trivial. But we'd have to modify every caller to handle the new world order.

So anyway, here it is:
  [1/6]: stash: tell setup_revisions() to free our allocated strings
    This fixes a real (albeit tiny) leak.
  [2/6]: revision: manage memory ownership of argv in setup_revisions()
    This fixes the double-free that started us off, but also addresses
    the related leak issues that our earlier discussion had.
  [3/6]: revision: add wrapper to setup_revisions() from a strvec
  [4/6]: treewide: use setup_revisions_from_strvec() when we have a strvec
  [5/6]: treewide: pass strvecs around for setup_revisions_from_strvec()
    The rest of this is optional. These three introduce a convenience
    wrapper, which I do think makes the code a little shorter and
    eliminates a possible footgun. But AFAIK it's not actually fixing
    any bugs.
  [6/6]: revision: retain argv NULL invariant in setup_revisions()
    This one does the NULL thing we discussed earlier for all callers.
    It turned up some interesting gotchas! One is that without the
    wrapper from patches 3-5, it introduces leaks for strvec users which
    assume (correctly) that setup_revisions() will never munge their
    argv or need to free anything. And two, lots of callers pass a NULL
    argv to setup_revisions. Yikes.
 bisect.c                    |  5 +---
 builtin/describe.c          |  3 ++-
 builtin/pack-objects.c      |  6 ++---
 builtin/rebase.c            |  3 +--
 builtin/stash.c             |  4 +--
 builtin/submodule--helper.c | 10 ++------
 http-push.c                 |  2 +-
 remote.c                    |  5 +---
 revision.c                  | 49 ++++++++++++++++++++++++++++++++++---
 revision.h                  |  2 ++
 sequencer.c                 |  7 +++---
 sequencer.h                 |  4 +--
 shallow.c                   |  4 +--
 shallow.h                   |  4 +--
 submodule.c                 |  2 +-
 t/t3903-stash.sh            | 11 +++++++++
 upload-pack.c               |  7 +++---
 17 files changed, 86 insertions(+), 42 deletions(-)
-Peff
Previous: Jeff KingNext: Jeff King
Message 10 of 26 in “[BUG] git stash show -p with invalid option aborts with double-free in show_stash() (strvec_clear)”
  1. Lauri NiskanenSep 19, 2025
  2. Kristoffer HaugsbakkSep 19, 2025
  3. Junio C HamanoSep 19, 2025
  4. Jeff KingSep 19, 2025
  5. Junio C HamanoSep 19, 2025
  6. Junio C HamanoSep 19, 2025
  7. Jeff KingSep 19, 2025
  8. Junio C HamanoSep 19, 2025
  9. Jeff KingSep 19, 2025
  10. 0/6 fixing double-frees and leaks via setup_revisions()Jeff King, Sep 19, 2025
  11. 1/6 stash: tell setup_revisions() to free our allocated stringsJeff King, Sep 19, 2025
  12. Junio C HamanoSep 22, 2025
  13. Jeff KingSep 22, 2025
  14. Junio C HamanoSep 22, 2025
  15. Jeff KingSep 22, 2025
  16. Junio C HamanoSep 22, 2025
  17. Jeff KingSep 23, 2025
  18. 2/6 revision: manage memory ownership of argv in setup_revisions()Jeff King, Sep 19, 2025
  19. 3/6 revision: add wrapper to setup_revisions() from a strvecJeff King, Sep 19, 2025
  20. Eric SunshineSep 20, 2025
  21. Jeff KingSep 20, 2025
  22. 4/6 treewide: use setup_revisions_from_strvec() when we have a strvecJeff King, Sep 19, 2025
  23. 5/6 treewide: pass strvecs around for setup_revisions_from_strvec()Jeff King, Sep 19, 2025
  24. Jeff KingSep 19, 2025
  25. 6/6 revision: retain argv NULL invariant in setup_revisions()Jeff King, Sep 19, 2025
  26. Jeff KingSep 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.