Re: Segfault with merge-tree on multiple Git versions

2 messages, 2 authors, 2016-06-15 · open the first message on its own page

Re: Segfault with merge-tree on multiple Git versions

From: thomas <hidden>
Date: 2016-06-15 22:56:32

Charlie Smurthwaite [off-list ref] writes:
I am experiencing a segmentation fault in various versions of Git using
different repositories. Specifically, I have reproduced it using a
public repo and the latest stable Git version. Other repos trigger the
error on different versions.

Full info can be found below. Thanks,

Charlie


Test repository:
https://github.com/atech/mail

Test Command
git merge-tree 26bb22a052fef9f74063afd4fc6fc11fe200b19f
8d6bdf012941d876b2279994e02f1bb0d5c26e7d
d5ef97ac407d945f231cd7c8fb1cfe48b3a12083
I happened to walk past on IRC and found I could easily reproduce it, so
I bisected:

  35ffe7583108ab236dcf81226690388491d9962f is the first bad commit
  commit 35ffe7583108ab236dcf81226690388491d9962f
  Author: Junio C Hamano [off-list ref]
  Date:   Thu Dec 13 15:51:29 2012 -0800

      merge-tree: fix d/f conflicts
      
      The previous commit documented two known breakages revolving around
      a case where one side flips a tree into a blob (or vice versa),
      where the original code simply gets confused and feeds a mixture of
      trees and blobs into either the recursive merge-tree (and recursing
      into the blob will fail) or three-way merge (and merging tree contents
      together with blobs will fail).
      
      Fix it by feeding trees (and only trees) into the recursive
      merge-tree machinery and blobs (and only blobs) into the three-way
      content level merge machinery separately; when this happens, the
      entire merge has to be marked as conflicting at the structure level.
      
      Signed-off-by: Junio C Hamano [off-list ref]

It seems to be a vanilla null dereference:

  Program received signal SIGSEGV, Segmentation fault.
  0x0000000000453bf9 in add_merge_entry (entry=0x0) at builtin/merge-tree.c:24
  24              *merge_result_end = entry;
  (gdb) bt
  #0  0x0000000000453bf9 in add_merge_entry (entry=0x0) at builtin/merge-tree.c:24
  #1  0x00000000004545f4 in unresolved (info=0x7fffffffce90, n=0x7ff7f0) at builtin/merge-tree.c:265
  #2  0x0000000000454741 in threeway_callback (n=3, mask=7, dirmask=7, entry=0x7ff7f0, 
      info=0x7fffffffce90) at builtin/merge-tree.c:330
  #3  0x00000000005233f3 in traverse_trees (n=3, t=0x7fffffffcf10, info=0x7fffffffce90)
      at tree-walk.c:407
  #4  0x0000000000454792 in merge_trees_recursive (t=0x7fffffffcf10, base=0x800530 "lib/mail", 
      df_conflict=1) at builtin/merge-tree.c:341
  #5  0x0000000000454382 in unresolved_directory (info=0x7fffffffd120, n=0x800420, df_conflict=1)
      at builtin/merge-tree.c:216
  #6  0x0000000000454507 in unresolved (info=0x7fffffffd120, n=0x800420) at builtin/merge-tree.c:253
  #7  0x0000000000454741 in threeway_callback (n=3, mask=7, dirmask=7, entry=0x800420, 
      info=0x7fffffffd120) at builtin/merge-tree.c:330
  #8  0x00000000005233f3 in traverse_trees (n=3, t=0x7fffffffd1a0, info=0x7fffffffd120)
      at tree-walk.c:407
  #9  0x0000000000454792 in merge_trees_recursive (t=0x7fffffffd1a0, base=0x7fd170 "lib", df_conflict=1)
      at builtin/merge-tree.c:341
  #10 0x0000000000454382 in unresolved_directory (info=0x7fffffffd3b0, n=0x8069f0, df_conflict=1)
      at builtin/merge-tree.c:216
  #11 0x0000000000454507 in unresolved (info=0x7fffffffd3b0, n=0x8069f0) at builtin/merge-tree.c:253
  #12 0x0000000000454741 in threeway_callback (n=3, mask=7, dirmask=7, entry=0x8069f0, 
      info=0x7fffffffd3b0) at builtin/merge-tree.c:330
  #13 0x00000000005233f3 in traverse_trees (n=3, t=0x7fffffffd450, info=0x7fffffffd3b0)
      at tree-walk.c:407
  #14 0x0000000000454792 in merge_trees_recursive (t=0x7fffffffd450, base=0x5510fc "", df_conflict=0)
      at builtin/merge-tree.c:341
  #15 0x00000000004547bc in merge_trees (t=0x7fffffffd450, base=0x5510fc "") at builtin/merge-tree.c:346
  #16 0x00000000004548ef in cmd_merge_tree (argc=4, argv=0x7fffffffd728, prefix=0x0)
      at builtin/merge-tree.c:373
  #17 0x00000000004056ec in run_builtin (p=0x7a1c88 <commands.20888+1416>, argc=4, argv=0x7fffffffd728)
      at git.c:273
  #18 0x000000000040587f in handle_internal_command (argc=4, argv=0x7fffffffd728) at git.c:434
  #19 0x0000000000405a4b in main (argc=4, argv=0x7fffffffd728) at git.c:523

Unfortunately I'm not familiar with the merge code, but if you can't
reproduce at your end let me know.

-- 
Thomas Rast
trast@{inf,student}.ethz.ch

Re: Segfault with merge-tree on multiple Git versions

From: John Keeping <hidden>
Date: 2016-06-15 22:56:32

On Wed, Mar 27, 2013 at 04:53:27PM +0100, thomas wrote:
Charlie Smurthwaite [off-list ref] writes:
quoted
I am experiencing a segmentation fault in various versions of Git using
different repositories. Specifically, I have reproduced it using a
public repo and the latest stable Git version. Other repos trigger the
error on different versions.

Full info can be found below. Thanks,

Charlie


Test repository:
https://github.com/atech/mail

Test Command
git merge-tree 26bb22a052fef9f74063afd4fc6fc11fe200b19f
8d6bdf012941d876b2279994e02f1bb0d5c26e7d
d5ef97ac407d945f231cd7c8fb1cfe48b3a12083
I happened to walk past on IRC and found I could easily reproduce it, so
I bisected:

  35ffe7583108ab236dcf81226690388491d9962f is the first bad commit
  commit 35ffe7583108ab236dcf81226690388491d9962f
  Author: Junio C Hamano [off-list ref]
  Date:   Thu Dec 13 15:51:29 2012 -0800

      merge-tree: fix d/f conflicts
      
      The previous commit documented two known breakages revolving around
      a case where one side flips a tree into a blob (or vice versa),
      where the original code simply gets confused and feeds a mixture of
      trees and blobs into either the recursive merge-tree (and recursing
      into the blob will fail) or three-way merge (and merging tree contents
      together with blobs will fail).
      
      Fix it by feeding trees (and only trees) into the recursive
      merge-tree machinery and blobs (and only blobs) into the three-way
      content level merge machinery separately; when this happens, the
      entire merge has to be marked as conflicting at the structure level.
      
      Signed-off-by: Junio C Hamano [off-list ref]
Looks like a simple typo in merge-tree.c::unresolved:

-- >8 --
merge-tree: fix typo in merge-tree.c::unresolved

When calculating whether there is a d/f conflict, the calculation of
whether both sides are directories generates an incorrect references
mask because it does not use the loop index to set the correct bit.
Fix this typo.

Signed-off-by: John Keeping <redacted>
diff --git a/builtin/merge-tree.c b/builtin/merge-tree.c
index e0d0b7d..bc912e3 100644
--- a/builtin/merge-tree.c
+++ b/builtin/merge-tree.c
@@ -245,7 +245,7 @@ static void unresolved(const struct traverse_info *info, struct name_entry n[3])
 	unsigned dirmask = 0, mask = 0;
 
 	for (i = 0; i < 3; i++) {
-		mask |= (1 << 1);
+		mask |= (1 << i);
 		if (n[i].mode && S_ISDIR(n[i].mode))
 			dirmask |= (1 << i);
 	}
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help