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>

Junio C Hamano committed Jan 26, 2016 at 22:50 UTC 2e1175d43d05e83fe836e1c8c8e7c25b7ee659ae
1 file changed +7
git.c
+7
@@ -26,11 +26,15 @@ static const char *env_names[] = {
26 };
27 static char *orig_env[4];
28 static int saved_env_before_alias;
29 +static int save_restore_env_balance;
30
31 static void save_env_before_alias(void)
32 {
33 int i;
34 saved_env_before_alias = 1;
35 +
36 + assert(save_restore_env_balance == 0);
37 + save_restore_env_balance = 1;
38 orig_cwd = xgetcwd();
39 for (i = 0; i < ARRAY_SIZE(env_names); i++) {
40 orig_env[i] = getenv(env_names[i]);
@@ -42,6 +46,9 @@ static void save_env_before_alias(void)
46 static void restore_env(int external_alias)
47 {
48 int i;
49 +
50 + assert(save_restore_env_balance == 1);
51 + save_restore_env_balance = 0;
52 if (!external_alias && orig_cwd && chdir(orig_cwd))
53 die_errno("could not move to %s", orig_cwd);
54 free(orig_cwd);