|
|
677019 |
From 9a9ab4b2cad1597cbafbae756483aefa6e36f1eb Mon Sep 17 00:00:00 2001
|
|
|
10fa70 |
From: Jiri Sasek <Jiri.Sasek@Oracle.COM>
|
|
|
10fa70 |
Date: Fri, 13 Mar 2020 19:02:58 +0100
|
|
|
10fa70 |
Subject: [PATCH] Add finalization safety check to com_err
|
|
|
10fa70 |
|
|
|
10fa70 |
If the linker erroneously runs the libkrb5 finalizer after the
|
|
|
10fa70 |
libcom_err finalizer, the consequent remove_error_table() calls could
|
|
|
10fa70 |
crash due to accessing a destroyed mutex or an invalid et_list
|
|
|
10fa70 |
pointer. Add an unsynchronized check on finalized in
|
|
|
10fa70 |
remove_error_table(), and set et_list to null in com_err_terminate()
|
|
|
10fa70 |
after destroying the list.
|
|
|
10fa70 |
|
|
|
10fa70 |
[ghudson@mit.edu: minimized code hanges; rewrote comment and commit
|
|
|
10fa70 |
message]
|
|
|
10fa70 |
|
|
|
10fa70 |
ticket: 8890 (new)
|
|
|
10fa70 |
(cherry picked from commit 9d654aa05e26bbf22f140abde3436afeff2fdf8d)
|
|
|
10fa70 |
(cherry picked from commit c7a37d3e87132864ebc44710baf1d50a69682b5c)
|
|
|
10fa70 |
---
|
|
|
10fa70 |
src/util/et/error_message.c | 7 ++++++-
|
|
|
10fa70 |
1 file changed, 6 insertions(+), 1 deletion(-)
|
|
|
10fa70 |
|
|
|
10fa70 |
diff --git a/src/util/et/error_message.c b/src/util/et/error_message.c
|
|
|
10fa70 |
index d7069a9df..7dc02a34e 100644
|
|
|
10fa70 |
--- a/src/util/et/error_message.c
|
|
|
10fa70 |
+++ b/src/util/et/error_message.c
|
|
|
10fa70 |
@@ -26,7 +26,7 @@
|
|
|
10fa70 |
|
|
|
10fa70 |
static struct et_list *et_list;
|
|
|
10fa70 |
static k5_mutex_t et_list_lock = K5_MUTEX_PARTIAL_INITIALIZER;
|
|
|
10fa70 |
-static int terminated = 0; /* for debugging shlib fini sequence errors */
|
|
|
10fa70 |
+static int terminated = 0; /* for safety and finalization debugging */
|
|
|
10fa70 |
|
|
|
10fa70 |
MAKE_INIT_FUNCTION(com_err_initialize);
|
|
|
10fa70 |
MAKE_FINI_FUNCTION(com_err_terminate);
|
|
|
10fa70 |
@@ -69,6 +69,7 @@ void com_err_terminate(void)
|
|
|
10fa70 |
enext = e->next;
|
|
|
10fa70 |
free(e);
|
|
|
10fa70 |
}
|
|
|
10fa70 |
+ et_list = NULL;
|
|
|
10fa70 |
k5_mutex_unlock(&et_list_lock);
|
|
|
10fa70 |
k5_mutex_destroy(&et_list_lock);
|
|
|
10fa70 |
terminated = 1;
|
|
|
10fa70 |
@@ -280,6 +281,10 @@ remove_error_table(const struct error_table *et)
|
|
|
10fa70 |
{
|
|
|
10fa70 |
struct et_list **ep, *e;
|
|
|
10fa70 |
|
|
|
10fa70 |
+ /* Safety check in case libraries are finalized in the wrong order. */
|
|
|
10fa70 |
+ if (terminated)
|
|
|
10fa70 |
+ return ENOENT;
|
|
|
10fa70 |
+
|
|
|
10fa70 |
if (CALL_INIT_FUNCTION(com_err_initialize))
|
|
|
10fa70 |
return 0;
|
|
|
10fa70 |
k5_mutex_lock(&et_list_lock);
|