git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "René Scharfe" <l.s.r@web.de>
To: Elijah Newren <newren@gmail.com>
Cc: Git Mailing List <git@vger.kernel.org>, Andrzej Hunt <andrzej@ahunt.org>
Subject: Re: [PATCH 02/12] environment: move strbuf into block to plug leak
Date: Sat, 26 Jun 2021 10:27:42 +0200	[thread overview]
Message-ID: <15df4c07-988e-baff-8760-a199ec9aeb1b@web.de> (raw)
In-Reply-To: <CABPp-BGFH787gsw-yd3BpLt_rDe2zDoSFP6mMx6PSQfy1Ct4vw@mail.gmail.com>

Am 21.06.21 um 22:49 schrieb Elijah Newren:
> On Sun, Jun 20, 2021 at 8:14 AM <andrzej@ahunt.org> wrote:
>> It looks like this leak has existed since realpath was first added to
>> set_git_work_tree() in:
>>   3d7747e318 (real_path: remove unsafe API, 2020-03-10)
>
> Looking at that commit, it appears to have introduced other problems.
> For example, the documentation for read_gitfile_gently() claims it
> returns a value from a shared buffer, but that commit got rid of the
> shared buffer so the documentation is no longer accurate.  The thing
> that is returned is either the path that was passed in, or some newly
> allocated path that differs, in which case the caller would be
> responsible to free() it, but it looks like the callers aren't doing
> so.

That comment is still correct.  The returned pointer references a shared
static buffer declared in read_gitfile_gently().  The control flow is a
bit hard to follow; path points to the static buffer if and only if
error_code is zero.  Using a dedicated variable for the result would
make that clearer, I think:

diff --git a/setup.c b/setup.c
index ead2f80cd8..75b0a4bea6 100644
--- a/setup.c
+++ b/setup.c
@@ -720,86 +720,87 @@ void read_gitfile_error_die(int error_code, const char *path, const char *dir)
 /*
  * Try to read the location of the git directory from the .git file,
  * return path to git directory if found. The return value comes from
  * a shared buffer.
  *
  * On failure, if return_error_code is not NULL, return_error_code
  * will be set to an error code and NULL will be returned. If
  * return_error_code is NULL the function will die instead (for most
  * cases).
  */
 const char *read_gitfile_gently(const char *path, int *return_error_code)
 {
 	const int max_file_size = 1 << 20;  /* 1MB */
 	int error_code = 0;
 	char *buf = NULL;
 	char *dir = NULL;
 	const char *slash;
 	struct stat st;
 	int fd;
 	ssize_t len;
 	static struct strbuf realpath = STRBUF_INIT;
+	const char *result = NULL;

 	if (stat(path, &st)) {
 		/* NEEDSWORK: discern between ENOENT vs other errors */
 		error_code = READ_GITFILE_ERR_STAT_FAILED;
 		goto cleanup_return;
 	}
 	if (!S_ISREG(st.st_mode)) {
 		error_code = READ_GITFILE_ERR_NOT_A_FILE;
 		goto cleanup_return;
 	}
 	if (st.st_size > max_file_size) {
 		error_code = READ_GITFILE_ERR_TOO_LARGE;
 		goto cleanup_return;
 	}
 	fd = open(path, O_RDONLY);
 	if (fd < 0) {
 		error_code = READ_GITFILE_ERR_OPEN_FAILED;
 		goto cleanup_return;
 	}
 	buf = xmallocz(st.st_size);
 	len = read_in_full(fd, buf, st.st_size);
 	close(fd);
 	if (len != st.st_size) {
 		error_code = READ_GITFILE_ERR_READ_FAILED;
 		goto cleanup_return;
 	}
 	if (!starts_with(buf, "gitdir: ")) {
 		error_code = READ_GITFILE_ERR_INVALID_FORMAT;
 		goto cleanup_return;
 	}
 	while (buf[len - 1] == '\n' || buf[len - 1] == '\r')
 		len--;
 	if (len < 9) {
 		error_code = READ_GITFILE_ERR_NO_PATH;
 		goto cleanup_return;
 	}
 	buf[len] = '\0';
 	dir = buf + 8;

 	if (!is_absolute_path(dir) && (slash = strrchr(path, '/'))) {
 		size_t pathlen = slash+1 - path;
 		dir = xstrfmt("%.*s%.*s", (int)pathlen, path,
 			      (int)(len - 8), buf + 8);
 		free(buf);
 		buf = dir;
 	}
 	if (!is_git_directory(dir)) {
 		error_code = READ_GITFILE_ERR_NOT_A_REPO;
 		goto cleanup_return;
 	}

 	strbuf_realpath(&realpath, dir, 1);
-	path = realpath.buf;
+	result = realpath.buf;

 cleanup_return:
 	if (return_error_code)
 		*return_error_code = error_code;
 	else if (error_code)
 		read_gitfile_error_die(error_code, path, dir);

 	free(buf);
-	return error_code ? NULL : path;
+	return result;
 }

 static const char *setup_explicit_git_dir(const char *gitdirenv,

  reply	other threads:[~2021-06-26  8:27 UTC|newest]

Thread overview: 51+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-20 15:11 [PATCH 00/12] Fix all leaks in tests t0002-t0099: Part 2 andrzej
2021-06-20 15:11 ` [PATCH 01/12] fmt-merge-msg: free newly allocated temporary strings when done andrzej
2021-06-21 20:34   ` Elijah Newren
2021-06-20 15:11 ` [PATCH 02/12] environment: move strbuf into block to plug leak andrzej
2021-06-21 20:49   ` Elijah Newren
2021-06-26  8:27     ` René Scharfe [this message]
2021-06-20 15:11 ` [PATCH 03/12] builtin/submodule--helper: release unused strbuf to avoid leak andrzej
2021-06-20 15:11 ` [PATCH 04/12] builtin/for-each-repo: remove unnecessary argv copy to plug leak andrzej
2021-06-21 20:55   ` Elijah Newren
2021-06-20 15:11 ` [PATCH 05/12] diffcore-rename: move old_dir/new_dir definition " andrzej
2021-06-21 14:01   ` Elijah Newren
2021-06-20 15:11 ` [PATCH 06/12] ref-filter: also free head for ATOM_HEAD to avoid leak andrzej
2021-06-21 21:10   ` Elijah Newren
2021-06-20 15:11 ` [PATCH 07/12] read-cache: call diff_setup_done " andrzej
2021-06-21 21:17   ` Elijah Newren
2021-06-20 15:12 ` [PATCH 08/12] convert: release strbuf " andrzej
2021-06-21 20:31   ` Elijah Newren
2021-06-20 15:12 ` [PATCH 09/12] builtin/mv: free or UNLEAK multiple pointers at end of cmd_mv andrzej
2021-06-20 15:12 ` [PATCH 10/12] builtin/merge: free found_ref when done andrzej
2021-06-21 21:27   ` Elijah Newren
2021-06-20 15:12 ` [PATCH 11/12] builtin/rebase: fix options.strategy memory lifecycle andrzej
2021-06-20 18:14   ` Phillip Wood
2021-06-21 21:39     ` Elijah Newren
2021-06-22  9:02       ` Phillip Wood
2021-07-25 13:03         ` Andrzej Hunt
2021-07-27 19:34           ` Phillip Wood
2021-06-20 15:12 ` [PATCH 12/12] reset: clear_unpack_trees_porcelain to plug leak andrzej
2021-06-21 21:44   ` Elijah Newren
2021-06-21 21:54 ` [PATCH 00/12] Fix all leaks in tests t0002-t0099: Part 2 Elijah Newren
2021-07-25 13:05   ` Andrzej Hunt
2021-07-26  8:01   ` Christian Couder
2021-07-25 13:08 ` [PATCH v2 " andrzej
2021-07-25 13:08   ` [PATCH v2 01/12] fmt-merge-msg: free newly allocated temporary strings when done andrzej
2021-07-26 19:20     ` Junio C Hamano
2021-07-25 13:08   ` [PATCH v2 02/12] environment: move strbuf into block to plug leak andrzej
2021-07-25 13:08   ` [PATCH v2 03/12] builtin/submodule--helper: release unused strbuf to avoid leak andrzej
2021-07-25 13:08   ` [PATCH v2 04/12] builtin/for-each-repo: remove unnecessary argv copy to plug leak andrzej
2021-07-26 20:02     ` Junio C Hamano
2021-07-25 13:08   ` [PATCH v2 05/12] diffcore-rename: move old_dir/new_dir definition " andrzej
2021-07-26 20:02     ` Junio C Hamano
2021-07-25 13:08   ` [PATCH v2 06/12] ref-filter: also free head for ATOM_HEAD to avoid leak andrzej
2021-07-26 20:04     ` Junio C Hamano
2021-07-25 13:08   ` [PATCH v2 07/12] read-cache: call diff_setup_done " andrzej
2021-07-26 20:10     ` Junio C Hamano
2021-07-25 13:08   ` [PATCH v2 08/12] convert: release strbuf " andrzej
2021-07-26 20:15     ` Junio C Hamano
2021-07-25 13:08   ` [PATCH v2 09/12] builtin/mv: free or UNLEAK multiple pointers at end of cmd_mv andrzej
2021-07-25 13:08   ` [PATCH v2 10/12] builtin/merge: free found_ref when done andrzej
2021-07-25 13:08   ` [PATCH v2 11/12] builtin/rebase: fix options.strategy memory lifecycle andrzej
2021-07-25 13:08   ` [PATCH v2 12/12] reset: clear_unpack_trees_porcelain to plug leak andrzej
2021-07-26 20:20   ` [PATCH v2 00/12] Fix all leaks in tests t0002-t0099: Part 2 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=15df4c07-988e-baff-8760-a199ec9aeb1b@web.de \
    --to=l.s.r@web.de \
    --cc=andrzej@ahunt.org \
    --cc=git@vger.kernel.org \
    --cc=newren@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).