cache file removal (bsc#1258307 CVE-2026-2604 glgo#GNOME/evolution-data-server#627). OBS-URL: https://build.opensuse.org/package/show/GNOME:Factory/evolution-data-server?expand=0&rev=488
173 lines
7.8 KiB
Diff
173 lines
7.8 KiB
Diff
From afa12b6ba502e5acaa431415aa3b939ddb377382 Mon Sep 17 00:00:00 2001
|
|
From: Milan Crha <mcrha@redhat.com>
|
|
Date: Mon, 16 Feb 2026 18:20:34 +0100
|
|
Subject: [PATCH] I#627 - Canonicalize path before local cache file removal
|
|
|
|
Closes https://gitlab.gnome.org/GNOME/evolution-data-server/-/issues/627
|
|
---
|
|
.../backends/file/e-book-backend-file.c | 2 +-
|
|
.../libedata-book/e-book-meta-backend.c | 2 +-
|
|
src/calendar/libedata-cal/e-cal-cache.c | 2 +-
|
|
src/libedataserver/e-data-server-util.c | 42 ++++++++++++++++++
|
|
src/libedataserver/e-data-server-util.h | 2 +
|
|
tests/libedataserver/libedataserver-test.c | 43 +++++++++++++++++++
|
|
6 files changed, 90 insertions(+), 3 deletions(-)
|
|
|
|
diff -urp evolution-data-server-3.58.3.orig/src/addressbook/backends/file/e-book-backend-file.c evolution-data-server-3.58.3/src/addressbook/backends/file/e-book-backend-file.c
|
|
--- evolution-data-server-3.58.3.orig/src/addressbook/backends/file/e-book-backend-file.c 2026-02-23 13:52:32.688903333 -0600
|
|
+++ evolution-data-server-3.58.3/src/addressbook/backends/file/e-book-backend-file.c 2026-02-23 14:07:47.807663557 -0600
|
|
@@ -392,7 +392,7 @@ maybe_delete_uri (EBookBackendFile *bf,
|
|
/* If the file is in our path it belongs to us and we need to delete it.
|
|
*/
|
|
if (bf->priv->photo_dirname &&
|
|
- !strncmp (bf->priv->photo_dirname, filename, strlen (bf->priv->photo_dirname))) {
|
|
+ e_util_filename_is_in_path (filename, bf->priv->photo_dirname)) {
|
|
|
|
d (g_print ("Deleting uri file: %s\n", filename));
|
|
|
|
diff -urp evolution-data-server-3.58.3.orig/src/addressbook/libedata-book/e-book-meta-backend.c evolution-data-server-3.58.3/src/addressbook/libedata-book/e-book-meta-backend.c
|
|
--- evolution-data-server-3.58.3.orig/src/addressbook/libedata-book/e-book-meta-backend.c 2026-02-23 13:52:32.702903481 -0600
|
|
+++ evolution-data-server-3.58.3/src/addressbook/libedata-book/e-book-meta-backend.c 2026-02-23 14:07:47.808137174 -0600
|
|
@@ -586,7 +586,7 @@ ebmb_gather_photos_local_filenames (EBoo
|
|
gchar *filename;
|
|
|
|
filename = g_filename_from_uri (url, NULL, NULL);
|
|
- if (filename && g_str_has_prefix (filename, cache_path))
|
|
+ if (filename && e_util_filename_is_in_path (filename, cache_path))
|
|
filenames = g_slist_prepend (filenames, filename);
|
|
else
|
|
g_free (filename);
|
|
diff -urp evolution-data-server-3.58.3.orig/src/calendar/libedata-cal/e-cal-cache.c evolution-data-server-3.58.3/src/calendar/libedata-cal/e-cal-cache.c
|
|
--- evolution-data-server-3.58.3.orig/src/calendar/libedata-cal/e-cal-cache.c 2026-02-23 13:52:32.722903693 -0600
|
|
+++ evolution-data-server-3.58.3/src/calendar/libedata-cal/e-cal-cache.c 2026-02-23 14:07:47.808526161 -0600
|
|
@@ -3707,7 +3707,7 @@ e_cal_cache_delete_attachments (ECalCach
|
|
if (!cache_dirname)
|
|
cache_dirname = g_path_get_dirname (e_cache_get_filename (E_CACHE (cal_cache)));
|
|
|
|
- if (g_str_has_prefix (filename, cache_dirname) &&
|
|
+ if (e_util_filename_is_in_path (filename, cache_dirname) &&
|
|
g_unlink (filename) == -1) {
|
|
/* Ignore these errors */
|
|
}
|
|
diff -urp evolution-data-server-3.58.3.orig/src/libedataserver/e-data-server-util.c evolution-data-server-3.58.3/src/libedataserver/e-data-server-util.c
|
|
--- evolution-data-server-3.58.3.orig/src/libedataserver/e-data-server-util.c 2026-02-23 13:52:32.784904350 -0600
|
|
+++ evolution-data-server-3.58.3/src/libedataserver/e-data-server-util.c 2026-02-23 14:07:47.809739409 -0600
|
|
@@ -3152,3 +3152,45 @@ e_util_guess_source_is_readonly (ESource
|
|
|
|
return res;
|
|
}
|
|
+
|
|
+/**
|
|
+ * e_util_filename_is_in_path:
|
|
+ * @filename: a filename
|
|
+ * @path: an expected path
|
|
+ *
|
|
+ * Checks whether the @filename is stored under @path.
|
|
+ * It use canonicalized form of the paths before comparing them.
|
|
+ * Both the @filename and @path are expected to be absolute paths,
|
|
+ * is not, %FALSE is returned.
|
|
+ *
|
|
+ * Returns: whether the @filename is stored under @path
|
|
+ *
|
|
+ * Since: 3.60
|
|
+ **/
|
|
+gboolean
|
|
+e_util_filename_is_in_path (const gchar *filename,
|
|
+ const gchar *path)
|
|
+{
|
|
+ gchar *canon_filename, *canon_path;
|
|
+ gsize path_len;
|
|
+ gboolean res;
|
|
+
|
|
+ g_return_val_if_fail (filename != NULL, FALSE);
|
|
+ g_return_val_if_fail (path != NULL, FALSE);
|
|
+
|
|
+ if (!g_path_is_absolute (filename) ||
|
|
+ !g_path_is_absolute (path))
|
|
+ return FALSE;
|
|
+
|
|
+ canon_filename = g_canonicalize_filename (filename, NULL);
|
|
+ canon_path = g_canonicalize_filename (path, NULL);
|
|
+ path_len = strlen (canon_path);
|
|
+
|
|
+ res = path_len > 0 && g_str_has_prefix (canon_filename, canon_path) &&
|
|
+ canon_filename[path_len] == G_DIR_SEPARATOR;
|
|
+
|
|
+ g_free (canon_filename);
|
|
+ g_free (canon_path);
|
|
+
|
|
+ return res;
|
|
+}
|
|
diff -urp evolution-data-server-3.58.3.orig/src/libedataserver/e-data-server-util.h evolution-data-server-3.58.3/src/libedataserver/e-data-server-util.h
|
|
--- evolution-data-server-3.58.3.orig/src/libedataserver/e-data-server-util.h 2026-02-23 13:52:32.784904350 -0600
|
|
+++ evolution-data-server-3.58.3/src/libedataserver/e-data-server-util.h 2026-02-23 14:09:07.455490246 -0600
|
|
@@ -265,6 +265,8 @@ void e_util_change_uri_port (GUri **in
|
|
gint port);
|
|
void e_util_call_malloc_trim (void);
|
|
gboolean e_util_guess_source_is_readonly (struct _ESource *source);
|
|
+gboolean e_util_filename_is_in_path (const gchar *filename,
|
|
+ const gchar *path);
|
|
|
|
G_END_DECLS
|
|
|
|
diff -urp evolution-data-server-3.58.3.orig/tests/libedataserver/libedataserver-test.c evolution-data-server-3.58.3/tests/libedataserver/libedataserver-test.c
|
|
--- evolution-data-server-3.58.3.orig/tests/libedataserver/libedataserver-test.c 2026-02-23 13:52:32.825904785 -0600
|
|
+++ evolution-data-server-3.58.3/tests/libedataserver/libedataserver-test.c 2026-02-23 14:07:47.810198389 -0600
|
|
@@ -119,6 +119,43 @@ test_parse_date (ETestServerFixture *fix
|
|
}
|
|
}
|
|
|
|
+static void
|
|
+test_filename_is_in_path (ETestServerFixture *fixture,
|
|
+ gconstpointer user_data)
|
|
+{
|
|
+ struct _tests {
|
|
+ const gchar *filename;
|
|
+ const gchar *path;
|
|
+ gboolean expected;
|
|
+ } tests[] = {
|
|
+ { "/home/user/.cache/dir/", "/home/user/.cache/dir", FALSE },
|
|
+ { "/home/user/.cache/dir", "/home/user/.cache/dir", FALSE },
|
|
+ { "/home/user/.cache/dir", "/home/user/.cache/dir/", FALSE },
|
|
+ { "/home/user/.cache/dir/", "/home/user/.cache/dir/", FALSE },
|
|
+ { "/home/user/.cache/dir/file.txt", "/home/user/.cache/dir/", TRUE },
|
|
+ { "/home/user/.cache/dir/file.txt", "/home/user/.cache/dir", TRUE },
|
|
+ { "/home/user/.cache/dir/subdir/file.txt", "/home/user/.cache/dir/", TRUE },
|
|
+ { "/home/user/.cache/dir/subdir/file.txt", "/home/user/.cache/dir", TRUE },
|
|
+ { "/home/user/.cache/dir/./file.txt", "/home/user/.cache/dir/", TRUE },
|
|
+ { "/home/user/.cache/dir/./file.txt", "/home/user/.cache/dir", TRUE },
|
|
+ { "/home/user/.cache/dir/../file.txt", "/home/user/.cache/dir/", FALSE },
|
|
+ { "/home/user/.cache/dir/../file.txt", "/home/user/.cache/dir", FALSE },
|
|
+ { "/home/user/.cache/dir/.././dir/../../.cache/./dir/file.txt", "/home/user/.cache/dir/", TRUE },
|
|
+ { "/home/user/.cache/dir/.././dir/../../.cache/./dir/file.txt", "/home/user/.cache/dir", TRUE },
|
|
+ { "/home/user/.cache/dir/../../../../var/lib/file.txt", "/home/user/.cache/dir/", FALSE },
|
|
+ { "/home/user/.cache/dir/../../../../var/lib/file.txt", "/home/user/.cache/dir", FALSE },
|
|
+ { "./file.txt", "/home/user/.cache/dir", FALSE },
|
|
+ { "../file.txt", "/home/user/.cache/dir", FALSE }
|
|
+ };
|
|
+ gint ii;
|
|
+
|
|
+ for (ii = 0; ii < G_N_ELEMENTS (tests); ii++) {
|
|
+ gboolean result = e_util_filename_is_in_path (tests[ii].filename, tests[ii].path);
|
|
+
|
|
+ g_assert_cmpint ((result ? 1 : 0), ==, (tests[ii].expected ? 1 : 0));
|
|
+ }
|
|
+}
|
|
+
|
|
gint
|
|
main (gint argc,
|
|
gchar **argv)
|
|
@@ -138,6 +175,12 @@ main (gint argc,
|
|
e_test_server_utils_setup,
|
|
test_parse_date,
|
|
e_test_server_utils_teardown);
|
|
+ g_test_add (
|
|
+ "/libedataserver-test/FilenameIsInPath",
|
|
+ ETestServerFixture, &test_closure,
|
|
+ e_test_server_utils_setup,
|
|
+ test_filename_is_in_path,
|
|
+ e_test_server_utils_teardown);
|
|
|
|
return e_test_server_utils_run (argc, argv);
|
|
}
|