git: protect against unbalanced calls to {save,restore}_env()
authorJunio C Hamano <gitster@pobox.com>
Wed, 27 Jan 2016 06:50:27 +0000 (22:50 -0800)
committerJunio C Hamano <gitster@pobox.com>
Wed, 27 Jan 2016 23:19:03 +0000 (15:19 -0800)
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>
git.c
diff --git a/git.c b/git.c
index a57a4cb4694e34bd49ed59d9d9cabf5b19e4d169..e39b972353c5647ddabc94dc89d415c00c01426c 100644 (file)
--- 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);