All of lore.kernel.org
 help / color / mirror / Atom feed
From: Patrick Steinhardt <ps@pks.im>
To: git@vger.kernel.org
Cc: Junio C Hamano <gitster@pobox.com>
Subject: [PATCH v2 00/20] Memory leak fixes (pt.5)
Date: Thu, 22 Aug 2024 11:17:08 +0200	[thread overview]
Message-ID: <cover.1724315484.git.ps@pks.im> (raw)
In-Reply-To: <cover.1724159575.git.ps@pks.im>

Hi,

this is version 2 of this patch series that fixes another set of memory
leaks.

Changes compared to v1:

  - Remove spaces between cast and variable.

  - Clarify why we move the `ctx.entries_nr` block.

  - Adapt sideband colors to use `git_config_get_string_tmp()` such that
    we do not have to allocate the strings in the first place.

  - Fix more memory leaks for config values in the remote state.

  - Refactor `unbundle()` to not free extra args passed by the caller
    anymore. Instead, this is now always done by the caler.

Thanks!

Patrick

Patrick Steinhardt (20):
  mailinfo: fix leaking header data
  convert: fix leaks when resetting attributes
  pretty: fix memory leaks when parsing pretty formats
  pretty: fix leaking key/value separator buffer
  builtin/merge-tree: fix leaking `-X` strategy options
  builtin/upload-archive: fix leaking args passed to `write_archive()`
  builtin/archive: fix leaking `OPT_FILENAME()` value
  midx-write: fix leaking hashfile on error cases
  builtin/repack: fix leaks when computing packs to repack
  t/helper: fix leaking multi-pack-indices in "read-midx"
  transport: fix leaking OID arrays in git:// transport data
  builtin/send-pack: fix leaking refspecs
  sideband: fix leaks when configuring sideband colors
  builtin/fetch-pack: fix leaking refs
  remote: fix leaking config strings
  remote: fix leaks when matching refspecs
  remote: fix leaking peer ref when expanding refmap
  builtin/fetch: fix leaking transaction with `--atomic`
  transport: fix leaking arguments when fetching from bundle
  transport: fix leaking negotiation tips

 archive.c                           | 10 ++++
 builtin/archive.c                   |  7 ++-
 builtin/bundle.c                    |  2 +
 builtin/fetch-pack.c                | 20 ++++---
 builtin/fetch.c                     |  8 +--
 builtin/merge-tree.c                | 13 ++++-
 builtin/repack.c                    | 36 +++++++++---
 builtin/send-pack.c                 |  1 +
 builtin/upload-archive.c            |  8 ++-
 bundle.c                            |  4 +-
 convert.c                           |  3 +
 mailinfo.c                          | 17 +++++-
 midx-write.c                        | 24 ++++----
 pretty.c                            | 13 ++++-
 remote.c                            | 85 +++++++++++++++++++++++------
 sideband.c                          | 15 +++--
 t/helper/test-read-midx.c           |  8 ++-
 t/t4150-am.sh                       |  1 +
 t/t4205-log-pretty-formats.sh       |  2 +
 t/t4301-merge-tree-write-tree.sh    |  1 +
 t/t5000-tar-tree.sh                 |  1 +
 t/t5003-archive-zip.sh              |  1 +
 t/t5100-mailinfo.sh                 |  1 +
 t/t5319-multi-pack-index.sh         |  2 +
 t/t5400-send-pack.sh                |  1 +
 t/t5401-update-hooks.sh             |  2 +
 t/t5408-send-pack-stdin.sh          |  2 +
 t/t5409-colorize-remote-messages.sh |  1 +
 t/t5501-fetch-push-alternates.sh    |  1 +
 t/t5505-remote.sh                   |  1 +
 t/t5510-fetch.sh                    |  1 +
 t/t5519-push-alternates.sh          |  1 +
 t/t5536-fetch-conflicts.sh          |  1 +
 t/t5548-push-porcelain.sh           |  1 +
 t/t5553-set-upstream.sh             |  1 +
 t/t5574-fetch-output.sh             |  1 +
 t/t5703-upload-pack-ref-in-want.sh  |  1 +
 t/t5812-proto-disable-http.sh       |  2 +
 t/t6050-replace.sh                  |  1 +
 t/t7704-repack-cruft.sh             |  1 +
 transport.c                         |  8 +++
 41 files changed, 237 insertions(+), 73 deletions(-)

Range-diff against v1:
 1:  69e30ea5179 =  1:  69e30ea5179 mailinfo: fix leaking header data
 2:  ed0f01bf92c =  2:  ed0f01bf92c convert: fix leaks when resetting attributes
 3:  82f3908f962 !  3:  8a1963685e7 pretty: fix memory leaks when parsing pretty formats
    @@ pretty.c: static int git_pretty_formats_config(const char *var, const char *valu
      		commit_formats_len++;
      	}
      
    -+	free((char *) commit_format->name);
    ++	free((char *)commit_format->name);
      	commit_format->name = xstrdup(name);
      	commit_format->format = CMIT_FMT_USERFORMAT;
      	if (git_config_string(&fmt, var, value))
      		return -1;
      
     -	if (skip_prefix(fmt, "format:", &commit_format->user_format)) {
    -+	free((char *) commit_format->user_format);
    ++	free((char *)commit_format->user_format);
     +	if (skip_prefix(fmt, "format:", &stripped)) {
      		commit_format->is_tformat = 0;
     -	} else if (skip_prefix(fmt, "tformat:", &commit_format->user_format)) {
 4:  696467780e6 =  4:  1c368a4489a pretty: fix leaking key/value separator buffer
 5:  53db2fc7206 =  5:  c62c5e9604e builtin/merge-tree: fix leaking `-X` strategy options
 6:  5b05a325218 =  6:  afdd7f90b13 builtin/upload-archive: fix leaking args passed to `write_archive()`
 7:  bad575df126 =  7:  38487f3f65b builtin/archive: fix leaking `OPT_FILENAME()` value
 8:  5f042ce5098 !  8:  693c93ddbf7 midx-write: fix leaking hashfile on error cases
    @@ Commit message
         hashfile and finalizing it anymore this is sufficient to fix the memory
         leak.
     
    +    While at it, also move around the block checking for `ctx.entries_nr`.
    +    This change is not required to fix the memory leak, but it feels natural
    +    to move together all massaging of parameters before we go with them and
    +    execute the actual logic.
    +
         Signed-off-by: Patrick Steinhardt <ps@pks.im>
     
      ## midx-write.c ##
 9:  5c820da9761 =  9:  6bca72e5c57 builtin/repack: fix leaks when computing packs to repack
10:  9caf5eeea93 = 10:  48b60279d18 t/helper: fix leaking multi-pack-indices in "read-midx"
11:  8e12c55536d = 11:  0cb440ef648 transport: fix leaking OID arrays in git:// transport data
12:  5d8e0a3d8b4 = 12:  f4300c9326b builtin/send-pack: fix leaking refspecs
13:  5d09959b642 ! 13:  28805c15a42 sideband: fix leaks when configuring sideband colors
    @@ Commit message
     
         We read a bunch of configs in `use_sideband_colors()` to configure the
         colors that Git should use. We never free the strings read from the
    -    config though, causing memory leaks. Fix those.
    +    config though, causing memory leaks.
    +
    +    Refactor the code to use `git_config_get_string_tmp()` instead, which
    +    does not allocate memory. As we throw the strings away after parsing
    +    them anyway there is no need to use allocated strings.
     
         Signed-off-by: Patrick Steinhardt <ps@pks.im>
     
    @@ sideband.c: static int use_sideband_colors(void)
      	const char *key = "color.remote";
      	struct strbuf sb = STRBUF_INIT;
     -	char *value;
    -+	char *value = NULL;
    ++	const char *value;
      	int i;
      
      	if (use_sideband_colors_cached >= 0)
    -@@ sideband.c: static int use_sideband_colors(void)
    - 	} else {
    + 		return use_sideband_colors_cached;
    + 
    +-	if (!git_config_get_string(key, &value)) {
    ++	if (!git_config_get_string_tmp(key, &value))
    + 		use_sideband_colors_cached = git_config_colorbool(key, value);
    +-	} else if (!git_config_get_string("color.ui", &value)) {
    ++	else if (!git_config_get_string_tmp("color.ui", &value))
    + 		use_sideband_colors_cached = git_config_colorbool("color.ui", value);
    +-	} else {
    ++	else
      		use_sideband_colors_cached = GIT_COLOR_AUTO;
    - 	}
    -+	FREE_AND_NULL(value);
    +-	}
      
      	for (i = 0; i < ARRAY_SIZE(keywords); i++) {
      		strbuf_reset(&sb);
      		strbuf_addf(&sb, "%s.%s", key, keywords[i].keyword);
    - 		if (git_config_get_string(sb.buf, &value))
    - 			continue;
    --		if (color_parse(value, keywords[i].color))
    +-		if (git_config_get_string(sb.buf, &value))
     -			continue;
    +-		if (color_parse(value, keywords[i].color))
    ++		if (git_config_get_string_tmp(sb.buf, &value))
    + 			continue;
     +		color_parse(value, keywords[i].color);
    -+		FREE_AND_NULL(value);
      	}
     +
      	strbuf_release(&sb);
14:  1c94195488d = 14:  aac84c5a2b7 builtin/fetch-pack: fix leaking refs
15:  97346d6f944 ! 15:  532328b7814 remote: fix leaking config strings
    @@ Commit message
         We're leaking several config strings when assembling remotes, either
         because we do not free preceding values in case a config was set
         multiple times, or because we do not free them when releasing the remote
    -    state. Plug those leaks.
    +    state. This includes config strings for "branch" sections, "insteadOf",
    +    "pushInsteadOf", and "pushDefault".
    +
    +    Plug those leaks.
     
         Signed-off-by: Patrick Steinhardt <ps@pks.im>
     
      ## remote.c ##
    +@@ remote.c: static struct branch *make_branch(struct remote_state *remote_state,
    + 	return ret;
    + }
    + 
    ++static void branch_release(struct branch *branch)
    ++{
    ++	free((char *)branch->name);
    ++	free((char *)branch->refname);
    ++	free(branch->remote_name);
    ++	free(branch->pushremote_name);
    ++	for (int i = 0; i < branch->merge_nr; i++)
    ++		refspec_item_clear(branch->merge[i]);
    ++	free(branch->merge);
    ++}
    ++
    + static struct rewrite *make_rewrite(struct rewrites *r,
    + 				    const char *base, size_t len)
    + {
    +@@ remote.c: static struct rewrite *make_rewrite(struct rewrites *r,
    + 	return ret;
    + }
    + 
    ++static void rewrites_release(struct rewrites *r)
    ++{
    ++	for (int i = 0; i < r->rewrite_nr; i++)
    ++		free((char *)r->rewrite[i]->base);
    ++	free(r->rewrite);
    ++	memset(r, 0, sizeof(*r));
    ++}
    ++
    + static void add_instead_of(struct rewrite *rewrite, const char *instead_of)
    + {
    + 	ALLOC_GROW(rewrite->instead_of, rewrite->instead_of_nr + 1, rewrite->instead_of_alloc);
     @@ remote.c: static int handle_config(const char *key, const char *value,
      			return -1;
      		branch = make_branch(remote_state, name, namelen);
    @@ remote.c: static int handle_config(const char *key, const char *value,
      		return git_config_string(&remote->foreign_vcs, key, value);
      	}
      	return 0;
    -@@ remote.c: void remote_state_clear(struct remote_state *remote_state)
    +@@ remote.c: struct remote_state *remote_state_new(void)
    + 
    + void remote_state_clear(struct remote_state *remote_state)
    + {
    ++	struct hashmap_iter iter;
    ++	struct branch *b;
    + 	int i;
    + 
      	for (i = 0; i < remote_state->remotes_nr; i++)
      		remote_clear(remote_state->remotes[i]);
      	FREE_AND_NULL(remote_state->remotes);
    @@ remote.c: void remote_state_clear(struct remote_state *remote_state)
      	remote_state->remotes_alloc = 0;
      	remote_state->remotes_nr = 0;
      
    ++	rewrites_release(&remote_state->rewrites);
    ++	rewrites_release(&remote_state->rewrites_push);
    ++
    + 	hashmap_clear_and_free(&remote_state->remotes_hash, struct remote, ent);
    +-	hashmap_clear_and_free(&remote_state->branches_hash, struct remote, ent);
    ++	hashmap_for_each_entry(&remote_state->branches_hash, &iter, b, ent) {
    ++		branch_release(b);
    ++		free(b);
    ++	}
    ++	hashmap_clear(&remote_state->branches_hash);
    + }
    + 
    + /*
16:  e1d0be37636 = 16:  440b3d99372 remote: fix leaks when matching refspecs
17:  773fe580d75 = 17:  662ec4e6484 remote: fix leaking peer ref when expanding refmap
18:  9ede792550e = 18:  dbd8eaa2cb1 builtin/fetch: fix leaking transaction with `--atomic`
19:  b72f7d1ee39 ! 19:  4c5740afe43 transport: fix leaking arguments when fetching from bundle
    @@ Commit message
         transport: fix leaking arguments when fetching from bundle
     
         In `fetch_refs_from_bundle()` we assemble a vector of arguments to pass
    -    to `unbundle()`, but never free it. Fix this leak.
    +    to `unbundle()`, but never free it. And in theory we wouldn't have to
    +    because `unbundle()` already knows to free the vector for us. But it
    +    fails to do so when it exits early due to `verify_bundle()` failing.
    +
    +    The calling convention that the arguments are freed by the callee and
    +    not the caller feels somewhat weird. Refactor the code such that it is
    +    instead the responsibility of the caller to free the vector, adapting
    +    the only two callsites where we pass extra arguments. This also fixes
    +    the memory leak.
     
         This memory leak gets hit in t5510, but fixing it isn't sufficient to
         make the whole test suite pass.
     
         Signed-off-by: Patrick Steinhardt <ps@pks.im>
     
    + ## builtin/bundle.c ##
    +@@ builtin/bundle.c: static int cmd_bundle_unbundle(int argc, const char **argv, const char *prefix)
    + 			 &extra_index_pack_args, 0) ||
    + 		list_bundle_refs(&header, argc, argv);
    + 	bundle_header_release(&header);
    ++
    + cleanup:
    ++	strvec_clear(&extra_index_pack_args);
    + 	free(bundle_file);
    + 	return ret;
    + }
    +
    + ## bundle.c ##
    +@@ bundle.c: int unbundle(struct repository *r, struct bundle_header *header,
    + 	if (flags & VERIFY_BUNDLE_FSCK)
    + 		strvec_push(&ip.args, "--fsck-objects");
    + 
    +-	if (extra_index_pack_args) {
    ++	if (extra_index_pack_args)
    + 		strvec_pushv(&ip.args, extra_index_pack_args->v);
    +-		strvec_clear(extra_index_pack_args);
    +-	}
    + 
    + 	ip.in = bundle_fd;
    + 	ip.no_stdout = 1;
    +
      ## transport.c ##
     @@ transport.c: static int fetch_refs_from_bundle(struct transport *transport,
      		       &extra_index_pack_args,
20:  e8f479deeb2 = 20:  c3d2b035761 transport: fix leaking negotiation tips
-- 
2.46.0.164.g477ce5ccd6.dirty


  parent reply	other threads:[~2024-08-22  9:17 UTC|newest]

Thread overview: 60+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-08-20 14:04 [PATCH 00/20] Memory leak fixes (pt.5) Patrick Steinhardt
2024-08-20 14:05 ` [PATCH 01/20] mailinfo: fix leaking header data Patrick Steinhardt
2024-08-20 19:25   ` Junio C Hamano
2024-08-20 14:05 ` [PATCH 02/20] convert: fix leaks when resetting attributes Patrick Steinhardt
2024-08-20 19:51   ` Junio C Hamano
2024-08-20 14:05 ` [PATCH 03/20] pretty: fix memory leaks when parsing pretty formats Patrick Steinhardt
2024-08-20 20:36   ` Junio C Hamano
2024-08-22  8:19     ` Patrick Steinhardt
2024-08-20 14:05 ` [PATCH 04/20] pretty: fix leaking key/value separator buffer Patrick Steinhardt
2024-08-20 14:05 ` [PATCH 05/20] builtin/merge-tree: fix leaking `-X` strategy options Patrick Steinhardt
2024-08-20 22:10   ` Junio C Hamano
2024-08-20 14:05 ` [PATCH 06/20] builtin/upload-archive: fix leaking args passed to `write_archive()` Patrick Steinhardt
2024-08-20 14:05 ` [PATCH 07/20] builtin/archive: fix leaking `OPT_FILENAME()` value Patrick Steinhardt
2024-08-20 14:05 ` [PATCH 08/20] midx-write: fix leaking hashfile on error cases Patrick Steinhardt
2024-08-20 23:19   ` Junio C Hamano
2024-08-22  8:19     ` Patrick Steinhardt
2024-08-20 14:05 ` [PATCH 09/20] builtin/repack: fix leaks when computing packs to repack Patrick Steinhardt
2024-08-20 14:05 ` [PATCH 10/20] t/helper: fix leaking multi-pack-indices in "read-midx" Patrick Steinhardt
2024-08-20 14:05 ` [PATCH 11/20] transport: fix leaking OID arrays in git:// transport data Patrick Steinhardt
2024-08-20 14:05 ` [PATCH 12/20] builtin/send-pack: fix leaking refspecs Patrick Steinhardt
2024-08-20 14:05 ` [PATCH 13/20] sideband: fix leaks when configuring sideband colors Patrick Steinhardt
2024-08-20 23:52   ` Junio C Hamano
2024-08-22  8:19     ` Patrick Steinhardt
2024-08-20 14:05 ` [PATCH 14/20] builtin/fetch-pack: fix leaking refs Patrick Steinhardt
2024-08-21 17:46   ` Junio C Hamano
2024-08-20 14:05 ` [PATCH 15/20] remote: fix leaking config strings Patrick Steinhardt
2024-08-21 17:58   ` Junio C Hamano
2024-08-22  8:19     ` Patrick Steinhardt
2024-08-22 16:04       ` Junio C Hamano
2024-08-20 14:05 ` [PATCH 16/20] remote: fix leaks when matching refspecs Patrick Steinhardt
2024-08-20 14:05 ` [PATCH 17/20] remote: fix leaking peer ref when expanding refmap Patrick Steinhardt
2024-08-20 14:05 ` [PATCH 18/20] builtin/fetch: fix leaking transaction with `--atomic` Patrick Steinhardt
2024-08-20 14:05 ` [PATCH 19/20] transport: fix leaking arguments when fetching from bundle Patrick Steinhardt
2024-08-21 18:07   ` Junio C Hamano
2024-08-22  8:19     ` Patrick Steinhardt
2024-08-22 16:06       ` Junio C Hamano
2024-08-20 14:06 ` [PATCH 20/20] transport: fix leaking negotiation tips Patrick Steinhardt
2024-08-22  9:17 ` Patrick Steinhardt [this message]
2024-08-22  9:17   ` [PATCH v2 01/20] mailinfo: fix leaking header data Patrick Steinhardt
2024-08-22  9:17   ` [PATCH v2 02/20] convert: fix leaks when resetting attributes Patrick Steinhardt
2024-08-22  9:17   ` [PATCH v2 03/20] pretty: fix memory leaks when parsing pretty formats Patrick Steinhardt
2024-08-22  9:17   ` [PATCH v2 04/20] pretty: fix leaking key/value separator buffer Patrick Steinhardt
2024-08-22  9:17   ` [PATCH v2 05/20] builtin/merge-tree: fix leaking `-X` strategy options Patrick Steinhardt
2024-08-22  9:17   ` [PATCH v2 06/20] builtin/upload-archive: fix leaking args passed to `write_archive()` Patrick Steinhardt
2024-08-22  9:17   ` [PATCH v2 07/20] builtin/archive: fix leaking `OPT_FILENAME()` value Patrick Steinhardt
2024-08-22  9:17   ` [PATCH v2 08/20] midx-write: fix leaking hashfile on error cases Patrick Steinhardt
2024-08-22  9:17   ` [PATCH v2 09/20] builtin/repack: fix leaks when computing packs to repack Patrick Steinhardt
2024-08-22  9:17   ` [PATCH v2 10/20] t/helper: fix leaking multi-pack-indices in "read-midx" Patrick Steinhardt
2024-08-22  9:17   ` [PATCH v2 11/20] transport: fix leaking OID arrays in git:// transport data Patrick Steinhardt
2024-08-22  9:17   ` [PATCH v2 12/20] builtin/send-pack: fix leaking refspecs Patrick Steinhardt
2024-08-22  9:17   ` [PATCH v2 13/20] sideband: fix leaks when configuring sideband colors Patrick Steinhardt
2024-08-22  9:17   ` [PATCH v2 14/20] builtin/fetch-pack: fix leaking refs Patrick Steinhardt
2024-08-22  9:17   ` [PATCH v2 15/20] remote: fix leaking config strings Patrick Steinhardt
2024-08-22  9:17   ` [PATCH v2 16/20] remote: fix leaks when matching refspecs Patrick Steinhardt
2024-08-22  9:18   ` [PATCH v2 17/20] remote: fix leaking peer ref when expanding refmap Patrick Steinhardt
2024-08-22  9:18   ` [PATCH v2 18/20] builtin/fetch: fix leaking transaction with `--atomic` Patrick Steinhardt
2024-08-22  9:18   ` [PATCH v2 19/20] transport: fix leaking arguments when fetching from bundle Patrick Steinhardt
2024-08-22 18:21     ` Junio C Hamano
2024-08-22  9:18   ` [PATCH v2 20/20] transport: fix leaking negotiation tips Patrick Steinhardt
2024-08-22 19:01   ` [PATCH v2 00/20] Memory leak fixes (pt.5) 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=cover.1724315484.git.ps@pks.im \
    --to=ps@pks.im \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.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 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.