aea50f
From b6036e23b0477be147211b4e21a6b49cd4d6c9a0 Mon Sep 17 00:00:00 2001
aea50f
From: Jamie Bainbridge <jamie.bainbridge@gmail.com>
aea50f
Date: Wed, 8 Sep 2021 12:08:17 +1000
aea50f
Subject: [PATCH] gutils: Avoid segfault in g_get_user_database_entry
aea50f
aea50f
g_get_user_database_entry() uses variable pwd to store the contents of
aea50f
the call to getpwnam_r(), then capitalises the first letter of pw_name
aea50f
with g_ascii_toupper (pw->pw_name[0]).
aea50f
aea50f
However, as per the getpwnam manpage, the result of that call "may point
aea50f
to a static area". When this happens, GLib is trying to edit static
aea50f
memory which belongs to a shared library, so segfaults.
aea50f
aea50f
Instead, copy pw_name off to a temporary variable, set uppercase on
aea50f
that variable, and use the variable to join into the desired string.
aea50f
Free the new variable after it is no longer needed.
aea50f
aea50f
Signed-off-by: Jamie Bainbridge <jamie.bainbridge@gmail.com>
aea50f
---
aea50f
 glib/gutils.c | 7 +++++--
aea50f
 1 file changed, 5 insertions(+), 2 deletions(-)
aea50f
aea50f
diff --git a/glib/gutils.c b/glib/gutils.c
aea50f
index b7a2113d4..4bccd7229 100644
aea50f
--- a/glib/gutils.c
aea50f
+++ b/glib/gutils.c
aea50f
@@ -692,14 +692,17 @@ g_get_user_database_entry (void)
aea50f
               {
aea50f
                 gchar **gecos_fields;
aea50f
                 gchar **name_parts;
aea50f
+                gchar *uppercase_pw_name;
aea50f
 
aea50f
                 /* split the gecos field and substitute '&' */
aea50f
                 gecos_fields = g_strsplit (pw->pw_gecos, ",", 0);
aea50f
                 name_parts = g_strsplit (gecos_fields[0], "&", 0);
aea50f
-                pw->pw_name[0] = g_ascii_toupper (pw->pw_name[0]);
aea50f
-                e.real_name = g_strjoinv (pw->pw_name, name_parts);
aea50f
+                uppercase_pw_name = g_strdup (pw->pw_name);
aea50f
+                uppercase_pw_name[0] = g_ascii_toupper (uppercase_pw_name[0]);
aea50f
+                e.real_name = g_strjoinv (uppercase_pw_name, name_parts);
aea50f
                 g_strfreev (gecos_fields);
aea50f
                 g_strfreev (name_parts);
aea50f
+                g_free (uppercase_pw_name);
aea50f
               }
aea50f
 #endif
aea50f
 
aea50f
-- 
aea50f
GitLab
aea50f