git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [BUG] git stash show -p with invalid option aborts with double-free in show_stash() (strvec_clear)
@ 2025-09-19 10:18 Lauri Niskanen
  2025-09-19 13:11 ` Kristoffer Haugsbakk
  0 siblings, 1 reply; 26+ messages in thread
From: Lauri Niskanen @ 2025-09-19 10:18 UTC (permalink / raw)
  To: git

What did you do before the bug happened?

Create a repo and a stash entry, then invoke `git stash show -p` with
an invalid option:

git init repro
cd repro
touch a
git add a
git commit -m init
echo x >> a
git stash
git stash show -p --invalid


What did you expect to happen?

Git should print a usage / option error and exit cleanly without crashing.


What happened instead?

free(): double free detected in tcache 2


GDB backtrace:
#0  __pthread_kill_implementation (threadid=<optimized out>,
signo=signo@entry=6, no_tid=no_tid@entry=0) at pthread_kill.c:44
#1  0x00007ffff7c98a13 in __pthread_kill_internal (threadid=<optimized
out>, signo=6) at pthread_kill.c:89
#2  0x00007ffff7c3e410 in __GI_raise (sig=sig@entry=6) at
../sysdeps/posix/raise.c:26
#3  0x00007ffff7c2557a in __GI_abort () at abort.c:77
#4  0x00007ffff7c26613 in __libc_message_impl
(fmt=fmt@entry=0x7ffff7db4355 "%s\n") at
../sysdeps/posix/libc_fatal.c:138
#5  0x00007ffff7ca2d65 in malloc_printerr
(str=str@entry=0x7ffff7db7d78 "free(): double free detected in tcache
2") at malloc.c:5892
#6  0x00007ffff7ca82e8 in tcache_double_free_verify (e=<optimized
out>) at malloc.c:3350
#7  0x00007ffff7ca80a5 in __GI___libc_free (mem=<optimized out>) at
malloc.c:3547
#8  0x00005555558570ce in strvec_clear (array=0x7fffffffc580) at
/usr/src/debug/git/git/strvec.c:134
#9  0x000055555567d9f9 in show_stash (argc=<optimized out>,
argv=<optimized out>, prefix=<optimized out>, repo=<optimized out>) at
builtin/stash.c:1047
#10 0x0000555555686f25 in cmd_stash (argc=3, argv=0x5555559bd260,
prefix=0x0, repo=0x555555992ae0 <the_repo.lto_priv>) at
builtin/stash.c:2410
#11 0x000055555555fd43 in run_builtin (p=0x555555984698
<commands.lto_priv+2904>, argc=<optimized out>, argv=<optimized out>,
repo=0x555555992ae0 <the_repo.lto_priv>) at
/usr/src/debug/git/git/git.c:480
#12 handle_builtin (args=args@entry=0x7fffffffe1d0) at
/usr/src/debug/git/git/git.c:746
#13 0x00005555555608a2 in run_argv (args=0x7fffffffe1d0) at
/usr/src/debug/git/git/git.c:813
#14 cmd_main (argc=<optimized out>, argv=<optimized out>) at
/usr/src/debug/git/git/git.c:953
#15 0x000055555555d784 in main (argc=5, argv=0x7fffffffe518) at
/usr/src/debug/git/git/common-main.c:9

Valgrind:
==2507916== Memcheck, a memory error detector
==2507916== Copyright (C) 2002-2024, and GNU GPL'd, by Julian Seward et al.
==2507916== Using Valgrind-3.25.1 and LibVEX; rerun with -h for copyright info
==2507916== Command: git stash show -p --invalid
==2507916==
==2507916== Invalid free() / delete / delete[] / realloc()
==2507916==    at 0x4CB18EF: free (vg_replace_malloc.c:989)
==2507916==    by 0x43030CD: strvec_clear (strvec.c:134)
==2507916==    by 0x41299F8: show_stash.lto_priv.0 (stash.c:1047)
==2507916==    by 0x4132F24: cmd_stash (stash.c:2410)
==2507916==    by 0x400BD42: UnknownInlinedFun (git.c:480)
==2507916==    by 0x400BD42: handle_builtin (git.c:746)
==2507916==    by 0x400C8A1: UnknownInlinedFun (git.c:813)
==2507916==    by 0x400C8A1: cmd_main (git.c:953)
==2507916==    by 0x4009783: main (common-main.c:9)
==2507916==  Address 0x4ff4540 is 0 bytes inside a block of size 8 free'd
==2507916==    at 0x4CB18EF: free (vg_replace_malloc.c:989)
==2507916==    by 0x43030CD: strvec_clear (strvec.c:134)
==2507916==    by 0x41299F8: show_stash.lto_priv.0 (stash.c:1047)
==2507916==    by 0x4132F24: cmd_stash (stash.c:2410)
==2507916==    by 0x400BD42: UnknownInlinedFun (git.c:480)
==2507916==    by 0x400BD42: handle_builtin (git.c:746)
==2507916==    by 0x400C8A1: UnknownInlinedFun (git.c:813)
==2507916==    by 0x400C8A1: cmd_main (git.c:953)
==2507916==    by 0x4009783: main (common-main.c:9)
==2507916==  Block was alloc'd at
==2507916==    at 0x4CAE7A8: malloc (vg_replace_malloc.c:446)
==2507916==    by 0x4E6E2AF: strdup (strdup.c:42)
==2507916==    by 0x4129624: UnknownInlinedFun (wrapper.c:43)
==2507916==    by 0x4129624: UnknownInlinedFun (strvec.c:25)
==2507916==    by 0x4129624: show_stash.lto_priv.0 (stash.c:994)
==2507916==    by 0x4132F24: cmd_stash (stash.c:2410)
==2507916==    by 0x400BD42: UnknownInlinedFun (git.c:480)
==2507916==    by 0x400BD42: handle_builtin (git.c:746)
==2507916==    by 0x400C8A1: UnknownInlinedFun (git.c:813)
==2507916==    by 0x400C8A1: cmd_main (git.c:953)
==2507916==    by 0x4009783: main (common-main.c:9)
==2507916==
usage: git stash show [-u | --include-untracked | --only-untracked]
[<diff-options>] [<stash>]

    -u, --[no-]include-untracked
                          include untracked files in the stash
    --only-untracked      only show untracked files in the stash

==2507916==
==2507916== HEAP SUMMARY:
==2507916==     in use at exit: 696,349 bytes in 371 blocks
==2507916==   total heap usage: 750 allocs, 380 frees, 1,221,944 bytes allocated
==2507916==
==2507916== LEAK SUMMARY:
==2507916==    definitely lost: 3 bytes in 1 blocks
==2507916==    indirectly lost: 0 bytes in 0 blocks
==2507916==      possibly lost: 120 bytes in 3 blocks
==2507916==    still reachable: 696,226 bytes in 367 blocks
==2507916==         suppressed: 0 bytes in 0 blocks
==2507916== Rerun with --leak-check=full to see details of leaked memory
==2507916==
==2507916== For lists of detected and suppressed errors, rerun with: -s
==2507916== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)


[System Info]
git version:
git version 2.51.0
cpu: x86_64
built from commit: c44beea485f0f2feaf460e2ac87fdd5608d63cf0
sizeof-long: 8
sizeof-size_t: 8
shell-path: /bin/sh
libcurl: 8.15.0
OpenSSL: OpenSSL 3.5.2 5 Aug 2025
zlib-ng: 2.2.5
SHA-1: SHA1_DC
SHA-256: SHA256_BLK
default-ref-format: files
default-hash: sha1
uname: Linux 6.16.7-arch1-1 #1 SMP PREEMPT_DYNAMIC Thu, 11 Sep 2025
17:42:36 +0000 x86_64
compiler info: gnuc: 15.2
libc info: glibc: 2.42
$SHELL (typically, interactive shell): /usr/bin/zsh


[Enabled Hooks]


--
Lauri Niskanen

^ permalink raw reply	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2025-09-23  0:48 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-19 10:18 [BUG] git stash show -p with invalid option aborts with double-free in show_stash() (strvec_clear) Lauri Niskanen
2025-09-19 13:11 ` Kristoffer Haugsbakk
2025-09-19 16:00   ` Junio C Hamano
2025-09-19 16:48     ` Jeff King
2025-09-19 17:13       ` Junio C Hamano
2025-09-19 16:58     ` Junio C Hamano
2025-09-19 17:20       ` Jeff King
2025-09-19 18:15         ` Junio C Hamano
2025-09-19 19:56           ` Jeff King
2025-09-19 22:33             ` [PATCH 0/6] fixing double-frees and leaks via setup_revisions() Jeff King
2025-09-19 22:40               ` [PATCH 1/6] stash: tell setup_revisions() to free our allocated strings Jeff King
2025-09-22 15:45                 ` Junio C Hamano
2025-09-22 19:05                   ` Jeff King
2025-09-22 19:36                     ` Junio C Hamano
2025-09-22 20:25                       ` Jeff King
2025-09-22 21:26                         ` Junio C Hamano
2025-09-23  0:48                           ` Jeff King
2025-09-19 22:45               ` [PATCH 2/6] revision: manage memory ownership of argv in setup_revisions() Jeff King
2025-09-19 22:48               ` [PATCH 3/6] revision: add wrapper to setup_revisions() from a strvec Jeff King
2025-09-20  5:10                 ` Eric Sunshine
2025-09-20  5:48                   ` Jeff King
2025-09-19 22:49               ` [PATCH 4/6] treewide: use setup_revisions_from_strvec() when we have " Jeff King
2025-09-19 22:50               ` [PATCH 5/6] treewide: pass strvecs around for setup_revisions_from_strvec() Jeff King
2025-09-19 23:11                 ` Jeff King
2025-09-19 22:51               ` [PATCH 6/6] revision: retain argv NULL invariant in setup_revisions() Jeff King
2025-09-19 23:07                 ` Jeff King

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).