|
|
d9c268 |
From ff90674fd801dd369231a20c47ebef0d08402e9e Mon Sep 17 00:00:00 2001
|
|
|
d9c268 |
From: William Roberts <william.c.roberts@intel.com>
|
|
|
d9c268 |
Date: Tue, 12 Jan 2021 14:12:48 -0600
|
|
|
d9c268 |
Subject: [PATCH 1/6] tabrmd-options: fix memory leak
|
|
|
d9c268 |
|
|
|
d9c268 |
The tabrmd_options_t structure is initialized with static char *
|
|
|
d9c268 |
strings. These strings can be replaced by g_option_context_parse().
|
|
|
d9c268 |
However, g_option_context_parse() replaces the string with allocated
|
|
|
d9c268 |
memory and thus needs a call to g_free. Either one would need to keep
|
|
|
d9c268 |
track if glib allocated the string and conditionally free it, or just
|
|
|
d9c268 |
set all the strings to glib allocated strings. This patch takes the
|
|
|
d9c268 |
approach of always allocating the option strings.
|
|
|
d9c268 |
|
|
|
d9c268 |
Fixes leaks like:
|
|
|
d9c268 |
==2677142==ERROR: LeakSanitizer: detected memory leaks
|
|
|
d9c268 |
|
|
|
d9c268 |
Direct leak of 9 byte(s) in 1 object(s) allocated from:
|
|
|
d9c268 |
#8 0x7fbd1acd5da1 in g_option_context_parse (/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x5eda1)
|
|
|
d9c268 |
#9 0x4cc438 in parse_opts /home/wcrobert/workspace/tpm2-abrmd/src/tabrmd-options.c:103:10
|
|
|
d9c268 |
#10 0x4c7ffe in main /home/wcrobert/workspace/tpm2-abrmd/src/tabrmd.c:41:10
|
|
|
d9c268 |
#11 0x7fbd1a8770b2 in __libc_start_main /build/glibc-ZN95T4/glibc-2.31/csu/../csu/libc-start.c:308:16
|
|
|
d9c268 |
#12 0x42004d in _start (/home/wcrobert/workspace/tpm2-abrmd/src/tpm2-abrmd+0x42004d)
|
|
|
d9c268 |
|
|
|
d9c268 |
Signed-off-by: William Roberts <william.c.roberts@intel.com>
|
|
|
d9c268 |
---
|
|
|
d9c268 |
src/tabrmd-init.c | 2 ++
|
|
|
d9c268 |
src/tabrmd-options.c | 53 +++++++++++++++++++++++++++++++++++++++-----
|
|
|
d9c268 |
src/tabrmd-options.h | 11 +++++----
|
|
|
d9c268 |
src/tabrmd.c | 4 +++-
|
|
|
d9c268 |
4 files changed, 59 insertions(+), 11 deletions(-)
|
|
|
d9c268 |
|
|
|
d9c268 |
diff --git a/src/tabrmd-init.c b/src/tabrmd-init.c
|
|
|
d9c268 |
index 2ad7539..58e0103 100644
|
|
|
d9c268 |
--- a/src/tabrmd-init.c
|
|
|
d9c268 |
+++ b/src/tabrmd-init.c
|
|
|
d9c268 |
@@ -99,6 +99,8 @@ gmain_data_cleanup (gmain_data_t *data)
|
|
|
d9c268 |
if (data->loop != NULL) {
|
|
|
d9c268 |
main_loop_quit (data->loop);
|
|
|
d9c268 |
}
|
|
|
d9c268 |
+
|
|
|
d9c268 |
+ tabrmd_options_free(&data->options);
|
|
|
d9c268 |
}
|
|
|
d9c268 |
/*
|
|
|
d9c268 |
* This function initializes and configures all of the long-lived objects
|
|
|
d9c268 |
diff --git a/src/tabrmd-options.c b/src/tabrmd-options.c
|
|
|
d9c268 |
index 0dd7b87..22f249c 100644
|
|
|
d9c268 |
--- a/src/tabrmd-options.c
|
|
|
d9c268 |
+++ b/src/tabrmd-options.c
|
|
|
d9c268 |
@@ -16,6 +16,12 @@
|
|
|
d9c268 |
#define G_OPTION_FLAG_NONE 0
|
|
|
d9c268 |
#endif
|
|
|
d9c268 |
|
|
|
d9c268 |
+#define SET_STR_IF_NULL(var, value) \
|
|
|
d9c268 |
+ do { \
|
|
|
d9c268 |
+ var = var == NULL ? g_strdup(value) : var; \
|
|
|
d9c268 |
+ g_assert(var); \
|
|
|
d9c268 |
+ } while(0)
|
|
|
d9c268 |
+
|
|
|
d9c268 |
/*
|
|
|
d9c268 |
* This is a GOptionArgFunc callback invoked from the GOption processor from
|
|
|
d9c268 |
* the parse_opts function below. It will be called when the daemon is
|
|
|
d9c268 |
@@ -36,6 +42,22 @@ show_version (const gchar *option_name,
|
|
|
d9c268 |
g_print ("tpm2-abrmd version %s\n", VERSION);
|
|
|
d9c268 |
exit (0);
|
|
|
d9c268 |
}
|
|
|
d9c268 |
+
|
|
|
d9c268 |
+/**
|
|
|
d9c268 |
+ * Frees internal memory associated with a tabrmd_options_t struct.
|
|
|
d9c268 |
+ * @param opts
|
|
|
d9c268 |
+ * The options to free, note it doesn't free opts itself.
|
|
|
d9c268 |
+ */
|
|
|
d9c268 |
+void
|
|
|
d9c268 |
+tabrmd_options_free(tabrmd_options_t *opts)
|
|
|
d9c268 |
+{
|
|
|
d9c268 |
+ g_assert(opts);
|
|
|
d9c268 |
+
|
|
|
d9c268 |
+ g_clear_pointer(&opts->dbus_name, g_free);
|
|
|
d9c268 |
+ g_clear_pointer(&opts->prng_seed_file, g_free);
|
|
|
d9c268 |
+ g_clear_pointer(&opts->tcti_conf, g_free);
|
|
|
d9c268 |
+}
|
|
|
d9c268 |
+
|
|
|
d9c268 |
/**
|
|
|
d9c268 |
* This function parses the parameter argument vector and populates the
|
|
|
d9c268 |
* parameter 'options' structure with data needed to configure the tabrmd.
|
|
|
d9c268 |
@@ -51,7 +73,7 @@ parse_opts (gint argc,
|
|
|
d9c268 |
gchar *argv[],
|
|
|
d9c268 |
tabrmd_options_t *options)
|
|
|
d9c268 |
{
|
|
|
d9c268 |
- gchar *logger_name = "stdout";
|
|
|
d9c268 |
+ gchar *logger_name = NULL;
|
|
|
d9c268 |
GOptionContext *ctx;
|
|
|
d9c268 |
GError *err = NULL;
|
|
|
d9c268 |
gboolean session_bus = FALSE;
|
|
|
d9c268 |
@@ -105,33 +127,52 @@ parse_opts (gint argc,
|
|
|
d9c268 |
return FALSE;
|
|
|
d9c268 |
}
|
|
|
d9c268 |
g_option_context_free (ctx);
|
|
|
d9c268 |
+
|
|
|
d9c268 |
+ /*
|
|
|
d9c268 |
+ * Set unset STRING options to defaults, we do this so we can free allocated
|
|
|
d9c268 |
+ * string options with gfree, having a mix of const and allocated ptr's
|
|
|
d9c268 |
+ * causes leaks
|
|
|
d9c268 |
+ */
|
|
|
d9c268 |
+ SET_STR_IF_NULL(options->dbus_name, TABRMD_DBUS_NAME_DEFAULT);
|
|
|
d9c268 |
+ SET_STR_IF_NULL(options->prng_seed_file, TABRMD_ENTROPY_SRC_DEFAULT);
|
|
|
d9c268 |
+ SET_STR_IF_NULL(options->tcti_conf, TABRMD_TCTI_CONF_DEFAULT);
|
|
|
d9c268 |
+ SET_STR_IF_NULL(logger_name, "stdout");
|
|
|
d9c268 |
+
|
|
|
d9c268 |
/* select the bus type, default to G_BUS_TYPE_SESSION */
|
|
|
d9c268 |
options->bus = session_bus ? G_BUS_TYPE_SESSION : G_BUS_TYPE_SYSTEM;
|
|
|
d9c268 |
- if (set_logger (logger_name) == -1) {
|
|
|
d9c268 |
+ gint ret = set_logger (logger_name);
|
|
|
d9c268 |
+ if (ret == -1) {
|
|
|
d9c268 |
g_critical ("Unknown logger: %s, try --help\n", logger_name);
|
|
|
d9c268 |
- return FALSE;
|
|
|
d9c268 |
+ g_free(logger_name);
|
|
|
d9c268 |
+ goto error;
|
|
|
d9c268 |
}
|
|
|
d9c268 |
+ g_free(logger_name);
|
|
|
d9c268 |
+
|
|
|
d9c268 |
if (options->max_connections < 1 ||
|
|
|
d9c268 |
options->max_connections > TABRMD_CONNECTION_MAX)
|
|
|
d9c268 |
{
|
|
|
d9c268 |
g_critical ("maximum number of connections must be between 1 "
|
|
|
d9c268 |
"and %d", TABRMD_CONNECTION_MAX);
|
|
|
d9c268 |
- return FALSE;
|
|
|
d9c268 |
+ goto error;
|
|
|
d9c268 |
}
|
|
|
d9c268 |
if (options->max_sessions < 1 ||
|
|
|
d9c268 |
options->max_sessions > TABRMD_SESSIONS_MAX_DEFAULT)
|
|
|
d9c268 |
{
|
|
|
d9c268 |
g_critical ("max-sessions must be between 1 and %d",
|
|
|
d9c268 |
TABRMD_SESSIONS_MAX_DEFAULT);
|
|
|
d9c268 |
- return FALSE;
|
|
|
d9c268 |
+ goto error;
|
|
|
d9c268 |
}
|
|
|
d9c268 |
if (options->max_transients < 1 ||
|
|
|
d9c268 |
options->max_transients > TABRMD_TRANSIENT_MAX)
|
|
|
d9c268 |
{
|
|
|
d9c268 |
g_critical ("max-trans-obj parameter must be between 1 and %d",
|
|
|
d9c268 |
TABRMD_TRANSIENT_MAX);
|
|
|
d9c268 |
- return FALSE;
|
|
|
d9c268 |
+ goto error;
|
|
|
d9c268 |
}
|
|
|
d9c268 |
g_warning ("tcti_conf after: \"%s\"", options->tcti_conf);
|
|
|
d9c268 |
return TRUE;
|
|
|
d9c268 |
+
|
|
|
d9c268 |
+error:
|
|
|
d9c268 |
+ tabrmd_options_free(options);
|
|
|
d9c268 |
+ return FALSE;
|
|
|
d9c268 |
}
|
|
|
d9c268 |
diff --git a/src/tabrmd-options.h b/src/tabrmd-options.h
|
|
|
d9c268 |
index 4994920..d6bcfe9 100644
|
|
|
d9c268 |
--- a/src/tabrmd-options.h
|
|
|
d9c268 |
+++ b/src/tabrmd-options.h
|
|
|
d9c268 |
@@ -15,10 +15,10 @@
|
|
|
d9c268 |
.max_connections = TABRMD_CONNECTIONS_MAX_DEFAULT, \
|
|
|
d9c268 |
.max_transients = TABRMD_TRANSIENT_MAX_DEFAULT, \
|
|
|
d9c268 |
.max_sessions = TABRMD_SESSIONS_MAX_DEFAULT, \
|
|
|
d9c268 |
- .dbus_name = TABRMD_DBUS_NAME_DEFAULT, \
|
|
|
d9c268 |
- .prng_seed_file = TABRMD_ENTROPY_SRC_DEFAULT, \
|
|
|
d9c268 |
+ .dbus_name = NULL, \
|
|
|
d9c268 |
+ .prng_seed_file = NULL, \
|
|
|
d9c268 |
.allow_root = FALSE, \
|
|
|
d9c268 |
- .tcti_conf = TABRMD_TCTI_CONF_DEFAULT, \
|
|
|
d9c268 |
+ .tcti_conf = NULL, \
|
|
|
d9c268 |
}
|
|
|
d9c268 |
|
|
|
d9c268 |
typedef struct tabrmd_options {
|
|
|
d9c268 |
@@ -28,7 +28,7 @@ typedef struct tabrmd_options {
|
|
|
d9c268 |
guint max_transients;
|
|
|
d9c268 |
guint max_sessions;
|
|
|
d9c268 |
gchar *dbus_name;
|
|
|
d9c268 |
- const gchar *prng_seed_file;
|
|
|
d9c268 |
+ gchar *prng_seed_file;
|
|
|
d9c268 |
gboolean allow_root;
|
|
|
d9c268 |
gchar *tcti_conf;
|
|
|
d9c268 |
} tabrmd_options_t;
|
|
|
d9c268 |
@@ -38,4 +38,7 @@ parse_opts (gint argc,
|
|
|
d9c268 |
gchar *argv[],
|
|
|
d9c268 |
tabrmd_options_t *options);
|
|
|
d9c268 |
|
|
|
d9c268 |
+void
|
|
|
d9c268 |
+tabrmd_options_free(tabrmd_options_t *opts);
|
|
|
d9c268 |
+
|
|
|
d9c268 |
#endif /* TABRMD_OPTIONS_H */
|
|
|
d9c268 |
diff --git a/src/tabrmd.c b/src/tabrmd.c
|
|
|
d9c268 |
index 7c93e90..e015de3 100644
|
|
|
d9c268 |
--- a/src/tabrmd.c
|
|
|
d9c268 |
+++ b/src/tabrmd.c
|
|
|
d9c268 |
@@ -43,7 +43,8 @@ main (int argc, char *argv[])
|
|
|
d9c268 |
}
|
|
|
d9c268 |
if (geteuid() == 0 && ! gmain_data.options.allow_root) {
|
|
|
d9c268 |
g_print ("Refusing to run as root. Pass --allow-root if you know what you are doing.\n");
|
|
|
d9c268 |
- return 1;
|
|
|
d9c268 |
+ ret = 1;
|
|
|
d9c268 |
+ goto out;
|
|
|
d9c268 |
}
|
|
|
d9c268 |
|
|
|
d9c268 |
g_mutex_init (&gmain_data.init_mutex);
|
|
|
d9c268 |
@@ -63,6 +64,7 @@ main (int argc, char *argv[])
|
|
|
d9c268 |
if (ret == 0 && gmain_data.ipc_disconnected) {
|
|
|
d9c268 |
ret = EX_IOERR;
|
|
|
d9c268 |
}
|
|
|
d9c268 |
+out:
|
|
|
d9c268 |
gmain_data_cleanup (&gmain_data);
|
|
|
d9c268 |
return ret;
|
|
|
d9c268 |
}
|
|
|
d9c268 |
--
|
|
|
d9c268 |
2.34.3
|
|
|
d9c268 |
|