sysprof/0011-libsysprof-return-NULL-instance-unless-debuginfod-wo.patch
Christian Hergert 857a3982f5 Update to 47.2
Resolves: RHEL-69379
2024-11-27 09:59:15 -08:00

159 lines
5.2 KiB
Diff

From ebd0abcaa340e5377b481a5c338c1faa1e14069c Mon Sep 17 00:00:00 2001
From: Christian Hergert <chergert@redhat.com>
Date: Fri, 11 Oct 2024 11:45:41 -0700
Subject: [PATCH 11/33] libsysprof: return NULL instance unless debuginfod
works
If we are configured with support for debuginfod and it fails to initialize
or we are not configured to use debuginfod, always ensure g_object_new()
will return a NULL instance back.
This helps prevent against misconfigured instances so we do not need to
do so many checks in vfuncs as well as allowing us to have the GType be
available always even when not built with debuginfod.
---
.../sysprof-debuginfod-symbolizer.c | 66 +++++++++++++++----
1 file changed, 53 insertions(+), 13 deletions(-)
diff --git a/src/libsysprof/sysprof-debuginfod-symbolizer.c b/src/libsysprof/sysprof-debuginfod-symbolizer.c
index 8dd60d19..bcad9a5c 100644
--- a/src/libsysprof/sysprof-debuginfod-symbolizer.c
+++ b/src/libsysprof/sysprof-debuginfod-symbolizer.c
@@ -20,18 +20,22 @@
#include "config.h"
-#include <elfutils/debuginfod.h>
#include <errno.h>
-#include <stdatomic.h>
#include <glib/gstdio.h>
#include "sysprof-symbolizer-private.h"
#include "sysprof-debuginfod-symbolizer.h"
-#include "sysprof-debuginfod-task-private.h"
#include "sysprof-elf-loader-private.h"
#include "sysprof-symbol-private.h"
+#if HAVE_DEBUGINFOD
+# include <elfutils/debuginfod.h>
+# include "sysprof-debuginfod-task-private.h"
+#else
+typedef struct _debuginfod_client debuginfod_client;
+#endif
+
struct _SysprofDebuginfodSymbolizer
{
SysprofSymbolizer parent_instance;
@@ -58,6 +62,7 @@ sysprof_debuginfod_symbolizer_symbolize (SysprofSymbolizer *symbolizer,
SysprofAddressContext context,
SysprofAddress address)
{
+#if HAVE_DEBUGINFOD
SysprofDebuginfodSymbolizer *self = SYSPROF_DEBUGINFOD_SYMBOLIZER (symbolizer);
g_autoptr(SysprofElf) elf = NULL;
g_autofree char *name = NULL;
@@ -145,6 +150,9 @@ sysprof_debuginfod_symbolizer_symbolize (SysprofSymbolizer *symbolizer,
SYSPROF_SYMBOL_KIND_USER);
return sym;
+#else
+ return NULL;
+#endif
}
static void
@@ -177,19 +185,54 @@ sysprof_debuginfod_symbolizer_finalize (GObject *object)
g_clear_pointer (&self->cache, g_hash_table_unref);
g_clear_pointer (&self->failed, g_hash_table_unref);
+
+#if HAVE_DEBUGINFOD
g_clear_pointer (&self->client, debuginfod_end);
+#endif
g_weak_ref_clear (&self->loader_wr);
G_OBJECT_CLASS (sysprof_debuginfod_symbolizer_parent_class)->finalize (object);
}
+static GObject *
+sysprof_debuginfod_symbolizer_constructor (GType type,
+ guint n_construct_params,
+ GObjectConstructParam *construct_properties)
+{
+#if HAVE_DEBUGINFOD
+ debuginfod_client *client;
+ GObject *object;
+
+ g_assert (type == SYSPROF_TYPE_DEBUGINFOD_SYMBOLIZER);
+
+ /* Don't even allow creating a SysprofDebuginfodSymbolizer instance unless we
+ * can create a new debuginfod_client. This ensures that even if an application
+ * does `g_object_new(SYSPROF_TYPE_DEBUGINFOD_SYMBOLIZER, NULL)` they will get
+ * `NULL` back instead of a misconfigured instance.
+ */
+ if (!(client = debuginfod_begin ()))
+ return NULL;
+
+ object = G_OBJECT_CLASS (sysprof_debuginfod_symbolizer_parent_class)
+ ->constructor (type, n_construct_params, construct_properties);
+
+ SYSPROF_DEBUGINFOD_SYMBOLIZER (object)->client = client;
+
+ return object;
+#else
+ errno = ENOTSUP;
+ return NULL;
+#endif
+}
+
static void
sysprof_debuginfod_symbolizer_class_init (SysprofDebuginfodSymbolizerClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
SysprofSymbolizerClass *symbolizer_class = SYSPROF_SYMBOLIZER_CLASS (klass);
+ object_class->constructor = sysprof_debuginfod_symbolizer_constructor;
object_class->dispose = sysprof_debuginfod_symbolizer_dispose;
object_class->finalize = sysprof_debuginfod_symbolizer_finalize;
@@ -201,17 +244,18 @@ static void
sysprof_debuginfod_symbolizer_init (SysprofDebuginfodSymbolizer *self)
{
g_weak_ref_init (&self->loader_wr, NULL);
+
+ self->loader = sysprof_elf_loader_new ();
+ self->cache = g_hash_table_new_full (NULL, NULL, g_object_unref, NULL);
+ self->failed = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
}
SysprofSymbolizer *
sysprof_debuginfod_symbolizer_new (GError **error)
{
- g_autoptr(SysprofDebuginfodSymbolizer) self = NULL;
+ SysprofSymbolizer *self;
- self = g_object_new (SYSPROF_TYPE_DEBUGINFOD_SYMBOLIZER, NULL);
- self->client = debuginfod_begin ();
-
- if (self->client == NULL)
+ if (!(self = g_object_new (SYSPROF_TYPE_DEBUGINFOD_SYMBOLIZER, NULL)))
{
int errsv = errno;
g_set_error_literal (error,
@@ -221,9 +265,5 @@ sysprof_debuginfod_symbolizer_new (GError **error)
return NULL;
}
- self->loader = sysprof_elf_loader_new ();
- self->cache = g_hash_table_new_full (NULL, NULL, g_object_unref, NULL);
- self->failed = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
-
- return SYSPROF_SYMBOLIZER (g_steal_pointer (&self));
+ return self;
}
--
2.45.2