From: "Ævar Arnfjörð Bjarmason" <avarab@gmail.com>
To: git@vger.kernel.org
Cc: "Junio C Hamano" <gitster@pobox.com>,
"Andrzej Hunt" <andrzej@ahunt.org>,
"Martin Ågren" <martin.agren@gmail.com>,
"Ævar Arnfjörð Bjarmason" <avarab@gmail.com>
Subject: [PATCH v2 0/3] refs.c + config.c: plug memory leaks
Date: Thu, 21 Oct 2021 21:54:12 +0200 [thread overview]
Message-ID: <cover-v2-0.3-00000000000-20211021T195133Z-avarab@gmail.com> (raw)
In-Reply-To: <patch-1.1-5a47bf2e9c9-20211021T114223Z-avarab@gmail.com>
In response to the feedback on v1 on this (in particular the
use-after-free, thanks Martin!) here's a v2 which I think is a good
thing to do with our without that particular GCC behavior I ran into.
As noted in 3/3 I think this is a known caveat of those SANITIZE=
modes, e.g. valgrind reports a memory leak regardless of optimization
level.
The only pure workaround for the issue is now 3/3, which I think is a
worthwhile to carry to avoid developer potentially wasting time on it.
Ævar Arnfjörð Bjarmason (3):
refs.c: make "repo_default_branch_name" static, remove xstrfmt()
config.c: don't leak memory in handle_path_include()
config.c: free(expanded) before die(), work around GCC oddity
config.c | 22 ++++++++++++++--------
refs.c | 8 +++-----
refs.h | 1 -
t/t1305-config-include.sh | 1 +
4 files changed, 18 insertions(+), 14 deletions(-)
Range-diff against v1:
-: ----------- > 1: 4f8554bb02e refs.c: make "repo_default_branch_name" static, remove xstrfmt()
-: ----------- > 2: d6d04da1d9d config.c: don't leak memory in handle_path_include()
1: 5a47bf2e9c9 ! 3: d812358e331 leak tests: free() before die for two API functions
@@ Metadata
Author: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
## Commit message ##
- leak tests: free() before die for two API functions
+ config.c: free(expanded) before die(), work around GCC oddity
- Call free() just before die() in two API functions whose tests are
- asserted under SANITIZE=leak. Normally this would not be needed due to
- how SANITIZE=leak works, but in these cases my GCC version (10.2.1-6)
- will fail tests t0001 and t0017 under SANITIZE=leak depending on the
- optimization level.
+ On my GCC version (10.2.1-6), but not the clang I have available t0017
+ will fail under SANITIZE=leak on optimization levels higher than -O0,
+ which is annoying when combined with the change in 956d2e4639b (tests:
+ add a test mode for SANITIZE=leak, run it in CI, 2021-09-23).
- See 956d2e4639b (tests: add a test mode for SANITIZE=leak, run it in
- CI, 2021-09-23) for the commit that marked t0017 for testing with
- SANITIZE=leak, and c150064dbe2 (leak tests: run various built-in tests
- in t00*.sh SANITIZE=leak, 2021-10-12) for t0001 (currently in "next").
+ We really do have a memory leak here in either case, as e.g. running
+ the pre-image under valgrind(1) will reveal. It's documented
+ SANITIZE=leak (and "address", which exhibits the same behavior) might
+ interact with compiler optimization in this way in some cases, and
+ since this function is called recursively it's going to be especially
+ interesting as an optimization target.
+
+ Let's work around this issue by freeing the "expanded" memory before
+ we call die(), using the "goto cleanup" pattern introduced in the
+ preceding commit.
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
## config.c ##
+@@ config.c: static int handle_path_include(const char *path, struct config_include_data *inc
+ int ret = 0;
+ struct strbuf buf = STRBUF_INIT;
+ char *expanded;
++ int die_depth = 0;
+
+ if (!path)
+ return config_error_nonbool("include.path");
@@ config.c: static int handle_path_include(const char *path, struct config_include_data *inc
}
if (!access_or_die(path, R_OK, 0)) {
- if (++inc->depth > MAX_INCLUDE_DEPTH)
+- die(_(include_depth_advice), MAX_INCLUDE_DEPTH, path,
+- !cf ? "<unknown>" :
+- cf->name ? cf->name :
+- "the command line");
+ if (++inc->depth > MAX_INCLUDE_DEPTH) {
-+ free(expanded);
- die(_(include_depth_advice), MAX_INCLUDE_DEPTH, path,
- !cf ? "<unknown>" :
- cf->name ? cf->name :
- "the command line");
++ die_depth = 1;
++ goto cleanup;
+ }
ret = git_config_from_file(git_config_include, path, inc);
inc->depth--;
}
-
- ## refs.c ##
-@@ refs.c: char *repo_default_branch_name(struct repository *r, int quiet)
- }
-
- full_ref = xstrfmt("refs/heads/%s", ret);
-- if (check_refname_format(full_ref, 0))
-+ if (check_refname_format(full_ref, 0)) {
-+ free(ret);
-+ free(full_ref);
- die(_("invalid branch name: %s = %s"), config_display_key, ret);
-+ }
- free(full_ref);
+ cleanup:
+ strbuf_release(&buf);
+ free(expanded);
+- return ret;
++ if (!die_depth)
++ return ret;
++ die(_(include_depth_advice), MAX_INCLUDE_DEPTH, path,
++ !cf ? "<unknown>" : cf->name ? cf->name : "the command line");
+ }
- return ret;
+ static void add_trailing_starstar_for_dir(struct strbuf *pat)
--
2.33.1.1494.g88b39a443e1
next prev parent reply other threads:[~2021-10-21 19:54 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-10-21 11:42 [PATCH] leak tests: free() before die for two API functions Ævar Arnfjörð Bjarmason
2021-10-21 15:33 ` Andrzej Hunt
2021-10-21 18:51 ` Junio C Hamano
2021-10-21 16:13 ` Martin Ågren
2021-10-21 19:54 ` Ævar Arnfjörð Bjarmason [this message]
2021-10-21 19:54 ` [PATCH v2 1/3] refs.c: make "repo_default_branch_name" static, remove xstrfmt() Ævar Arnfjörð Bjarmason
2021-10-21 23:26 ` Junio C Hamano
2021-10-21 19:54 ` [PATCH v2 2/3] config.c: don't leak memory in handle_path_include() Ævar Arnfjörð Bjarmason
2021-10-21 23:30 ` Junio C Hamano
2021-10-22 17:19 ` Ævar Arnfjörð Bjarmason
2021-10-22 21:21 ` Junio C Hamano
2021-10-22 22:30 ` Ævar Arnfjörð Bjarmason
2021-10-21 19:54 ` [PATCH v2 3/3] config.c: free(expanded) before die(), work around GCC oddity Ævar Arnfjörð Bjarmason
2021-10-21 23:32 ` Junio C Hamano
2021-10-22 18:19 ` [PATCH v3 0/6] usage.c: add die_message() & plug memory leaks in refs.c & config.c Ævar Arnfjörð Bjarmason
2021-10-22 18:19 ` [PATCH v3 1/6] usage.c: add a die_message() routine Ævar Arnfjörð Bjarmason
2021-10-24 5:49 ` Junio C Hamano
2021-10-22 18:19 ` [PATCH v3 2/6] usage.c API users: use die_message() where appropriate Ævar Arnfjörð Bjarmason
2021-10-22 18:19 ` [PATCH v3 3/6] usage.c + gc: add and use a die_message_errno() Ævar Arnfjörð Bjarmason
2021-10-24 5:52 ` Junio C Hamano
2021-10-22 18:19 ` [PATCH v3 4/6] config.c: don't leak memory in handle_path_include() Ævar Arnfjörð Bjarmason
2021-10-24 5:53 ` Junio C Hamano
2021-10-22 18:19 ` [PATCH v3 5/6] config.c: free(expanded) before die(), work around GCC oddity Ævar Arnfjörð Bjarmason
2021-10-26 8:53 ` Jeff King
2021-10-22 18:19 ` [PATCH v3 6/6] refs: plug memory leak in repo_default_branch_name() Ævar Arnfjörð Bjarmason
2021-10-27 21:50 ` [PATCH v3 0/6] usage.c: add die_message() & plug memory leaks in refs.c & config.c Jonathan Tan
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
List information: http://vger.kernel.org/majordomo-info.html
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=cover-v2-0.3-00000000000-20211021T195133Z-avarab@gmail.com \
--to=avarab@gmail.com \
--cc=andrzej@ahunt.org \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=martin.agren@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.
Code repositories for project(s) associated with this public inbox
https://80x24.org/mirrors/git.git
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 read-only IMAP folder(s) and NNTP newsgroup(s).