From 001befcdd5a208a046e0196e3fec7b16041cfe14 Mon Sep 17 00:00:00 2001 From: Anurag Gupta Date: Tue, 6 May 2014 12:16:24 -0700 Subject: Fix the issues in git__on_shutdown --- src/global.c | 12 +++++++----- src/sysdir.c | 2 ++ 2 files changed, 9 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/global.c b/src/global.c index 15baf1eb8..a64dce9ef 100644 --- a/src/global.c +++ b/src/global.c @@ -23,7 +23,7 @@ static git_atomic git__n_inits; void git__on_shutdown(git_global_shutdown_fn callback) { int count = git_atomic_inc(&git__n_shutdown_callbacks); - assert(count <= MAX_SHUTDOWN_CB); + assert(count <= MAX_SHUTDOWN_CB && count > 0); git__shutdown_callbacks[count - 1] = callback; } @@ -31,10 +31,12 @@ static void git__shutdown(void) { int pos; - while ((pos = git_atomic_dec(&git__n_shutdown_callbacks)) >= 0) { - if (git__shutdown_callbacks[pos]) - git__shutdown_callbacks[pos](); - } + for (pos = git_atomic_get(&git__n_shutdown_callbacks); pos > 0; pos = git_atomic_dec(&git__n_shutdown_callbacks)) + if (git__shutdown_callbacks[pos - 1]) { + git__shutdown_callbacks[pos - 1](); + git__shutdown_callbacks[pos - 1] = NULL; + } + } /** diff --git a/src/sysdir.c b/src/sysdir.c index e0c24f3b3..cd94a8b57 100644 --- a/src/sysdir.c +++ b/src/sysdir.c @@ -90,6 +90,8 @@ void git_sysdir_global_shutdown(void) int i; for (i = 0; i < GIT_SYSDIR__MAX; ++i) git_buf_free(&git_sysdir__dirs[i]); + + git_sysdir__dirs_shutdown_set = 0; } static int git_sysdir_check_selector(git_sysdir_t which) -- cgit v1.2.1 From 0bf5430dc77c69d2b2d27a771b584b17cedb97ec Mon Sep 17 00:00:00 2001 From: Anurag Gupta Date: Tue, 6 May 2014 13:33:47 -0700 Subject: Fix the issues in git_shutdown 1) Call to git_shutdown results in setting git__n_shutdown_callbacks to -1. Next call to git__on_shutdown results in ABW (Array Bound Write) for array git__shutdown_callbacks. In the current Implementation, git_atomic_dec is called git__n_shutdown_callbacks + 1 times. I have modified it to a for loop so that it is more readable. It would not set git__n_shutdown_callbacks to a negative number and reset the elements of git__shutdown_callbacks to NULL. 2) In function git_sysdir_get, shutdown function is registered only if git_sysdir__dirs_shutdown_set is set to 0. However, after this variable is set to 1, it is never reset to 0. If git_sysdir_global_init is called again from synchronized_threads_init it does not register shutdown function for this subsystem. --- src/global.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/global.c b/src/global.c index a64dce9ef..4dfdcf438 100644 --- a/src/global.c +++ b/src/global.c @@ -31,11 +31,11 @@ static void git__shutdown(void) { int pos; - for (pos = git_atomic_get(&git__n_shutdown_callbacks); pos > 0; pos = git_atomic_dec(&git__n_shutdown_callbacks)) - if (git__shutdown_callbacks[pos - 1]) { - git__shutdown_callbacks[pos - 1](); - git__shutdown_callbacks[pos - 1] = NULL; - } + for (pos = git_atomic_get(&git__n_shutdown_callbacks); pos > 0; pos = git_atomic_dec(&git__n_shutdown_callbacks)) { + git_global_shutdown_fn cb = git__swap(git__shutdown_callbacks[pos - 1], NULL); + if (cb != NULL) + cb(); + } } -- cgit v1.2.1