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

Re: [RFC PATCH v3 00/17] Return of smart HTTP

From
Shawn O. Pearce <spearce@spearce.org>
Date
Oct 15, 2009, 20:45 UTC
Message-ID
<20091015204543.GP10505@spearce.org>
In-Reply-To
<7vfx9k4d33.fsf@alter.siamese.dyndns.org>
Junio C Hamano <gitster@pobox.com> wrote:
Show 8 quoted lines
> "Shawn O. Pearce" <spearce@spearce.org> writes:
> 
> > It does.  It is caused by the disconnect_helper call inside of
> > fetch_with_import.  You can't disconnect inside of the fetch method
> > of a transport, the caller is going to disconnect you a second time.
> > ...
> > This bug isn't due to the merge, its a bug in Johan's series that
> > needs to be fixed before it could merge down to next/master.
...
> I am a bit confused about your diagnosis, though.  As far as I recall,
> Johan's topic itself nor 'pu' with Johan's topic but without v2 of
> sp/smart-http did not have the issue.

Sadly, sometimes double frees do not result in segfaults, other times they do. The reason you are not seeing a problem with these other variants is because of luck, not code correctness.

Actually, after some further research, the bug is not Johan's but is actually Daniel's. Johan, I apologize for claiming it was your bug.

In:
  commit 23a3380ee9c2d5164712c40f8821cb0fba24e80c
  Author: Daniel Barkalow <barkalow@iabervon.org>
  Date:   Thu Sep 3 22:14:01 2009 -0400
    Add support for "import" helper command

Daniel introduces the fetch_with_import() function to transport-helper.c. This method calls disconnect_helper():

+static int fetch_with_import(struct transport *transport,
+                            int nr_heads, struct ref **to_fetch)
+{
...
+       disconnect_helper(transport);
+       finish_command(&fastimport);

Unfortunately this is in the middle of the transport_fetch() call stack; transport_fetch() called the static fetch() function in transport-helper.c, which in turn called fetch_with_import().

Callers (e.g. builtin-fetch.c) invoke transport_close() when they are done with the handle (see line 704). That in turn calls disconnect_helper() a second time.

The disconnect_helper function is not prepared to be called twice:
static int disconnect_helper(struct transport *transport)
{
	struct helper_data *data = transport->data;
	if (data->helper) {
	...
	}
	free(data);
	return 0;
}

Because of that unexpected invocation inside of fetch_with_import we have already free'd the memory block used by transport->data, and the second invocation attempts to free it again. Worse, if the block was reused by a subsequent malloc, data->helper might not be NULL, and we'd enter into the if block and do its work again.

Long story short, transport_close() is what is supposed to perform the work that disconnect_helper does, as its the final thing right before we free the struct transport block. Free'ing the data block inside of the fetch or push functions is wrong.

Its fine to close the helper and restart it within the single lifespan of a struct transport, but dammit, don't free the struct helper_data until transport_close().

-- 
Shawn.
Previous: Junio C HamanoNext: Nanako Shiraishi
Message 28 of 52 in “Return of smart HTTP”
  1. 00/17 Return of smart HTTPShawn O. Pearce, Oct 15, 2009
  2. 01/17 pkt-line: Add strbuf based functionsShawn O. Pearce, Oct 15, 2009
  3. 02/17 pkt-line: Make packet_read_line easier to debugShawn O. Pearce, Oct 15, 2009
  4. 03/17 fetch-pack: Use a strbuf to compose the want listShawn O. Pearce, Oct 15, 2009
  5. 04/17 Move "get_ack()" back to fetch-packShawn O. Pearce, Oct 15, 2009
  6. 05/17 Add multi_ack_detailed capability to fetch-pack/upload-packShawn O. Pearce, Oct 15, 2009
  7. 06/17 remote-curl: Refactor walker initializationShawn O. Pearce, Oct 15, 2009
  8. 07/17 fetch: Allow transport -v -v -v to set verbosity to 3Shawn O. Pearce, Oct 15, 2009
  9. 08/17 remote-helpers: Fetch more than one ref in a batchShawn O. Pearce, Oct 15, 2009
  10. 09/17 remote-helpers: Support custom transport optionsShawn O. Pearce, Oct 15, 2009
  11. 10/17 Move WebDAV HTTP push under remote-curlShawn O. Pearce, Oct 15, 2009
  12. Tay Ray ChuanOct 19, 2009
  13. Shawn O. PearceOct 28, 2009
  14. Tay Ray ChuanOct 28, 2009
  15. 11/17 Git-aware CGI to provide dumb HTTP transportShawn O. Pearce, Oct 15, 2009
  16. 12/17 Add stateless RPC options to upload-pack, receive-packShawn O. Pearce, Oct 15, 2009
  17. 13/17 Smart fetch and push over HTTP: server sideShawn O. Pearce, Oct 15, 2009
  18. 14/17 Discover refs via smart HTTP server when availableShawn O. Pearce, Oct 15, 2009
  19. 15/17 Smart push over HTTP: client sideShawn O. Pearce, Oct 15, 2009
  20. 16/17 Smart fetch over HTTP: client sideShawn O. Pearce, Oct 15, 2009
  21. 17/17 Smart HTTP fetch: gzip requestsShawn O. Pearce, Oct 15, 2009
  22. Junio C HamanoOct 15, 2009
  23. Nanako ShiraishiOct 15, 2009
  24. Shawn O. PearceOct 15, 2009
  25. Johan HerlandOct 15, 2009
  26. Shawn O. PearceOct 15, 2009
  27. Junio C HamanoOct 15, 2009
  28. Shawn O. PearceOct 15, 2009
  29. Nanako ShiraishiOct 22, 2009
  30. Daniel BarkalowOct 22, 2009
  31. Fix memory leak in transport-helperDaniel Barkalow, Oct 27, 2009
  32. Johannes SchindelinOct 27, 2009
  33. Daniel BarkalowOct 27, 2009
  34. Jeff KingOct 27, 2009
  35. Johannes SchindelinOct 27, 2009
  36. Daniel BarkalowOct 27, 2009
  37. Junio C HamanoOct 28, 2009
  38. Mark LodatoOct 16, 2009
  39. Shawn O. PearceOct 16, 2009
  40. Mark LodatoOct 16, 2009
  41. Shawn O. PearceOct 16, 2009
  42. Marcus CamenOct 22, 2009
  43. 0/6 http: push and test fixesTay Ray Chuan, Oct 25, 2009
  44. 1/7 http-push: fix check condition on http.c::finish_http_pack_request()Tay Ray Chuan, Oct 25, 2009
  45. 2/7 http-push: allow stderr messages to appear alongside helper_status onesTay Ray Chuan, Oct 25, 2009
  46. 3/7 http-push: add more 'error <dst> <why>' status reportsTay Ray Chuan, Oct 25, 2009
  47. 4/7 t5540-http-push: expect success when pushing without argumentsTay Ray Chuan, Oct 25, 2009
  48. 5/7 t5540-http-push: check existence of fetched filesTay Ray Chuan, Oct 25, 2009
  49. 6/7 t5540-http-push: when deleting remote refs, don't need to branch -d -rTay Ray Chuan, Oct 25, 2009
  50. 7/7 t5540-http-push: remove redundant fetchesTay Ray Chuan, Oct 25, 2009
  51. Clemens BuchacherOct 25, 2009
  52. Clemens BuchacherOct 25, 2009

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.