summaryrefslogtreecommitdiff
path: root/git.c
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2016-01-26 22:50:27 -0800
committerJunio C Hamano <gitster@pobox.com>2016-01-27 15:19:03 -0800
commit2e1175d43d05e83fe836e1c8c8e7c25b7ee659ae (patch)
tree05ae2bd23b338bd8db109e77d600e46cce3068f9 /git.c
parent9d1d2b7fad9bec6320a2058c625787c835864960 (diff)
downloadgit-2e1175d43d05e83fe836e1c8c8e7c25b7ee659ae.tar.gz
git: protect against unbalanced calls to {save,restore}_env()
We made sure that save_env_before_alias() does not skip saving the environment when asked to (which led to use-after-free of orig_cwd in restore_env() in the buggy version) with the previous step. Protect against future breakage where somebody adds new callers of these functions in an unbalanced fashion. Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'git.c')
-rw-r--r--git.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/git.c b/git.c
index a57a4cb469..e39b972353 100644
--- a/git.c
+++ b/git.c
@@ -26,11 +26,15 @@ static const char *env_names[] = {
};
static char *orig_env[4];
static int saved_env_before_alias;
+static int save_restore_env_balance;
static void save_env_before_alias(void)
{
int i;
saved_env_before_alias = 1;
+
+ assert(save_restore_env_balance == 0);
+ save_restore_env_balance = 1;
orig_cwd = xgetcwd();
for (i = 0; i < ARRAY_SIZE(env_names); i++) {
orig_env[i] = getenv(env_names[i]);
@@ -42,6 +46,9 @@ static void save_env_before_alias(void)
static void restore_env(int external_alias)
{
int i;
+
+ assert(save_restore_env_balance == 1);
+ save_restore_env_balance = 0;
if (!external_alias && orig_cwd && chdir(orig_cwd))
die_errno("could not move to %s", orig_cwd);
free(orig_cwd);