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

[PATCH 03/10] merge: do not point "branch" to a resolve_ref()'s static buffer

From
Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Date
Nov 15, 2011, 06:07 UTC
Message-ID
<1321337276-17803-3-git-send-email-pclouds@gmail.com>
In-Reply-To
<1321337276-17803-1-git-send-email-pclouds@gmail.com>

resolve_ref() may return a pointer to a static buffer. Callers that use this value longer than a couple of statements should copy the value to avoid some hidden resolve_ref() call that may change the static buffer's value.

The bug found by Tony Wang <wwwjfy@gmail.com> in builtin/merge.c demonstrates this. The first call is in cmd_merge()

branch = resolve_ref("HEAD", head_sha1, 0, &flag);

Then deep in lookup_commit_or_die() a few lines after, resolve_ref() may be called again and destroy "branch".

lookup_commit_or_die
 lookup_commit_reference
  lookup_commit_reference_gently
   parse_object
    lookup_replace_object
     do_lookup_replace_object
      prepare_replace_object
       for_each_replace_ref
        do_for_each_ref
         get_loose_refs
          get_ref_dir
           get_ref_dir
            resolve_ref

Ask resolve_ref() to allocate a new buffer instead of returning static buffer.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 builtin/merge.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/builtin/merge.c b/builtin/merge.c
index 1be6f3b..1a3095f 100644
--- a/builtin/merge.c
+++ b/builtin/merge.c
@@ -1087,6 +1087,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
 	struct commit_list *common = NULL;
 	const char *best_strategy = NULL, *wt_strategy = NULL;
 	struct commit_list **remotes = &remoteheads;
+	char *branch_ref;
 
 	if (argc == 2 && !strcmp(argv[1], "-h"))
 		usage_with_options(builtin_merge_usage, builtin_merge_options);
@@ -1095,7 +1096,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
 	 * Check if we are _not_ on a detached HEAD, i.e. if there is a
 	 * current branch.
 	 */
-	branch = resolve_ref("HEAD", head_sha1, 0, &flag, 0);
+	branch = branch_ref = resolve_ref("HEAD", head_sha1, 0, &flag, 1);
 	if (branch && !prefixcmp(branch, "refs/heads/"))
 		branch += 11;
 	if (!branch || is_null_sha1(head_sha1))
@@ -1497,5 +1498,6 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
 		ret = suggest_conflicts(option_renormalize);
 
 done:
+	free(branch_ref);
 	return ret;
 }
-- 
1.7.4.74.g639db
Previous: Nguyễn Thái Ngọc DuyNext: Nguyễn Thái Ngọc Duy
Message 19 of 31 in “Re: git bug(?) for commit baf18fc261ca475343fe3cb9cd2c0dded4bc1bb7”
  1. Nguyen Thai Ngoc DuyNov 7, 2011
  2. Tony WangNov 7, 2011
  3. Nguyen Thai Ngoc DuyNov 7, 2011
  4. Tony WangNov 7, 2011
  5. Nguyen Thai Ngoc DuyNov 7, 2011
  6. Copy resolve_ref() return value for longer useNguyễn Thái Ngọc Duy, Nov 8, 2011
  7. Junio C HamanoNov 13, 2011
  8. Nguyen Thai Ngoc DuyNov 13, 2011
  9. Junio C HamanoNov 13, 2011
  10. 1/2 Convert many resolve_ref() calls to read_ref*() and ref_exists()Nguyễn Thái Ngọc Duy, Nov 13, 2011
  11. 2/2 Copy resolve_ref() return value for longer useNguyễn Thái Ngọc Duy, Nov 13, 2011
  12. Junio C HamanoNov 13, 2011
  13. Nguyen Thai Ngoc DuyNov 14, 2011
  14. Junio C HamanoNov 14, 2011
  15. Jeff KingNov 14, 2011
  16. Nguyen Thai Ngoc DuyNov 15, 2011
  17. 01/10 Allow resolve_ref() caller to decide whether to receive static bufferNguyễn Thái Ngọc Duy, Nov 15, 2011
  18. 02/10 cmd_merge: convert to single exit pointNguyễn Thái Ngọc Duy, Nov 15, 2011
  19. 03/10 merge: do not point "branch" to a resolve_ref()'s static bufferNguyễn Thái Ngọc Duy, Nov 15, 2011
  20. 04/10 commit: move resolve_ref() closer to where the return value is usedNguyễn Thái Ngọc Duy, Nov 15, 2011
  21. 05/10 checkout: do not try xstrdup() on NULLNguyễn Thái Ngọc Duy, Nov 15, 2011
  22. 06/10 reflog-walk.c: request allocated buffer from resolve_ref()Nguyễn Thái Ngọc Duy, Nov 15, 2011
  23. 07/10 receive-pack: request resolve_ref() to allocate new bufferNguyễn Thái Ngọc Duy, Nov 15, 2011
  24. 08/10 notes: request resolve_ref() to allocate new bufferNguyễn Thái Ngọc Duy, Nov 15, 2011
  25. 09/10 fmt-merge-msg: request resolve_ref() to allocate new bufferNguyễn Thái Ngọc Duy, Nov 15, 2011
  26. 10/10 branch: request resolve_ref() to allocate new bufferNguyễn Thái Ngọc Duy, Nov 15, 2011
  27. Junio C HamanoNov 15, 2011
  28. Junio C HamanoNov 13, 2011
  29. Tony WangDec 10, 2011
  30. Nguyen Thai Ngoc DuyDec 10, 2011
  31. Tony WangDec 11, 2011

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.