[glib/mcatanzaro/glib-2-56-rhel8: 45/45] gutils: Avoid segfault in g_get_user_database_entry
- From: Michael Catanzaro <mcatanzaro src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib/mcatanzaro/glib-2-56-rhel8: 45/45] gutils: Avoid segfault in g_get_user_database_entry
- Date: Wed, 10 Nov 2021 22:06:00 +0000 (UTC)
commit d1a6b6d7dd3c3c9a340aa774487ad2c1baf876a0
Author: Jamie Bainbridge <jamie bainbridge gmail com>
Date: Wed Sep 8 12:08:17 2021 +1000
gutils: Avoid segfault in g_get_user_database_entry
g_get_user_database_entry() capitalises the first letter of pw_name
with g_ascii_toupper (pw->pw_name[0]).
However, the manpage for getpwnam() and getpwuid() says the result of
those calls "may point to a static area". GLib is then trying to edit
static memory which belongs to a shared library, so segfaults.
The reentrant variants of the above calls are supposed to fill the user
buffer supplied to them, however Michael Catanzaro also found a bug in
systemd where the data is not copied to the user buffer and still points
to static memory, resulting in the same sort of segfault. See:
https://github.com/systemd/systemd/issues/20679
Solve both these cases in GLib by copying pw_name off to a temporary
variable, set uppercase on that variable, and use the variable to join
into the desired string. Free the variable after it is no longer needed.
Signed-off-by: Jamie Bainbridge <jamie bainbridge gmail com>
glib/gutils.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
---
diff --git a/glib/gutils.c b/glib/gutils.c
index 5813b2281..2dca1bbc7 100644
--- a/glib/gutils.c
+++ b/glib/gutils.c
@@ -703,14 +703,17 @@ g_get_user_database_entry (void)
{
gchar **gecos_fields;
gchar **name_parts;
+ gchar *uppercase_pw_name;
/* split the gecos field and substitute '&' */
gecos_fields = g_strsplit (pw->pw_gecos, ",", 0);
name_parts = g_strsplit (gecos_fields[0], "&", 0);
- pw->pw_name[0] = g_ascii_toupper (pw->pw_name[0]);
- e.real_name = g_strjoinv (pw->pw_name, name_parts);
+ uppercase_pw_name = g_strdup (pw->pw_name);
+ uppercase_pw_name[0] = g_ascii_toupper (uppercase_pw_name[0]);
+ e.real_name = g_strjoinv (uppercase_pw_name, name_parts);
g_strfreev (gecos_fields);
g_strfreev (name_parts);
+ g_free (uppercase_pw_name);
}
#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]