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

Re: [PATCH] line-log: protect inner strbuf from free

From
Derrick Stolee <stolee@gmail.com>
Date
Oct 3, 2024, 02:36 UTC
Message-ID
<1fc0d162-9814-4d94-ac67-2ea8e40495f4@gmail.com>
In-Reply-To
<20241002235639.GB3455554@coredump.intra.peff.net>
On 10/2/24 7:56 PM, Jeff King wrote:
> On Wed, Oct 02, 2024 at 04:07:04PM +0000, Derrick Stolee via GitGitGadget wrote:
...
Show 14 quoted lines
> Good catch. Your analysis looks correct, though I had two questions I
> managed to answer myself:
> 
>    1. This seems like an obvious use-after-free problem. Why didn't we
>       catch it sooner? I think the answer is that most uses of the
>       output_prefix callback happen via diff_line_prefix(), which was not
>       broken by 394affd46d. It's only line-log that was affected.
> 
>       Building with ASan and running:
> 
>         ./git log --graph -L :diff_line_prefix:diff.c
> 
>       shows the problem immediately (and that your patch fixes it).
>       Should we include a new test in this patch?
Thank you for sending a test in your second reply. I will include it in v2.
Show 7 quoted lines
>    2. If the caller isn't freeing it, then who does? Should diffopt
>       cleanup do so? The answer is "no", the pointer is not owned by that
>       struct. In your cases (1) and (3), the caller does so after
>       finishing with the diffopt struct. In case (2) it is effectively
>       "leaked", but still reachable by the static strbuf. That's not
>       great, and is a problem for eventual libification. But for now, we
>       can ignore it as it won't trigger the leak-checker.

I agree with this, including the potential for cleaning up the static strbuf and using the 'data' parameter like the other functions.

>       It does make me wonder what leak Patrick saw that caused him to
>       write 394affd46d, and whether we're now leaking in some case that
>       I'm missing.
Looking at the change, I can only guess that it was the previous use of
	char *prefix = "";

that signaled that an unfreeable string was being assigned to a non-const pointer. This signals that _something_ is wrong with the function, but the way that the buffer is returned by the function pointer is suspicious, too.

Show 7 quoted lines
> I do think this would have been a harder mistake to make if the callback
> simply returned a "const char *" pointer. We'd lose the ability to show
> prefixes with embedded NULs, but I'm not sure that's a big deal. It
> would also help for line-log to use the existing helper rather than
> inventing its own. So together on top something like this (which I'd
> probably turn into two patches if this seems to others like it's
> valuable and not just churn):

I do agree that changing the return type will make this easier to prevent and the code should be easier to read as well.

Your diffed patch looks pretty good. I made an attempt at guessing where you would have split them (first remove the duplicate method, then change the method prototype and callers).

I even took some time to attempt to remove the static strbuf from diff_output_prefix_callback() in favor of using the 'data' member of the diff_options struct, but it was not incredibly obvious how to communicate ownership of the struct which would need to store both the graph struct and the strbuf. Perhaps this would be good for #leftoverbits.

Thanks, -Stolee

Previous: Jeff KingNext: Jeff King
Message 4 of 24 in “line-log: protect inner strbuf from free”
  1. line-log: protect inner strbuf from freeDerrick Stolee via GitGitGadget, Oct 2, 2024
  2. Jeff KingOct 2, 2024
  3. Jeff KingOct 3, 2024
  4. Derrick StoleeOct 3, 2024
  5. Jeff KingOct 3, 2024
  6. Derrick StoleeOct 3, 2024
  7. Jeff KingOct 3, 2024
  8. 0/3 line-log: protect inner strbuf from freeDerrick Stolee via GitGitGadget, Oct 3, 2024
  9. 1/3 line-log: protect inner strbuf from freeDerrick Stolee via GitGitGadget, Oct 3, 2024
  10. Patrick SteinhardtOct 4, 2024
  11. 2/3 line-log: remove output_prefix()Jeff King via GitGitGadget, Oct 3, 2024
  12. 3/3 diff: modify output_prefix function pointerJeff King via GitGitGadget, Oct 3, 2024
  13. Junio C HamanoOct 3, 2024
  14. 0/5 diff output_prefix cleanupsJeff King, Oct 3, 2024
  15. 1/5 line-log: use diff_line_prefix() instead of custom helperJeff King, Oct 3, 2024
  16. 2/5 diff: drop line_prefix_length fieldJeff King, Oct 3, 2024
  17. 3/5 diff: return const char from output_prefix callbackJeff King, Oct 3, 2024
  18. 4/5 diff: return line_prefix directly when possibleJeff King, Oct 3, 2024
  19. 5/5 diff: store graph prefix buf in git_graph structJeff King, Oct 3, 2024
  20. Junio C HamanoOct 3, 2024
  21. Patrick SteinhardtOct 4, 2024
  22. Derrick StoleeOct 4, 2024
  23. Junio C HamanoOct 4, 2024
  24. Derrick StoleeOct 4, 2024

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.