All of lore.kernel.org
 help / color / mirror / Atom feed
From: Johannes Schindelin <Johannes.Schindelin@gmx.de>
To: Kaartic Sivaraam <kaartic.sivaraam@gmail.com>
Cc: Phillip Wood <phillip.wood@dunelm.org.uk>,
	Git Mailing List <git@vger.kernel.org>,
	Junio C Hamano <gitster@pobox.com>
Subject: Re: Error in `git': free(): invalid pointer (was Re: [PATCH] sequencer: improve config handling)
Date: Fri, 22 Dec 2017 12:49:19 +0100 (STD)	[thread overview]
Message-ID: <alpine.DEB.2.21.1.1712221201210.406@MININT-6BKU6QN.europe.corp.microsoft.com> (raw)
In-Reply-To: <1513874528.9646.2.camel@gmail.com>

Hi Kaartic,

On Thu, 21 Dec 2017, Kaartic Sivaraam wrote:

> Speaking of trace, (thanks to Dscho!) the one I got using 'valgrind'
> (with `--leak-check=full` option) can be found below. I've kept only
> relevant parts of it to avoid unwanted noise of `set -x`. Let me know
> if that's needed too.
> 
> ...
> 
> + git diff-files --quiet --ignore-submodules
> + git diff-index --cached --quiet --ignore-submodules HEAD --
> + test 0 = 1
> + test -z 1
> + valgrind --leak-check=full git rebase--helper --continue
> ==10384== Memcheck, a memory error detector
> ==10384== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
> ==10384== Using Valgrind-3.12.0.SVN and LibVEX; rerun with -h for copyright info
> ==10384== Command: git rebase--helper --continue
> ==10384== 
> ==10384== Invalid free() / delete / delete[] / realloc()
> ==10384==    at 0x4C2CDDB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
> ==10384==    by 0x24E3F8: read_populate_opts (sequencer.c:1964)
> ==10384==    by 0x24E3F8: sequencer_continue (sequencer.c:2753)
> ==10384==    by 0x1735DC: cmd_rebase__helper (rebase--helper.c:52)
> ==10384==    by 0x11B847: run_builtin (git.c:346)
> ==10384==    by 0x11B847: handle_builtin (git.c:554)
> ==10384==    by 0x11BB05: run_argv (git.c:606)
> ==10384==    by 0x11BB05: cmd_main (git.c:683)
> ==10384==    by 0x11AC0B: main (common-main.c:43)
> ==10384==  Address 0x2a898a is in a r-x mapped file /mnt/Source/Git/git-next/git segment
> ==10384== 
> Successfully rebased and updated refs/heads/public.
> ==10384== 
> ==10384== HEAP SUMMARY:
> ==10384==     in use at exit: 680,882 bytes in 332 blocks
> ==10384==   total heap usage: 717 allocs, 386 frees, 1,709,293 bytes allocated
> ==10384== 
> ==10384== 2,053 (2,048 direct, 5 indirect) bytes in 1 blocks are definitely lost in loss record 75 of 83
> ==10384==    at 0x4C2BADF: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
> ==10384==    by 0x4C2DE5F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
> ==10384==    by 0x27E0FE: xrealloc (wrapper.c:138)
> ==10384==    by 0x2072A3: add_object_array_with_path (object.c:319)
> ==10384==    by 0x23D745: add_pending_object_with_path (revision.c:163)
> ==10384==    by 0x24030E: add_pending_object_with_mode (revision.c:170)
> ==10384==    by 0x24030E: add_pending_object (revision.c:176)
> ==10384==    by 0x24030E: add_head_to_pending (revision.c:188)
> ==10384==    by 0x280EFA: has_uncommitted_changes.part.17 (wt-status.c:2288)
> ==10384==    by 0x24DF88: commit_staged_changes (sequencer.c:2705)
> ==10384==    by 0x24DF88: sequencer_continue (sequencer.c:2749)
> ==10384==    by 0x1735DC: cmd_rebase__helper (rebase--helper.c:52)
> ==10384==    by 0x11B847: run_builtin (git.c:346)
> ==10384==    by 0x11B847: handle_builtin (git.c:554)
> ==10384==    by 0x11BB05: run_argv (git.c:606)
> ==10384==    by 0x11BB05: cmd_main (git.c:683)
> ==10384==    by 0x11AC0B: main (common-main.c:43)
> ==10384== 
> ==10384== LEAK SUMMARY:
> ==10384==    definitely lost: 2,048 bytes in 1 blocks
> ==10384==    indirectly lost: 5 bytes in 1 blocks
> ==10384==      possibly lost: 0 bytes in 0 blocks
> ==10384==    still reachable: 678,829 bytes in 330 blocks
> ==10384==         suppressed: 0 bytes in 0 blocks
> ==10384== Reachable blocks (those to which a pointer was found) are not shown.
> ==10384== To see them, rerun with: --leak-check=full --show-leak-kinds=all
> ==10384== 
> ==10384== For counts of detected and suppressed errors, rerun with: -v
> ==10384== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
> + exit
> 
> 
> I think I didn't mention I've set `commit.gpgsign` to `true` for that
> repo, did I?

Hah! I had troubles to associate the correct line in my versions of Git's
source code (the line numbers alone are only reliable if you also have a
commit from which the Git binaries were built), but I did this free() at
(https://github.com/git/git/blob/cd54ea2b18/sequencer.c#L1975:

	if (read_oneliner(&buf, rebase_path_gpg_sign_opt(), 1)) {
		if (!starts_with(buf.buf, "-S"))
			strbuf_reset(&buf);
		else {
			free(opts->gpg_sign);
			^^^^^^^^^^^^^^^^^^^^^
			opts->gpg_sign = xstrdup(buf.buf + 2);
		}
		strbuf_reset(&buf);
	}

The culprit is that we have these really unclear ownership rules, where it
is not at all clear who is responsible for releasing allocated memory:
caller or callee? (Hannes would not rightfully point out that this would
be a non-issue if we would switch to C++). In C, the common pattern is to
use `const char *` for users that are *not* supposed to take ownership,
and `char *` for users that are supposed to take custody. And in this
instance, `gpg_sign` should be owned by `struct replay_opts` because of
this (https://github.com/git/git/blob/cd54ea2b18/sequencer.h#L38):

	char *gpg_sign;

Technically, using `char *` (instead of `const char *`) does not say
"you're now responsible for de-allocating this memory", of course, but in
practice it is often used like this (and the signature of `free(void *)`
certainly encourages that type of interpreting the `const` qualifier).

But. There is a problem when you set commit.gpgSign = true (see
https://github.com/git/git/blob/cd54ea2b18/sequencer.c#L162-L165):

	if (!strcmp(k, "commit.gpgsign")) {
		opts->gpg_sign = git_config_bool(k, v) ? "" : NULL;
		return 0;
	}

See how a "" is assigned to that field of type `char *`? It should not
even be possible, as the "" is implicitly read-only memory. And it
certainly was never malloc()ed.

So how to solve it? My suggestion would be to use xstrdup("") instead of
"" here.

I spent a little quality time with the code and came up with a patch that
I will send out in a moment.

By the way, Kaartic, thank you so much for focusing on correctness before
focusing on style issues. I know it is harder to review patches for
correctness than it is to concentrate on style issues, but in my mind it
is not only much more work, but also a lot more valuable.

Ciao,
Dscho

  reply	other threads:[~2017-12-22 11:49 UTC|newest]

Thread overview: 120+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-09-25 10:10 [RFC PATCH 0/8] sequencer: dont't fork git commit Phillip Wood
2017-09-25 10:10 ` [RFC PATCH 1/8] commit: move empty message checks to libgit Phillip Wood
2017-09-25 10:10 ` [RFC PATCH 2/8] commit: move code to update HEAD " Phillip Wood
2017-10-07  9:54   ` Junio C Hamano
2017-10-24 10:01     ` Phillip Wood
2017-10-24 12:41       ` Junio C Hamano
2017-09-25 10:10 ` [RFC PATCH 3/8] sequencer: refactor update_head() Phillip Wood
2017-09-25 10:10 ` [RFC PATCH 4/8] commit: move post-rewrite code to libgit Phillip Wood
2017-09-25 10:10 ` [RFC PATCH 5/8] commit: move print_commit_summary() " Phillip Wood
2017-09-25 10:10 ` [RFC PATCH 6/8] sequencer: simplify adding Signed-off-by: trailer Phillip Wood
2017-09-25 10:10 ` [RFC PATCH 7/8] sequencer: load commit related config Phillip Wood
2017-09-25 10:10 ` [RFC PATCH 8/8] sequencer: try to commit without forking 'git commit' Phillip Wood
2017-11-06 11:27 ` [PATCH v1 0/8] sequencer: dont't fork git commit Phillip Wood
2017-11-06 11:27   ` [PATCH v1 1/8] commit: move empty message checks to libgit Phillip Wood
2017-11-07  0:43     ` Johannes Schindelin
2017-11-07 14:24       ` Phillip Wood
2017-11-06 11:27   ` [PATCH v1 2/8] Add a function to update HEAD after creating a commit Phillip Wood
2017-11-07  2:56     ` Junio C Hamano
2017-11-07  3:02       ` Johannes Schindelin
2017-11-07 14:26         ` Phillip Wood
2017-11-06 11:27   ` [PATCH v1 3/8] commit: move post-rewrite code to libgit Phillip Wood
2017-11-07  3:03     ` Junio C Hamano
2017-11-07 14:28       ` Phillip Wood
2017-11-06 11:27   ` [PATCH v1 4/8] commit: move print_commit_summary() " Phillip Wood
2017-11-07  3:38     ` Junio C Hamano
2017-11-07 14:32       ` Phillip Wood
2017-11-08  1:04         ` Junio C Hamano
2017-11-06 11:27   ` [PATCH v1 5/8] sequencer: don't die in print_commit_summary() Phillip Wood
2017-11-07  4:18     ` Junio C Hamano
2017-11-07 10:24       ` Johannes Schindelin
2017-11-07 15:13       ` Junio C Hamano
2017-11-10 14:53         ` Phillip Wood
2017-11-10 18:05           ` Junio C Hamano
2017-11-13 11:11             ` Phillip Wood
2017-11-06 11:27   ` [PATCH v1 6/8] sequencer: simplify adding Signed-off-by: trailer Phillip Wood
2017-11-07  0:52     ` Johannes Schindelin
2017-11-07  4:52     ` Junio C Hamano
2017-11-07 14:46       ` Phillip Wood
2017-11-06 11:27   ` [PATCH v1 7/8] sequencer: load commit related config Phillip Wood
2017-11-07  1:02     ` Johannes Schindelin
2017-11-07 10:50       ` Phillip Wood
2017-11-06 11:27   ` [PATCH v1 8/8] sequencer: try to commit without forking 'git commit' Phillip Wood
2017-11-07  1:36     ` Johannes Schindelin
2017-11-07 11:16       ` Phillip Wood
2017-11-07 14:09         ` Johannes Schindelin
2017-11-10 11:09 ` [PATCH v2 0/9] sequencer: dont't fork git commit Phillip Wood
2017-11-10 11:09   ` [PATCH v2 1/9] t3404: check intermediate squash messages Phillip Wood
2017-11-10 11:09   ` [PATCH v2 2/9] commit: move empty message checks to libgit Phillip Wood
2017-11-10 18:51     ` Ramsay Jones
2017-11-13 11:08       ` Phillip Wood
2017-11-10 11:09   ` [PATCH v2 3/9] Add a function to update HEAD after creating a commit Phillip Wood
2017-11-10 18:36     ` Junio C Hamano
2017-11-13 11:25       ` Phillip Wood
2017-11-10 11:09   ` [PATCH v2 4/9] commit: move post-rewrite code to libgit Phillip Wood
2017-11-10 11:09   ` [PATCH v2 5/9] commit: move print_commit_summary() " Phillip Wood
2017-11-10 11:09   ` [PATCH v2 6/9] sequencer: don't die in print_commit_summary() Phillip Wood
2017-11-10 11:09   ` [PATCH v2 7/9] sequencer: simplify adding Signed-off-by: trailer Phillip Wood
2017-11-10 11:09   ` [PATCH v2 8/9] sequencer: load commit related config Phillip Wood
2017-11-10 11:09   ` [PATCH v2 9/9] sequencer: try to commit without forking 'git commit' Phillip Wood
2017-11-10 19:21   ` [PATCH v2 0/9] sequencer: dont't fork git commit Junio C Hamano
2017-11-13 11:24     ` Phillip Wood
2017-11-14  1:15       ` Junio C Hamano
2017-11-17 11:34 ` [PATCH v3 0/8] sequencer: don't " Phillip Wood
2017-11-17 11:34   ` [PATCH v3 1/8] t3404: check intermediate squash messages Phillip Wood
2017-11-17 11:34   ` [PATCH v3 2/8] commit: move empty message checks to libgit Phillip Wood
2017-11-17 11:34   ` [PATCH v3 3/8] Add a function to update HEAD after creating a commit Phillip Wood
2017-11-17 11:34   ` [PATCH v3 4/8] commit: move post-rewrite code to libgit Phillip Wood
2017-11-17 11:34   ` [PATCH v3 5/8] commit: move print_commit_summary() " Phillip Wood
2017-11-17 11:34   ` [PATCH v3 6/8] sequencer: simplify adding Signed-off-by: trailer Phillip Wood
2017-11-17 11:34   ` [PATCH v3 7/8] sequencer: load commit related config Phillip Wood
2017-11-17 11:34   ` [PATCH v3 8/8] sequencer: try to commit without forking 'git commit' Phillip Wood
2017-11-18  3:41   ` [PATCH v3 0/8] sequencer: don't fork git commit Junio C Hamano
2017-11-18  3:57     ` Junio C Hamano
2017-11-18 11:32       ` Phillip Wood
2017-11-18 14:33       ` Phillip Wood
2017-11-24 11:07 ` [PATCH v4 0/9] " Phillip Wood
2017-11-24 11:07   ` [PATCH v4 1/9] t3404: check intermediate squash messages Phillip Wood
2017-11-24 11:07   ` [PATCH v4 2/9] commit: move empty message checks to libgit Phillip Wood
2017-11-24 11:07   ` [PATCH v4 3/9] Add a function to update HEAD after creating a commit Phillip Wood
2017-11-24 11:07   ` [PATCH v4 4/9] commit: move post-rewrite code to libgit Phillip Wood
2017-11-24 11:07   ` [PATCH v4 5/9] commit: move print_commit_summary() " Phillip Wood
2017-11-24 11:07   ` [PATCH v4 6/9] sequencer: simplify adding Signed-off-by: trailer Phillip Wood
2017-11-24 11:07   ` [PATCH v4 7/9] sequencer: load commit related config Phillip Wood
2017-11-24 13:48     ` Junio C Hamano
2017-11-24 14:38       ` Phillip Wood
2017-12-04 18:30     ` Junio C Hamano
2017-12-05 11:21       ` Phillip Wood
2017-12-05 12:10         ` Phillip Wood
2017-12-09 19:05         ` Phillip Wood
2017-11-24 11:07   ` [PATCH v4 8/9] sequencer: try to commit without forking 'git commit' Phillip Wood
2017-11-24 11:07   ` [PATCH v4 9/9] t3512/t3513: remove KNOWN_FAILURE_CHERRY_PICK_SEES_EMPTY_COMMIT=1 Phillip Wood
2017-12-04 19:24     ` Stefan Beller
2017-12-05 12:13       ` Phillip Wood
2017-12-11 14:13 ` [PATCH v5 0/9] sequencer: don't fork git commit Phillip Wood
2017-12-11 14:13   ` [PATCH v5 1/9] t3404: check intermediate squash messages Phillip Wood
2017-12-11 14:13   ` [PATCH v5 2/9] commit: move empty message checks to libgit Phillip Wood
2017-12-11 14:13   ` [PATCH v5 3/9] Add a function to update HEAD after creating a commit Phillip Wood
2017-12-11 14:13   ` [PATCH v5 4/9] commit: move post-rewrite code to libgit Phillip Wood
2017-12-11 14:13   ` [PATCH v5 5/9] commit: move print_commit_summary() " Phillip Wood
2017-12-11 14:13   ` [PATCH v5 6/9] sequencer: simplify adding Signed-off-by: trailer Phillip Wood
2017-12-11 14:13   ` [PATCH v5 7/9] sequencer: load commit related config Phillip Wood
2017-12-11 18:53     ` Phillip Wood
2017-12-11 14:13   ` [PATCH v5 8/9] sequencer: try to commit without forking 'git commit' Phillip Wood
2018-01-10 20:53     ` Jonathan Nieder
2018-01-10 22:40       ` Johannes Schindelin
2018-01-11 10:41         ` Phillip Wood
2018-01-11 20:21           ` Johannes Schindelin
2017-12-11 14:13   ` [PATCH v5 9/9] t3512/t3513: remove KNOWN_FAILURE_CHERRY_PICK_SEES_EMPTY_COMMIT=1 Phillip Wood
2017-12-11 23:44   ` [PATCH v5 0/9] sequencer: don't fork git commit Junio C Hamano
2017-12-12 10:32     ` Phillip Wood
2017-12-13 11:46     ` [PATCH] sequencer: improve config handling Phillip Wood
2017-12-20 18:33       ` Error in `git': free(): invalid pointer (was Re: [PATCH] sequencer: improve config handling) Kaartic Sivaraam
2017-12-21 14:06         ` Johannes Schindelin
2017-12-21 16:42           ` Kaartic Sivaraam
2017-12-22 11:49             ` Johannes Schindelin [this message]
2017-12-25  8:51               ` Kaartic Sivaraam
     [not found]         ` <18737953.1042351513802399608.JavaMail.defaultUser@defaultHost>
2017-12-21 15:02           ` Kaartic Sivaraam
2017-12-21 16:53         ` phillip.wood
2017-12-21 17:14           ` Kaartic Sivaraam
2017-12-22 10:47             ` phillip.wood

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=alpine.DEB.2.21.1.1712221201210.406@MININT-6BKU6QN.europe.corp.microsoft.com \
    --to=johannes.schindelin@gmx.de \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=kaartic.sivaraam@gmail.com \
    --cc=phillip.wood@dunelm.org.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.