Merge ~whershberger/ubuntu/+source/glib2.0:ubuntu/noble-devel-lp2072586 into ubuntu/+source/glib2.0:ubuntu/noble-devel

Proposed by Wesley Hershberger
Status: Needs review
Proposed branch: ~whershberger/ubuntu/+source/glib2.0:ubuntu/noble-devel-lp2072586
Merge into: ubuntu/+source/glib2.0:ubuntu/noble-devel
Diff against target: 156 lines (+134/-0)
3 files modified
debian/changelog (+8/-0)
debian/patches/lp2072586-gfileutils-Preserve-mode-during-atomic-updates.patch (+125/-0)
debian/patches/series (+1/-0)
Reviewer Review Type Date Requested Status
Ubuntu Sponsors Pending
git-ubuntu import Pending
Review via email: mp+485047@code.launchpad.net

Commit message

gfileutils: Preserve mode during atomic file writes (LP: #2072586)

Description of the change

Backport 45a36e52

To post a comment you must log in.

Unmerged commits

46e0c19... by Wesley Hershberger

gfileutils: Preserve mode during atomic file writes (LP: #2072586)

* gfileutils: Preserve mode during atomic file writes to prevent high umask
  from rendering dconf database files unreadable (LP: #2072586).
  - d/p/lp2072586-gfileutils-Preserve-mode-during-atomic-updates.patch

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/debian/changelog b/debian/changelog
2index 4999ee8..e1645da 100644
3--- a/debian/changelog
4+++ b/debian/changelog
5@@ -1,3 +1,11 @@
6+glib2.0 (2.80.0-6ubuntu3.3) jammy; urgency=medium
7+
8+ * gfileutils: Preserve mode during atomic file writes to prevent high umask
9+ from rendering dconf database files unreadable (LP: #2072586).
10+ - d/p/lp2072586-gfileutils-Preserve-mode-during-atomic-updates.patch
11+
12+ -- Wesley Hershberger <wesley.hershberger@canonical.com> Fri, 25 Apr 2025 16:53:19 -0500
13+
14 glib2.0 (2.80.0-6ubuntu3.2) noble-security; urgency=medium
15
16 * SECURITY UPDATE: Buffer overflow
17diff --git a/debian/patches/lp2072586-gfileutils-Preserve-mode-during-atomic-updates.patch b/debian/patches/lp2072586-gfileutils-Preserve-mode-during-atomic-updates.patch
18new file mode 100644
19index 0000000..bc83847
20--- /dev/null
21+++ b/debian/patches/lp2072586-gfileutils-Preserve-mode-during-atomic-updates.patch
22@@ -0,0 +1,125 @@
23+From: Wesley Hershberger <wesley.hershberger@canonical.com>
24+Date: Tue, 22 Apr 2025 16:37:49 -0500
25+Subject: gfileutils: Preserve mode during atomic updates
26+
27+If g_file_set_contents{_full,} is replacing an existing file, require
28+that the tmpfile have the same mode as the existing file.
29+
30+This prevents the umask from taking effect for consistent writes to
31+existing files.
32+
33+Closes GNOME/dconf#76
34+
35+Bug: https://gitlab.gnome.org/GNOME/dconf/-/issues/76
36+Bug-Ubuntu: https://bugs.launchpad.net/bugs/2072586
37+Origin: upstream, https://gitlab.gnome.org/GNOME/glib/-/commit/45a36e52b570cf86ce2599b657e63a83d284cb46
38+---
39+ glib/gfileutils.c | 25 +++++++++++++++++++++++--
40+ glib/tests/fileutils.c | 14 ++++++++++----
41+ 2 files changed, 33 insertions(+), 6 deletions(-)
42+
43+diff --git a/glib/gfileutils.c b/glib/gfileutils.c
44+index 2801777..7811016 100644
45+--- a/glib/gfileutils.c
46++++ b/glib/gfileutils.c
47+@@ -1318,8 +1318,8 @@ g_file_set_contents (const gchar *filename,
48+ * to 7 characters to @filename.
49+ *
50+ * If the file didn’t exist before and is created, it will be given the
51+- * permissions from @mode. Otherwise, the permissions of the existing file may
52+- * be changed to @mode depending on @flags, or they may remain unchanged.
53++ * permissions from @mode. Otherwise, the permissions of the existing file will
54++ * remain unchanged.
55+ *
56+ * Returns: %TRUE on success, %FALSE if an error occurred
57+ *
58+@@ -1362,6 +1362,7 @@ g_file_set_contents_full (const gchar *filename,
59+ gboolean retval;
60+ int fd;
61+ gboolean do_fsync;
62++ GStatBuf old_stat;
63+
64+ tmp_filename = g_strdup_printf ("%s.XXXXXX", filename);
65+
66+@@ -1379,6 +1380,26 @@ g_file_set_contents_full (const gchar *filename,
67+ goto consistent_out;
68+ }
69+
70++ /* Maintain the permissions of the file if it exists */
71++ if (!g_stat (filename, &old_stat))
72++ {
73++#ifndef G_OS_WIN32
74++ if (fchmod (fd, old_stat.st_mode))
75++#else /* G_OS_WIN32 */
76++ if (chmod (tmp_filename, old_stat.st_mode))
77++#endif /* G_OS_WIN32 */
78++ {
79++ int saved_errno = errno;
80++ if (error)
81++ set_file_error (error,
82++ tmp_filename, _ ("Failed to set permissions of “%s”: %s"),
83++ saved_errno);
84++ g_unlink (tmp_filename);
85++ retval = FALSE;
86++ goto consistent_out;
87++ }
88++ }
89++
90+ do_fsync = fd_should_be_fsynced (fd, filename, flags);
91+ if (!write_to_file (contents, length, g_steal_fd (&fd), tmp_filename, do_fsync, error))
92+ {
93+diff --git a/glib/tests/fileutils.c b/glib/tests/fileutils.c
94+index 56be804..b7b77e1 100644
95+--- a/glib/tests/fileutils.c
96++++ b/glib/tests/fileutils.c
97+@@ -1686,7 +1686,9 @@ test_set_contents_full (void)
98+ EXISTING_FILE_DIRECTORY,
99+ }
100+ existing_file;
101+- int new_mode; /* only relevant if @existing_file is %EXISTING_FILE_NONE */
102++ /* only relevant if @existing_file is
103++ * %EXISTING_FILE_NONE or %EXISTING_FILE_REGULAR */
104++ int mode;
105+ gboolean use_strlen;
106+
107+ gboolean expected_success;
108+@@ -1697,6 +1699,8 @@ test_set_contents_full (void)
109+ { EXISTING_FILE_NONE, 0644, FALSE, TRUE, 0 },
110+ { EXISTING_FILE_NONE, 0644, TRUE, TRUE, 0 },
111+ { EXISTING_FILE_NONE, 0600, FALSE, TRUE, 0 },
112++ // Assume umask is 022, ensures that we preserve perms with, eg. 077
113++ { EXISTING_FILE_REGULAR, 0666, FALSE, TRUE, 0 },
114+ { EXISTING_FILE_REGULAR, 0644, FALSE, TRUE, 0 },
115+ #ifndef G_OS_WIN32
116+ { EXISTING_FILE_SYMLINK, 0644, FALSE, TRUE, 0 },
117+@@ -1741,6 +1745,8 @@ test_set_contents_full (void)
118+ g_assert_no_errno (g_fsync (fd));
119+ close (fd);
120+
121++ g_assert_no_errno (chmod (file_name, tests[i].mode));
122++
123+ #ifndef G_OS_WIN32
124+ /* Pass an existing symlink to g_file_set_contents_full() to see
125+ * what it does. */
126+@@ -1784,7 +1790,7 @@ test_set_contents_full (void)
127+ /* Set the file contents */
128+ ret = g_file_set_contents_full (set_contents_name, "b",
129+ tests[i].use_strlen ? -1 : 1,
130+- flags, tests[i].new_mode, &error);
131++ flags, tests[i].mode, &error);
132+
133+ if (!tests[i].expected_success)
134+ {
135+@@ -1808,10 +1814,10 @@ test_set_contents_full (void)
136+
137+ g_assert_no_errno (g_lstat (set_contents_name, &statbuf));
138+
139+- if (tests[i].existing_file == EXISTING_FILE_NONE)
140++ if (tests[i].existing_file & (EXISTING_FILE_NONE | EXISTING_FILE_REGULAR))
141+ {
142+ int mode = statbuf.st_mode & ~S_IFMT;
143+- int new_mode = tests[i].new_mode;
144++ int new_mode = tests[i].mode;
145+ #ifdef G_OS_WIN32
146+ /* on windows, group and others perms handling is different */
147+ /* only check the rwx user permissions */
148diff --git a/debian/patches/series b/debian/patches/series
149index 2deb54b..5d89fd6 100644
150--- a/debian/patches/series
151+++ b/debian/patches/series
152@@ -38,3 +38,4 @@ CVE-2024-34397-15.patch
153 CVE-2024-34397-16.patch
154 CVE-2024-34397-regression.patch
155 CVE-2024-52533.patch
156+lp2072586-gfileutils-Preserve-mode-during-atomic-updates.patch

Subscribers

People subscribed via source and target branches