git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jeff King <peff@peff.net>
To: Andrzej Hunt via GitGitGadget <gitgitgadget@gmail.com>
Cc: git@vger.kernel.org, Andrzej Hunt <andrzej@ahunt.org>,
	Andrzej Hunt <ajrhunt@google.com>
Subject: Re: [PATCH 1/7] symbolic-ref: don't leak shortened refname in check_symref()
Date: Mon, 8 Mar 2021 14:01:32 -0500	[thread overview]
Message-ID: <YEZ0jLppB9wOg/af@coredump.intra.peff.net> (raw)
In-Reply-To: <ff0f7c167fa5b5da2d843fa03edb70907e6af763.1615228580.git.gitgitgadget@gmail.com>

On Mon, Mar 08, 2021 at 06:36:14PM +0000, Andrzej Hunt via GitGitGadget wrote:

> From: Andrzej Hunt <ajrhunt@google.com>
> 
> This leak has existed since:
> 9ab55daa55 (git symbolic-ref --delete $symref, 2012-10-21)
> 
> This leak was found when running t0001 with LSAN, see also LSAN output
> below:
> 
> Direct leak of 19 byte(s) in 1 object(s) allocated from:
>     #0 0x486514 in strdup /home/abuild/rpmbuild/BUILD/llvm-11.0.0.src/build/../projects/compiler-rt/lib/asan/asan_interceptors.cpp:452:3
>     #1 0x9ab048 in xstrdup /home/ahunt/oss-fuzz/git/wrapper.c:29:14
>     #2 0x8b452f in refs_shorten_unambiguous_ref /home/ahunt/oss-fuzz/git/refs.c
>     #3 0x8b47e8 in shorten_unambiguous_ref /home/ahunt/oss-fuzz/git/refs.c:1287:9
>     #4 0x679fce in check_symref /home/ahunt/oss-fuzz/git/builtin/symbolic-ref.c:28:14
>     #5 0x679ad8 in cmd_symbolic_ref /home/ahunt/oss-fuzz/git/builtin/symbolic-ref.c:70:9
>     #6 0x4cd60d in run_builtin /home/ahunt/oss-fuzz/git/git.c:453:11
>     #7 0x4cb2da in handle_builtin /home/ahunt/oss-fuzz/git/git.c:704:3
>     #8 0x4ccc37 in run_argv /home/ahunt/oss-fuzz/git/git.c:771:4
>     #9 0x4cac29 in cmd_main /home/ahunt/oss-fuzz/git/git.c:902:19
>     #10 0x69cc6e in main /home/ahunt/oss-fuzz/git/common-main.c:52:11
>     #11 0x7f98388a4349 in __libc_start_main (/lib64/libc.so.6+0x24349)

As a general template for fixing leaks, this information seems pretty
good. You might want to give a brief reason for why it's a leak (like
you do already in the second patch). Here it just would be something
like:

  shorten_unambiguous_ref() returns an allocated string. We have to
  track it separately from the const refname.

Or whatever. It doesn't need to be a novel, but just give an overview of
what's going that makes the diff obvious.

> diff --git a/builtin/symbolic-ref.c b/builtin/symbolic-ref.c
> index 80237f0df10f..8cf52599693a 100644
> --- a/builtin/symbolic-ref.c
> +++ b/builtin/symbolic-ref.c
> @@ -24,9 +24,15 @@ static int check_symref(const char *HEAD, int quiet, int shorten, int print)
>  			return 1;
>  	}
>  	if (print) {
> -		if (shorten)
> -			refname = shorten_unambiguous_ref(refname, 0);
> -		puts(refname);
> +		if (shorten) {
> +			const char *shortened_refname;
> +
> +			shortened_refname = shorten_unambiguous_ref(refname, 0);
> +			puts(shortened_refname);
> +			free((void *)shortened_refname);
> +		} else {
> +			puts(refname);
> +		}

If a variable is meant to take ownership of memory, our usual convention
is to not declare it as "const". And then you don't need to cast to pass
it to free().

There's also an idiom in Git's codebase when a const pointer may alias
unowned storage, or a buffer that needs to be freed. Something like:

  if (print) {
          char *to_free = NULL;
	  if (shorten)
	          refname = to_free = shorten_unambiguous_ref(refname, 0);
	  puts(refname);
	  free(to_free);
  }

That avoids duplicating the part of the code that handles the variable.
In this case it is only a single line, but IMHO it's still easier to
read, as it makes clear that we call puts() in either case.

-Peff

  reply	other threads:[~2021-03-08 19:02 UTC|newest]

Thread overview: 52+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-03-08 18:36 [PATCH 0/7] Fix all leaks in t0001 Andrzej Hunt via GitGitGadget
2021-03-08 18:36 ` [PATCH 1/7] symbolic-ref: don't leak shortened refname in check_symref() Andrzej Hunt via GitGitGadget
2021-03-08 19:01   ` Jeff King [this message]
2021-03-14 18:07     ` Andrzej Hunt
2021-03-08 18:36 ` [PATCH 2/7] reset: free instead of leaking unneeded ref Andrzej Hunt via GitGitGadget
2021-03-08 19:03   ` Jeff King
2021-03-08 18:36 ` [PATCH 3/7] clone: free or UNLEAK further pointers when finished Andrzej Hunt via GitGitGadget
2021-03-08 19:12   ` Jeff King
2021-03-14 16:56     ` Andrzej Hunt
2021-03-08 18:36 ` [PATCH 4/7] worktree: fix leak in dwim_branch() Andrzej Hunt via GitGitGadget
2021-03-08 19:16   ` Jeff King
2021-03-14 17:56     ` Andrzej Hunt
2021-03-08 18:36 ` [PATCH 5/7] init: remove git_init_db_config() while fixing leaks Andrzej Hunt via GitGitGadget
2021-03-08 19:29   ` Jeff King
2021-03-08 18:36 ` [PATCH 6/7] init-db: silence template_dir leak when converting to absolute path Andrzej Hunt via GitGitGadget
2021-03-08 19:30   ` Jeff King
2021-03-08 18:36 ` [PATCH 7/7] parse-options: don't leak alias help messages Andrzej Hunt via GitGitGadget
2021-03-08 19:46   ` Jeff King
2021-03-14 17:03     ` Andrzej Hunt
2021-03-08 18:55 ` [PATCH 0/7] Fix all leaks in t0001 Jeff King
2021-03-12 23:42   ` Junio C Hamano
2021-03-14 16:54   ` Andrzej Hunt
2021-03-15 16:23     ` Andrzej Hunt
2021-03-08 18:57 ` Junio C Hamano
2021-03-14 16:55   ` Andrzej Hunt
2021-03-14 18:47 ` [PATCH v2 0/9] " Andrzej Hunt via GitGitGadget
2021-03-14 18:47   ` [PATCH v2 1/9] symbolic-ref: don't leak shortened refname in check_symref() Andrzej Hunt via GitGitGadget
2021-03-14 18:47   ` [PATCH v2 2/9] reset: free instead of leaking unneeded ref Andrzej Hunt via GitGitGadget
2021-03-14 18:47   ` [PATCH v2 3/9] clone: free or UNLEAK further pointers when finished Andrzej Hunt via GitGitGadget
2021-03-14 18:47   ` [PATCH v2 4/9] worktree: fix leak in dwim_branch() Andrzej Hunt via GitGitGadget
2021-03-14 18:47   ` [PATCH v2 5/9] init: remove git_init_db_config() while fixing leaks Andrzej Hunt via GitGitGadget
2021-03-14 18:47   ` [PATCH v2 6/9] init-db: silence template_dir leak when converting to absolute path Andrzej Hunt via GitGitGadget
2021-03-14 18:47   ` [PATCH v2 7/9] parse-options: convert bitfield values to use binary shift Andrzej Hunt via GitGitGadget
2021-03-14 20:25     ` Martin Ågren
2021-03-14 22:57       ` Junio C Hamano
2021-03-15 16:20       ` Andrzej Hunt
2021-03-14 18:47   ` [PATCH v2 8/9] parse-options: don't leak alias help messages Andrzej Hunt via GitGitGadget
2021-03-14 19:48     ` Eric Sunshine
2021-03-15 16:20       ` Andrzej Hunt
2021-03-14 20:00     ` Andrzej Hunt
2021-03-14 18:47   ` [PATCH v2 9/9] transport: also free remote_refs in transport_disconnect() Andrzej Hunt via GitGitGadget
2021-03-21 16:58   ` [PATCH v3 0/9] Fix all leaks in t0001 Andrzej Hunt via GitGitGadget
2021-03-21 16:58     ` [PATCH v3 1/9] symbolic-ref: don't leak shortened refname in check_symref() Andrzej Hunt via GitGitGadget
2021-03-21 16:58     ` [PATCH v3 2/9] reset: free instead of leaking unneeded ref Andrzej Hunt via GitGitGadget
2021-03-21 16:58     ` [PATCH v3 3/9] clone: free or UNLEAK further pointers when finished Andrzej Hunt via GitGitGadget
2021-03-21 16:58     ` [PATCH v3 4/9] worktree: fix leak in dwim_branch() Andrzej Hunt via GitGitGadget
2021-03-21 16:58     ` [PATCH v3 5/9] init: remove git_init_db_config() while fixing leaks Andrzej Hunt via GitGitGadget
2021-03-21 16:58     ` [PATCH v3 6/9] init-db: silence template_dir leak when converting to absolute path Andrzej Hunt via GitGitGadget
2021-03-21 16:58     ` [PATCH v3 7/9] parse-options: convert bitfield values to use binary shift Andrzej Hunt via GitGitGadget
2021-03-21 16:58     ` [PATCH v3 8/9] parse-options: don't leak alias help messages Andrzej Hunt via GitGitGadget
2021-03-21 16:58     ` [PATCH v3 9/9] transport: also free remote_refs in transport_disconnect() Andrzej Hunt via GitGitGadget
2021-03-21 21:40     ` [PATCH v3 0/9] Fix all leaks in t0001 Junio C Hamano

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=YEZ0jLppB9wOg/af@coredump.intra.peff.net \
    --to=peff@peff.net \
    --cc=ajrhunt@google.com \
    --cc=andrzej@ahunt.org \
    --cc=git@vger.kernel.org \
    --cc=gitgitgadget@gmail.com \
    /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 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).