Re: Segfault when rebasing with --autosquash

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sat, May 02, 2020 at 09:22:09PM -0400, Paul Ganssle wrote:

> Unfortunately, I have been unable to /deliberately/ create a repository
> that exhibits this behavior using `git absorb`, but last time it
> happened I created a fork of my repo and trimmed out as many commits as
> I could while still exhibiting the behavior, you can find it here, along
> with instructions on how to trigger the bug:
> https://github.com/pganssle-bug-mwes/git_autosquash_bug_mwe

Thanks, this is a good reproduction recipe.

The todo list looks like this:

  pick f4af993 Add sphinx configuration
  pick 1203b9a Add tox environment for building docs
  pick bc28c93 Add minimal documentation for the ZoneInfo module
  pick a5f6347 fixup! Add minimal documentation for the ZoneInfo module
  pick ba18026 fixup! Add sphinx configuration
  pick 04bac75 fixup! Add sphinx configuration
  pick d25a6ae fixup! Add sphinx configuration
  pick 3747813 fixup! Add minimal documentation for the ZoneInfo module
  pick 64ebca8 fixup! Add minimal documentation for the ZoneInfo module
  pick 6c6a5a2 fixup! 3747813a8df9675a7c8b33c4fc665adc52d86b5b

The interesting one is the last one, which is a fixup of another fixup.

Building with ASan, I get this:

  ==1857141==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60400000084c at pc 0x555555c3a37b bp 0x7fffffffbfb0 sp 0x7fffffffbfa8
  WRITE of size 4 at 0x60400000084c thread T0
      #0 0x555555c3a37a in todo_list_rearrange_squash /home/peff/compile/git/sequencer.c:5391
      #1 0x555555c386af in complete_action /home/peff/compile/git/sequencer.c:5196
      #2 0x555555842c2f in do_interactive_rebase builtin/rebase.c:366
      #3 0x55555584320a in run_sequencer_rebase builtin/rebase.c:401
      #4 0x555555849fc5 in run_specific_rebase builtin/rebase.c:949
      #5 0x555555855b29 in cmd_rebase builtin/rebase.c:2071
      #6 0x5555556f23b4 in run_builtin /home/peff/compile/git/git.c:447
      #7 0x5555556f2b06 in handle_builtin /home/peff/compile/git/git.c:672
      #8 0x5555556f3d2d in cmd_main /home/peff/compile/git/git.c:840
      #9 0x555555900565 in main /home/peff/compile/git/common-main.c:52
      #10 0x7ffff7322e0a in __libc_start_main ../csu/libc-start.c:308
      #11 0x5555556ee0d9 in _start (/home/peff/compile/git/git-rebase+0x19a0d9)

The code in question looks like this:

                  if (i2 >= 0) {
                          rearranged = 1;
                          todo_list->items[i].command =
                                  starts_with(subject, "fixup!") ?
                                  TODO_FIXUP : TODO_SQUASH;
                          if (next[i2] < 0)
                                  next[i2] = i;
                          else
                                  next[tail[i2]] = i;
                          tail[i2] = i;

where "i" is the index of the fixup commit and "i2" is the index of the
thing we're fixing up. When we hit that final fixup, our next[i2] will
not be negative. The commit we're fixing is already part of a fixup
chain. But it's not _itself_ being fixed up already, so its tail[i2] is
negative. And thus we'll try to write to next[-1].

I'm not sure if there's a simple logic error here, or a more fundamental
issue with the "next" array having an overloaded meaning. This all comes
from c44a4c650c (rebase -i: rearrange fixup/squash lines using the
rebase--helper, 2017-07-14), so I've added Dscho to the cc.

-Peff



[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux