From 7098250e7aa2f4aef2775f71f31c4e9642dad768 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 8 Nov 2023 08:48:35 +0100 Subject: [PATCH] gutils: avoid race setting prgname from g_option_context_parse()/g_application_run() g_option_context_parse()/g_application_run()/g_test_init() for convenience also call g_set_prgname(), when the prgname is unset at this point. This was racy. Fix the race by using an atomic compare-and-exchange and only reset the value, if it is unset still. --- gio/gapplication.c | 3 ++- glib/glib-private.c | 3 +++ glib/glib-private.h | 3 +++ glib/goption.c | 6 ++---- glib/gtestutils.c | 4 ++-- glib/gutils.c | 19 +++++++++++++++++++ glib/gutilsprivate.h | 2 ++ 7 files changed, 33 insertions(+), 7 deletions(-) diff --git a/gio/gapplication.c b/gio/gapplication.c index 210ebaf6e..7465c9a54 100644 --- a/gio/gapplication.c +++ b/gio/gapplication.c @@ -38,6 +38,7 @@ #include "gioenumtypes.h" #include "gioenums.h" #include "gfile.h" +#include "glib-private.h" #include "glibintl.h" #include "gmarshal-internal.h" @@ -2526,7 +2527,7 @@ g_application_run (GApplication *application, gchar *prgname; prgname = g_path_get_basename (argv[0]); - g_set_prgname (prgname); + GLIB_PRIVATE_CALL (g_set_prgname_once) (prgname); g_free (prgname); } diff --git a/glib/glib-private.c b/glib/glib-private.c index 9f4887aa2..c2b68a060 100644 --- a/glib/glib-private.c +++ b/glib/glib-private.c @@ -23,6 +23,7 @@ #include "glib-private.h" #include "glib-init.h" +#include "gutilsprivate.h" #ifdef USE_INVALID_PARAMETER_HANDLER #include @@ -71,6 +72,8 @@ glib__private__ (void) g_find_program_for_path, g_uri_get_default_scheme_port, + + g_set_prgname_once, }; return &table; diff --git a/glib/glib-private.h b/glib/glib-private.h index e96a73fb6..50aa8a050 100644 --- a/glib/glib-private.h +++ b/glib/glib-private.h @@ -288,6 +288,9 @@ typedef struct { /* See guri.c */ int (* g_uri_get_default_scheme_port) (const char *scheme); + /* See gutils.c */ + gboolean (* g_set_prgname_once) (const gchar *prgname); + /* Add other private functions here, initialize them in glib-private.c */ } GLibPrivateVTable; diff --git a/glib/goption.c b/glib/goption.c index e6d8bf1b8..781c5bae6 100644 --- a/glib/goption.c +++ b/glib/goption.c @@ -35,6 +35,7 @@ #include "gprintf.h" #include "glibintl.h" +#include "gutilsprivate.h" #if defined G_OS_WIN32 #include @@ -1813,10 +1814,7 @@ g_option_context_parse (GOptionContext *context, else prgname = platform_get_argv0 (); - if (prgname) - g_set_prgname (prgname); - else - g_set_prgname (""); + g_set_prgname_once (prgname ? prgname : "