Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Step:15-SP4
glib2.17285
glib2-CVE-2019-13012-keyfile-settings-Use-tight...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File glib2-CVE-2019-13012-keyfile-settings-Use-tighter-permissions.patch of Package glib2.17285
From f79ddc754a11330c7ebe9fd4876466c21c88527f Mon Sep 17 00:00:00 2001 From: Colin Walters <walters@verbum.org> Date: Thu, 23 Jun 2016 08:42:53 -0400 Subject: GFile: Add g_file_peek_path() This is a variant of g_file_get_path() which returns a const string to the caller, rather than transferring ownership. I've been carrying `gs_file_get_path_cached()` in libgsystem and it has seen a lot of use in the ostree and flatpak codebases. There are probably others too. I think language bindings like Python/Gjs could also use this to avoid an extra malloc (i.e. we could transparently replace `g_file_get_path()` with `g_file_peek_path()`. (Originally by Colin Walters. Tweaked by Philip Withnall to update to 2.56, change the function name and drop the locking.) https://bugzilla.gnome.org/show_bug.cgi?id=767976 --- docs/reference/gio/gio-sections.txt | 1 + gio/gfile.c | 101 ++++++++++++++++++++++++++++++++++++ gio/gfile.h | 2 + gio/tests/file.c | 8 +-- 4 files changed, 109 insertions(+), 3 deletions(-) diff --git a/docs/reference/gio/gio-sections.txt b/docs/reference/gio/gio-sections.txt index 780d249..4829c53 100644 --- a/docs/reference/gio/gio-sections.txt +++ b/docs/reference/gio/gio-sections.txt @@ -90,6 +90,7 @@ g_file_hash g_file_equal g_file_get_basename g_file_get_path +g_file_peek_path g_file_get_uri g_file_get_parse_name g_file_get_parent diff --git a/gio/gfile.c b/gio/gfile.c index 1d664e9..1cb8373 100644 --- a/gio/gfile.c +++ b/gio/gfile.c @@ -533,6 +533,107 @@ g_file_get_path (GFile *file) return (* iface->get_path) (file); } +/* Original commit introducing this in libgsystem: + * + * fileutil: Handle recent: and trash: URIs + * + * The gs_file_get_path_cached() was rather brittle in its handling + * of URIs. It would assert() when a GFile didn't have a backing path + * (such as when handling trash: or recent: URIs), and didn't know + * how to get the target URI for those items either. + * + * Make sure that we do not assert() when a backing path cannot be + * found, and handle recent: and trash: URIs. + * + * https://bugzilla.gnome.org/show_bug.cgi?id=708435 + */ +static char * +file_get_target_path (GFile *file) +{ + GFileInfo *info; + const char *target; + char *path; + + info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_TARGET_URI, G_FILE_QUERY_INFO_NONE, NULL, NULL); + if (info == NULL) + return NULL; + target = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_TARGET_URI); + path = g_filename_from_uri (target, NULL, NULL); + g_object_unref (info); + + return path; +} + +static const char * +file_peek_path_generic (GFile *file) +{ + const char *path; + static GQuark _file_path_quark = 0; + + if (G_UNLIKELY (_file_path_quark) == 0) + _file_path_quark = g_quark_from_static_string ("gio-file-path"); + + /* We need to be careful about threading, as two threads calling + * g_file_peek_path() on the same file could race: both would see + * (g_object_get_qdata(…) == NULL) to begin with, both would generate and add + * the path, but the second thread to add it would end up freeing the path + * set by the first thread. The first thread would still return the pointer + * to that freed path, though, resulting an a read-after-free. Handle that + * with a compare-and-swap loop. The g_object_*_qdata() functions are atomic. */ + + while (TRUE) + { + gchar *new_path = NULL; + + path = g_object_get_qdata ((GObject*)file, _file_path_quark); + + if (path != NULL) + break; + + if (g_file_has_uri_scheme (file, "trash") || + g_file_has_uri_scheme (file, "recent")) + new_path = file_get_target_path (file); + else + new_path = g_file_get_path (file); + if (new_path == NULL) + return NULL; + + /* By passing NULL here, we ensure we never replace existing data: */ + if (g_object_replace_qdata ((GObject *) file, _file_path_quark, + NULL, (gpointer) new_path, + (GDestroyNotify) g_free, NULL)) + break; + else + g_free (new_path); + } + + return path; +} + +/** + * g_file_peek_path: + * @file: input #GFile + * + * Exactly like g_file_get_path(), but caches the result via + * g_object_set_qdata_full(). This is useful for example in C + * applications which mix `g_file_*` APIs with native ones. It + * also avoids an extra duplicated string when possible, so will be + * generally more efficient. + * + * This call does no blocking I/O. + * + * Returns: (type filename) (nullable): string containing the #GFile's path, + * or %NULL if no such path exists. The returned string is owned by @file. + * Since: 2.56 + */ +const char * +g_file_peek_path (GFile *file) +{ + if (G_IS_LOCAL_FILE (file)) + return _g_local_file_get_filename ((GLocalFile *) file); + return file_peek_path_generic (file); +} + /** * g_file_get_uri: * @file: input #GFile diff --git a/gio/gfile.h b/gio/gfile.h index 1efbfa0..7b02649 100644 --- a/gio/gfile.h +++ b/gio/gfile.h @@ -617,6 +617,8 @@ GLIB_AVAILABLE_IN_ALL char * g_file_get_basename (GFile *file); GLIB_AVAILABLE_IN_ALL char * g_file_get_path (GFile *file); +GLIB_AVAILABLE_IN_2_54 +const char * g_file_peek_path (GFile *file); GLIB_AVAILABLE_IN_ALL char * g_file_get_uri (GFile *file); GLIB_AVAILABLE_IN_ALL diff --git a/gio/tests/file.c b/gio/tests/file.c index 7791837..df3d387 100644 --- a/gio/tests/file.c +++ b/gio/tests/file.c @@ -149,9 +149,12 @@ monitor_changed (GFileMonitor *monitor, { CreateDeleteData *data = user_data; gchar *path; + const gchar *peeked_path; path = g_file_get_path (file); + peeked_path = g_file_peek_path (file); g_assert_cmpstr (data->monitor_path, ==, path); + g_assert_cmpstr (path, ==, peeked_path); g_free (path); if (event_type == G_FILE_MONITOR_EVENT_CREATED) @@ -599,7 +602,7 @@ static void test_replace_load (void) { ReplaceLoadData *data; - gchar *path; + const gchar *path; GFileIOStream *iostream; data = g_new0 (ReplaceLoadData, 1); @@ -611,7 +614,7 @@ test_replace_load (void) g_assert (data->file != NULL); g_object_unref (iostream); - path = g_file_get_path (data->file); + path = g_file_peek_path (data->file); remove (path); g_assert (!g_file_query_exists (data->file, NULL)); @@ -633,7 +636,6 @@ test_replace_load (void) g_main_loop_unref (data->loop); g_object_unref (data->file); g_free (data); - free (path); } static void -- 2.16.4 From 60017259cbb03810b5214bcbe185d749cead4e57 Mon Sep 17 00:00:00 2001 From: Matthias Clasen <mclasen@redhat.com> Date: Tue, 22 Jan 2019 13:26:31 -0500 Subject: keyfile settings: Use tighter permissions When creating directories, create them with 700 permissions, instead of 777. Closes: #1658 --- gio/gkeyfilesettingsbackend.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gio/gkeyfilesettingsbackend.c b/gio/gkeyfilesettingsbackend.c index a37978e..6bd9509 100644 --- a/gio/gkeyfilesettingsbackend.c +++ b/gio/gkeyfilesettingsbackend.c @@ -89,7 +89,8 @@ g_keyfile_settings_backend_keyfile_write (GKeyfileSettingsBackend *kfsb) contents = g_key_file_to_data (kfsb->keyfile, &length, NULL); g_file_replace_contents (kfsb->file, contents, length, NULL, FALSE, - G_FILE_CREATE_REPLACE_DESTINATION, + G_FILE_CREATE_REPLACE_DESTINATION | + G_FILE_CREATE_PRIVATE, NULL, NULL, NULL); compute_checksum (kfsb->digest, contents, length); @@ -640,7 +641,7 @@ g_keyfile_settings_backend_new (const gchar *filename, kfsb->file = g_file_new_for_path (filename); kfsb->dir = g_file_get_parent (kfsb->file); - g_file_make_directory_with_parents (kfsb->dir, NULL, NULL); + g_mkdir_with_parents(g_file_peek_path(kfsb->dir), 0700); kfsb->file_monitor = g_file_monitor (kfsb->file, 0, NULL, NULL); kfsb->dir_monitor = g_file_monitor (kfsb->dir, 0, NULL, NULL); -- 2.16.4
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor