#1131301 Heap corruption when running 'git difftool --dir-diff' against two refs with identical contents

Package:
git
Source:
git
Description:
fast, scalable, distributed revision control system
Submitter:
Aaron Rainbolt
Date:
2026-06-11 09:47:02 UTC
Severity:
normal
Tags:
#1131301#5
Date:
2026-03-20 00:36:26 UTC
From:
To:
On a freshly installed, CLI-only Debian 13 virtual machine running
under KVM:

    sudo apt install git gdb
    git clone https://salsa.debian.org/grub-team/grub.git
    cd grub
    git difftool --dir-diff HEAD

Almost every time this is run, Git will segfault. Sometimes the command
will exit successfully. Occasionally, the message 'free(): invalid
pointer' will appear and Git will crash with SIGABRT instead. The issue
is intermittent but easily reproducible.

This is fixed by upstream already:
https://github.com/git/git/commit/98e4015593

#1131301#16
Date:
2026-06-11 09:34:59 UTC
From:
To:
I can confirm this bug. In addition, I found that it is deterministic
rather than intermittent: the crash occurs exactly when the resulting
dir-diff is empty. In run_dir_diff() (builtin/difftool.c), the
statement "if (!i) goto finish;" jumps to the cleanup label, where
hashmap_clear_and_free() is then called on the hashmaps wt_modified
and tmp_modified, which at that point have not yet been initialized.

The following steps reproduce the crash reliably on my system (Debian
13.5, git 1:2.47.3-0+deb13u1):

cd "$(mktemp -d)" && git init -q . \
&& git config user.email t@example.com && git config user.name t \
&& echo x > f.txt && git add f.txt && git commit -qm init \
&& git difftool -d -x true
=> Segmentation fault (core dumped)

Running the same command after modifying f.txt (i.e. with a non-empty
diff) completes without error, which supports the empty-diff analysis
above.

To rule out local configuration, I also ran the same steps in a
pristine container:

docker run --rm debian:trixie bash -c '
apt-get update -qq && apt-get install -y -qq git
mkdir /repro && cd /repro && git init -q .
git config user.email t@example.com && git config user.name t
echo x > f.txt && git add f.txt && git commit -qm init
git difftool -d -x true'
=> Segmentation fault (core dumped), exit code 139

The same test in a debian:sid container (git 2.53.0) does not crash,
which is consistent with upstream fix 98e4015593 already referenced in
this bug report.

Backtrace obtained with the dbgsym package:

#0 hashmap_iter_next (iter=<synthetic pointer>) at ./hashmap.c:299
#1 free_individual_entries (map=0x7fffffffc460, entry_offset=0) at
./hashmap.c:183
#2 hashmap_clear_ (map=0x7fffffffc460, entry_offset=0) at ./hashmap.c:207
#3 run_dir_diff (extcmd=0x0, symlinks=1, ...) at builtin/difftool.c:667
#4 cmd_difftool (...) at builtin/difftool.c:801

Since this makes "git difftool --dir-diff" crash on every clean
working tree, and the upstream fix is a small, self-contained
HASHMAP_INIT change, could it be considered for inclusion in a trixie
point release?