diff options
author | Alexandr Miloslavskiy <alexandr.miloslavskiy@syntevo.com> | 2020-03-06 19:03:13 +0000 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2020-03-06 14:45:51 -0800 |
commit | 0915a5b4cdf00a8c6c755b77b854725a183993b4 (patch) | |
tree | 9614e0bd72e228432eeb16a1c7219deb0061e3ed /environment.c | |
parent | 076cbdcd739aeb33c1be87b73aebae5e43d7bcc5 (diff) | |
download | git-0915a5b4cdf00a8c6c755b77b854725a183993b4.tar.gz |
set_git_dir: fix crash when used with real_path()
`real_path()` returns result from a shared buffer, inviting subtle
reentrance bugs. One of these bugs occur when invoked this way:
set_git_dir(real_path(git_dir))
In this case, `real_path()` has reentrance:
real_path
read_gitfile_gently
repo_set_gitdir
setup_git_env
set_git_dir_1
set_git_dir
Later, `set_git_dir()` uses its now-dead parameter:
!is_absolute_path(path)
Fix this by using a dedicated `strbuf` to hold `strbuf_realpath()`.
Signed-off-by: Alexandr Miloslavskiy <alexandr.miloslavskiy@syntevo.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'environment.c')
-rw-r--r-- | environment.c | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/environment.c b/environment.c index e72a02d0d5..c436de31ee 100644 --- a/environment.c +++ b/environment.c @@ -345,11 +345,20 @@ static void update_relative_gitdir(const char *name, free(path); } -void set_git_dir(const char *path) +void set_git_dir(const char *path, int make_realpath) { + struct strbuf realpath = STRBUF_INIT; + + if (make_realpath) { + strbuf_realpath(&realpath, path, 1); + path = realpath.buf; + } + set_git_dir_1(path); if (!is_absolute_path(path)) chdir_notify_register(NULL, update_relative_gitdir, NULL); + + strbuf_release(&realpath); } const char *get_log_output_encoding(void) |