diff options
author | Chen Qi <Qi.Chen@windriver.com> | 2021-04-25 16:44:00 +0800 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2021-05-04 22:57:50 +0100 |
commit | 80c76a82ec29d585fff9da914a4c5ff9279bd8cc (patch) | |
tree | d45f10c321683ddd2befa46c2bb8daad473fce4f /meta/recipes-core/glib-2.0 | |
parent | aa8618b6245d4910a323f198652983e39e3984fe (diff) | |
download | poky-80c76a82ec29d585fff9da914a4c5ff9279bd8cc.tar.gz |
glib-2.0: fix CVE-2021-28153
Backport patches to fix CVE-2021-28153.
(From OE-Core rev: 8a0aae46bc87c00fb4d32f6ce5567cc44cae6d34)
Signed-off-by: Chen Qi <Qi.Chen@windriver.com>
Signed-off-by: Anuj Mittal <anuj.mittal@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/recipes-core/glib-2.0')
6 files changed, 503 insertions, 0 deletions
diff --git a/meta/recipes-core/glib-2.0/glib-2.0/0001-glocalfileoutputstream-Fix-a-typo-in-a-comment.patch b/meta/recipes-core/glib-2.0/glib-2.0/0001-glocalfileoutputstream-Fix-a-typo-in-a-comment.patch new file mode 100644 index 0000000000..e3def1a980 --- /dev/null +++ b/meta/recipes-core/glib-2.0/glib-2.0/0001-glocalfileoutputstream-Fix-a-typo-in-a-comment.patch | |||
@@ -0,0 +1,32 @@ | |||
1 | From 48dd0d030a2b5240457472d40d8691b80bf5fa78 Mon Sep 17 00:00:00 2001 | ||
2 | From: Philip Withnall <pwithnall@endlessos.org> | ||
3 | Date: Wed, 24 Feb 2021 17:33:38 +0000 | ||
4 | Subject: [PATCH 1/5] glocalfileoutputstream: Fix a typo in a comment | ||
5 | |||
6 | Signed-off-by: Philip Withnall <pwithnall@endlessos.org> | ||
7 | |||
8 | CVE: CVE-2021-28153 | ||
9 | |||
10 | Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/glib/-/issues/2325] | ||
11 | |||
12 | Signed-off-by: Chen Qi <Qi.Chen@windriver.com> | ||
13 | --- | ||
14 | gio/glocalfileoutputstream.c | 2 +- | ||
15 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
16 | |||
17 | diff --git a/gio/glocalfileoutputstream.c b/gio/glocalfileoutputstream.c | ||
18 | index f34c3e4..e3d31d6 100644 | ||
19 | --- a/gio/glocalfileoutputstream.c | ||
20 | +++ b/gio/glocalfileoutputstream.c | ||
21 | @@ -854,7 +854,7 @@ handle_overwrite_open (const char *filename, | ||
22 | mode = mode_from_flags_or_info (flags, reference_info); | ||
23 | |||
24 | /* We only need read access to the original file if we are creating a backup. | ||
25 | - * We also add O_CREATE to avoid a race if the file was just removed */ | ||
26 | + * We also add O_CREAT to avoid a race if the file was just removed */ | ||
27 | if (create_backup || readable) | ||
28 | open_flags = O_RDWR | O_CREAT | O_BINARY; | ||
29 | else | ||
30 | -- | ||
31 | 2.17.1 | ||
32 | |||
diff --git a/meta/recipes-core/glib-2.0/glib-2.0/0002-tests-Stop-using-g_test_bug_base-in-file-tests.patch b/meta/recipes-core/glib-2.0/glib-2.0/0002-tests-Stop-using-g_test_bug_base-in-file-tests.patch new file mode 100644 index 0000000000..d8d4d51751 --- /dev/null +++ b/meta/recipes-core/glib-2.0/glib-2.0/0002-tests-Stop-using-g_test_bug_base-in-file-tests.patch | |||
@@ -0,0 +1,47 @@ | |||
1 | From 3d7f54ae4cfdddaf1a807879d9263e16cd12ffd3 Mon Sep 17 00:00:00 2001 | ||
2 | From: Philip Withnall <pwithnall@endlessos.org> | ||
3 | Date: Wed, 24 Feb 2021 17:34:32 +0000 | ||
4 | Subject: [PATCH 2/5] tests: Stop using g_test_bug_base() in file tests | ||
5 | MIME-Version: 1.0 | ||
6 | Content-Type: text/plain; charset=UTF-8 | ||
7 | Content-Transfer-Encoding: 8bit | ||
8 | |||
9 | Since a following commit is going to add a new test which references | ||
10 | Gitlab, so it’s best to move the URI bases inside the test cases. | ||
11 | |||
12 | Signed-off-by: Philip Withnall <pwithnall@endlessos.org> | ||
13 | |||
14 | CVE: CVE-2021-28153 | ||
15 | |||
16 | Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/glib/-/issues/2325] | ||
17 | |||
18 | Signed-off-by: Chen Qi <Qi.Chen@windriver.com> | ||
19 | --- | ||
20 | gio/tests/file.c | 4 +--- | ||
21 | 1 file changed, 1 insertion(+), 3 deletions(-) | ||
22 | |||
23 | diff --git a/gio/tests/file.c b/gio/tests/file.c | ||
24 | index d876965..39d51da 100644 | ||
25 | --- a/gio/tests/file.c | ||
26 | +++ b/gio/tests/file.c | ||
27 | @@ -686,7 +686,7 @@ test_replace_cancel (void) | ||
28 | guint count; | ||
29 | GError *error = NULL; | ||
30 | |||
31 | - g_test_bug ("629301"); | ||
32 | + g_test_bug ("https://bugzilla.gnome.org/629301"); | ||
33 | |||
34 | path = g_dir_make_tmp ("g_file_replace_cancel_XXXXXX", &error); | ||
35 | g_assert_no_error (error); | ||
36 | @@ -1785,8 +1785,6 @@ main (int argc, char *argv[]) | ||
37 | { | ||
38 | g_test_init (&argc, &argv, NULL); | ||
39 | |||
40 | - g_test_bug_base ("http://bugzilla.gnome.org/"); | ||
41 | - | ||
42 | g_test_add_func ("/file/basic", test_basic); | ||
43 | g_test_add_func ("/file/build-filename", test_build_filename); | ||
44 | g_test_add_func ("/file/parent", test_parent); | ||
45 | -- | ||
46 | 2.17.1 | ||
47 | |||
diff --git a/meta/recipes-core/glib-2.0/glib-2.0/0003-glocalfileoutputstream-Factor-out-a-flag-check.patch b/meta/recipes-core/glib-2.0/glib-2.0/0003-glocalfileoutputstream-Factor-out-a-flag-check.patch new file mode 100644 index 0000000000..425a1d402f --- /dev/null +++ b/meta/recipes-core/glib-2.0/glib-2.0/0003-glocalfileoutputstream-Factor-out-a-flag-check.patch | |||
@@ -0,0 +1,60 @@ | |||
1 | From 8cc84a2f8c668541aaba584cb9b73c98afeb8e2d Mon Sep 17 00:00:00 2001 | ||
2 | From: Philip Withnall <pwithnall@endlessos.org> | ||
3 | Date: Wed, 10 Mar 2021 16:05:55 +0000 | ||
4 | Subject: [PATCH 3/5] glocalfileoutputstream: Factor out a flag check | ||
5 | |||
6 | This clarifies the code a little. It introduces no functional changes. | ||
7 | |||
8 | Signed-off-by: Philip Withnall <pwithnall@endlessos.org> | ||
9 | |||
10 | CVE: CVE-2021-28153 | ||
11 | |||
12 | Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/glib/-/issues/2325] | ||
13 | |||
14 | Signed-off-by: Chen Qi <Qi.Chen@windriver.com> | ||
15 | --- | ||
16 | gio/glocalfileoutputstream.c | 7 ++++--- | ||
17 | 1 file changed, 4 insertions(+), 3 deletions(-) | ||
18 | |||
19 | diff --git a/gio/glocalfileoutputstream.c b/gio/glocalfileoutputstream.c | ||
20 | index e3d31d6..392d0b0 100644 | ||
21 | --- a/gio/glocalfileoutputstream.c | ||
22 | +++ b/gio/glocalfileoutputstream.c | ||
23 | @@ -850,6 +850,7 @@ handle_overwrite_open (const char *filename, | ||
24 | int res; | ||
25 | int mode; | ||
26 | int errsv; | ||
27 | + gboolean replace_destination_set = (flags & G_FILE_CREATE_REPLACE_DESTINATION); | ||
28 | |||
29 | mode = mode_from_flags_or_info (flags, reference_info); | ||
30 | |||
31 | @@ -960,7 +961,7 @@ handle_overwrite_open (const char *filename, | ||
32 | * to a backup file and rewrite the contents of the file. | ||
33 | */ | ||
34 | |||
35 | - if ((flags & G_FILE_CREATE_REPLACE_DESTINATION) || | ||
36 | + if (replace_destination_set || | ||
37 | (!(_g_stat_nlink (&original_stat) > 1) && !is_symlink)) | ||
38 | { | ||
39 | char *dirname, *tmp_filename; | ||
40 | @@ -979,7 +980,7 @@ handle_overwrite_open (const char *filename, | ||
41 | |||
42 | /* try to keep permissions (unless replacing) */ | ||
43 | |||
44 | - if ( ! (flags & G_FILE_CREATE_REPLACE_DESTINATION) && | ||
45 | + if (!replace_destination_set && | ||
46 | ( | ||
47 | #ifdef HAVE_FCHOWN | ||
48 | fchown (tmpfd, _g_stat_uid (&original_stat), _g_stat_gid (&original_stat)) == -1 || | ||
49 | @@ -1120,7 +1121,7 @@ handle_overwrite_open (const char *filename, | ||
50 | } | ||
51 | } | ||
52 | |||
53 | - if (flags & G_FILE_CREATE_REPLACE_DESTINATION) | ||
54 | + if (replace_destination_set) | ||
55 | { | ||
56 | g_close (fd, NULL); | ||
57 | |||
58 | -- | ||
59 | 2.17.1 | ||
60 | |||
diff --git a/meta/recipes-core/glib-2.0/glib-2.0/0004-glocalfileoutputstream-Fix-CREATE_REPLACE_DESTINATIO.patch b/meta/recipes-core/glib-2.0/glib-2.0/0004-glocalfileoutputstream-Fix-CREATE_REPLACE_DESTINATIO.patch new file mode 100644 index 0000000000..54a9f452d6 --- /dev/null +++ b/meta/recipes-core/glib-2.0/glib-2.0/0004-glocalfileoutputstream-Fix-CREATE_REPLACE_DESTINATIO.patch | |||
@@ -0,0 +1,294 @@ | |||
1 | From ed8f2235da7d2a408bfa18c1003f4a07f90b05e8 Mon Sep 17 00:00:00 2001 | ||
2 | From: Philip Withnall <pwithnall@endlessos.org> | ||
3 | Date: Wed, 24 Feb 2021 17:36:07 +0000 | ||
4 | Subject: [PATCH 4/5] glocalfileoutputstream: Fix CREATE_REPLACE_DESTINATION | ||
5 | with symlinks | ||
6 | MIME-Version: 1.0 | ||
7 | Content-Type: text/plain; charset=UTF-8 | ||
8 | Content-Transfer-Encoding: 8bit | ||
9 | |||
10 | The `G_FILE_CREATE_REPLACE_DESTINATION` flag is equivalent to unlinking | ||
11 | the destination file and re-creating it from scratch. That did | ||
12 | previously work, but in the process the code would call `open(O_CREAT)` | ||
13 | on the file. If the file was a dangling symlink, this would create the | ||
14 | destination file (empty). That’s not an intended side-effect, and has | ||
15 | security implications if the symlink is controlled by a lower-privileged | ||
16 | process. | ||
17 | |||
18 | Fix that by not opening the destination file if it’s a symlink, and | ||
19 | adjusting the rest of the code to cope with | ||
20 | - the fact that `fd == -1` is not an error iff `is_symlink` is true, | ||
21 | - and that `original_stat` will contain the `lstat()` results for the | ||
22 | symlink now, rather than the `stat()` results for its target (again, | ||
23 | iff `is_symlink` is true). | ||
24 | |||
25 | This means that the target of the dangling symlink is no longer created, | ||
26 | which was the bug. The symlink itself continues to be replaced (as | ||
27 | before) with the new file — this is the intended behaviour of | ||
28 | `g_file_replace()`. | ||
29 | |||
30 | The behaviour for non-symlink cases, or cases where the symlink was not | ||
31 | dangling, should be unchanged. | ||
32 | |||
33 | Includes a unit test. | ||
34 | |||
35 | Signed-off-by: Philip Withnall <pwithnall@endlessos.org> | ||
36 | |||
37 | Fixes: #2325 | ||
38 | |||
39 | CVE: CVE-2021-28153 | ||
40 | |||
41 | Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/glib/-/issues/2325] | ||
42 | |||
43 | Signed-off-by: Chen Qi <Qi.Chen@windriver.com> | ||
44 | --- | ||
45 | gio/glocalfileoutputstream.c | 77 ++++++++++++++++++------- | ||
46 | gio/tests/file.c | 108 +++++++++++++++++++++++++++++++++++ | ||
47 | 2 files changed, 163 insertions(+), 22 deletions(-) | ||
48 | |||
49 | diff --git a/gio/glocalfileoutputstream.c b/gio/glocalfileoutputstream.c | ||
50 | index 392d0b0..a2c7e3c 100644 | ||
51 | --- a/gio/glocalfileoutputstream.c | ||
52 | +++ b/gio/glocalfileoutputstream.c | ||
53 | @@ -878,16 +878,22 @@ handle_overwrite_open (const char *filename, | ||
54 | /* Could be a symlink, or it could be a regular ELOOP error, | ||
55 | * but then the next open will fail too. */ | ||
56 | is_symlink = TRUE; | ||
57 | - fd = g_open (filename, open_flags, mode); | ||
58 | + if (!replace_destination_set) | ||
59 | + fd = g_open (filename, open_flags, mode); | ||
60 | } | ||
61 | -#else | ||
62 | - fd = g_open (filename, open_flags, mode); | ||
63 | - errsv = errno; | ||
64 | +#else /* if !O_NOFOLLOW */ | ||
65 | /* This is racy, but we do it as soon as possible to minimize the race */ | ||
66 | is_symlink = g_file_test (filename, G_FILE_TEST_IS_SYMLINK); | ||
67 | + | ||
68 | + if (!is_symlink || !replace_destination_set) | ||
69 | + { | ||
70 | + fd = g_open (filename, open_flags, mode); | ||
71 | + errsv = errno; | ||
72 | + } | ||
73 | #endif | ||
74 | |||
75 | - if (fd == -1) | ||
76 | + if (fd == -1 && | ||
77 | + (!is_symlink || !replace_destination_set)) | ||
78 | { | ||
79 | char *display_name = g_filename_display_name (filename); | ||
80 | g_set_error (error, G_IO_ERROR, | ||
81 | @@ -898,15 +904,30 @@ handle_overwrite_open (const char *filename, | ||
82 | return -1; | ||
83 | } | ||
84 | |||
85 | - res = g_local_file_fstat (fd, | ||
86 | - G_LOCAL_FILE_STAT_FIELD_TYPE | | ||
87 | - G_LOCAL_FILE_STAT_FIELD_MODE | | ||
88 | - G_LOCAL_FILE_STAT_FIELD_UID | | ||
89 | - G_LOCAL_FILE_STAT_FIELD_GID | | ||
90 | - G_LOCAL_FILE_STAT_FIELD_MTIME | | ||
91 | - G_LOCAL_FILE_STAT_FIELD_NLINK, | ||
92 | - G_LOCAL_FILE_STAT_FIELD_ALL, &original_stat); | ||
93 | - errsv = errno; | ||
94 | + if (!is_symlink) | ||
95 | + { | ||
96 | + res = g_local_file_fstat (fd, | ||
97 | + G_LOCAL_FILE_STAT_FIELD_TYPE | | ||
98 | + G_LOCAL_FILE_STAT_FIELD_MODE | | ||
99 | + G_LOCAL_FILE_STAT_FIELD_UID | | ||
100 | + G_LOCAL_FILE_STAT_FIELD_GID | | ||
101 | + G_LOCAL_FILE_STAT_FIELD_MTIME | | ||
102 | + G_LOCAL_FILE_STAT_FIELD_NLINK, | ||
103 | + G_LOCAL_FILE_STAT_FIELD_ALL, &original_stat); | ||
104 | + errsv = errno; | ||
105 | + } | ||
106 | + else | ||
107 | + { | ||
108 | + res = g_local_file_lstat (filename, | ||
109 | + G_LOCAL_FILE_STAT_FIELD_TYPE | | ||
110 | + G_LOCAL_FILE_STAT_FIELD_MODE | | ||
111 | + G_LOCAL_FILE_STAT_FIELD_UID | | ||
112 | + G_LOCAL_FILE_STAT_FIELD_GID | | ||
113 | + G_LOCAL_FILE_STAT_FIELD_MTIME | | ||
114 | + G_LOCAL_FILE_STAT_FIELD_NLINK, | ||
115 | + G_LOCAL_FILE_STAT_FIELD_ALL, &original_stat); | ||
116 | + errsv = errno; | ||
117 | + } | ||
118 | |||
119 | if (res != 0) | ||
120 | { | ||
121 | @@ -923,16 +944,27 @@ handle_overwrite_open (const char *filename, | ||
122 | if (!S_ISREG (_g_stat_mode (&original_stat))) | ||
123 | { | ||
124 | if (S_ISDIR (_g_stat_mode (&original_stat))) | ||
125 | - g_set_error_literal (error, | ||
126 | - G_IO_ERROR, | ||
127 | - G_IO_ERROR_IS_DIRECTORY, | ||
128 | - _("Target file is a directory")); | ||
129 | - else | ||
130 | - g_set_error_literal (error, | ||
131 | + { | ||
132 | + g_set_error_literal (error, | ||
133 | + G_IO_ERROR, | ||
134 | + G_IO_ERROR_IS_DIRECTORY, | ||
135 | + _("Target file is a directory")); | ||
136 | + goto err_out; | ||
137 | + } | ||
138 | + else if (!is_symlink || | ||
139 | +#ifdef S_ISLNK | ||
140 | + !S_ISLNK (_g_stat_mode (&original_stat)) | ||
141 | +#else | ||
142 | + FALSE | ||
143 | +#endif | ||
144 | + ) | ||
145 | + { | ||
146 | + g_set_error_literal (error, | ||
147 | G_IO_ERROR, | ||
148 | G_IO_ERROR_NOT_REGULAR_FILE, | ||
149 | _("Target file is not a regular file")); | ||
150 | - goto err_out; | ||
151 | + goto err_out; | ||
152 | + } | ||
153 | } | ||
154 | |||
155 | if (etag != NULL) | ||
156 | @@ -1015,7 +1047,8 @@ handle_overwrite_open (const char *filename, | ||
157 | } | ||
158 | } | ||
159 | |||
160 | - g_close (fd, NULL); | ||
161 | + if (fd >= 0) | ||
162 | + g_close (fd, NULL); | ||
163 | *temp_filename = tmp_filename; | ||
164 | return tmpfd; | ||
165 | } | ||
166 | diff --git a/gio/tests/file.c b/gio/tests/file.c | ||
167 | index 39d51da..ddd1ffc 100644 | ||
168 | --- a/gio/tests/file.c | ||
169 | +++ b/gio/tests/file.c | ||
170 | @@ -805,6 +805,113 @@ test_replace_cancel (void) | ||
171 | g_object_unref (tmpdir); | ||
172 | } | ||
173 | |||
174 | +static void | ||
175 | +test_replace_symlink (void) | ||
176 | +{ | ||
177 | +#ifdef G_OS_UNIX | ||
178 | + gchar *tmpdir_path = NULL; | ||
179 | + GFile *tmpdir = NULL, *source_file = NULL, *target_file = NULL; | ||
180 | + GFileOutputStream *stream = NULL; | ||
181 | + const gchar *new_contents = "this is a test message which should be written to source and not target"; | ||
182 | + gsize n_written; | ||
183 | + GFileEnumerator *enumerator = NULL; | ||
184 | + GFileInfo *info = NULL; | ||
185 | + gchar *contents = NULL; | ||
186 | + gsize length = 0; | ||
187 | + GError *local_error = NULL; | ||
188 | + | ||
189 | + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/2325"); | ||
190 | + g_test_summary ("Test that G_FILE_CREATE_REPLACE_DESTINATION doesn’t follow symlinks"); | ||
191 | + | ||
192 | + /* Create a fresh, empty working directory. */ | ||
193 | + tmpdir_path = g_dir_make_tmp ("g_file_replace_symlink_XXXXXX", &local_error); | ||
194 | + g_assert_no_error (local_error); | ||
195 | + tmpdir = g_file_new_for_path (tmpdir_path); | ||
196 | + | ||
197 | + g_test_message ("Using temporary directory %s", tmpdir_path); | ||
198 | + g_free (tmpdir_path); | ||
199 | + | ||
200 | + /* Create symlink `source` which points to `target`. */ | ||
201 | + source_file = g_file_get_child (tmpdir, "source"); | ||
202 | + target_file = g_file_get_child (tmpdir, "target"); | ||
203 | + g_file_make_symbolic_link (source_file, "target", NULL, &local_error); | ||
204 | + g_assert_no_error (local_error); | ||
205 | + | ||
206 | + /* Ensure that `target` doesn’t exist */ | ||
207 | + g_assert_false (g_file_query_exists (target_file, NULL)); | ||
208 | + | ||
209 | + /* Replace the `source` symlink with a regular file using | ||
210 | + * %G_FILE_CREATE_REPLACE_DESTINATION, which should replace it *without* | ||
211 | + * following the symlink */ | ||
212 | + stream = g_file_replace (source_file, NULL, FALSE /* no backup */, | ||
213 | + G_FILE_CREATE_REPLACE_DESTINATION, NULL, &local_error); | ||
214 | + g_assert_no_error (local_error); | ||
215 | + | ||
216 | + g_output_stream_write_all (G_OUTPUT_STREAM (stream), new_contents, strlen (new_contents), | ||
217 | + &n_written, NULL, &local_error); | ||
218 | + g_assert_no_error (local_error); | ||
219 | + g_assert_cmpint (n_written, ==, strlen (new_contents)); | ||
220 | + | ||
221 | + g_output_stream_close (G_OUTPUT_STREAM (stream), NULL, &local_error); | ||
222 | + g_assert_no_error (local_error); | ||
223 | + | ||
224 | + g_clear_object (&stream); | ||
225 | + | ||
226 | + /* At this point, there should still only be one file: `source`. It should | ||
227 | + * now be a regular file. `target` should not exist. */ | ||
228 | + enumerator = g_file_enumerate_children (tmpdir, | ||
229 | + G_FILE_ATTRIBUTE_STANDARD_NAME "," | ||
230 | + G_FILE_ATTRIBUTE_STANDARD_TYPE, | ||
231 | + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, &local_error); | ||
232 | + g_assert_no_error (local_error); | ||
233 | + | ||
234 | + info = g_file_enumerator_next_file (enumerator, NULL, &local_error); | ||
235 | + g_assert_no_error (local_error); | ||
236 | + g_assert_nonnull (info); | ||
237 | + | ||
238 | + g_assert_cmpstr (g_file_info_get_name (info), ==, "source"); | ||
239 | + g_assert_cmpint (g_file_info_get_file_type (info), ==, G_FILE_TYPE_REGULAR); | ||
240 | + | ||
241 | + g_clear_object (&info); | ||
242 | + | ||
243 | + info = g_file_enumerator_next_file (enumerator, NULL, &local_error); | ||
244 | + g_assert_no_error (local_error); | ||
245 | + g_assert_null (info); | ||
246 | + | ||
247 | + g_file_enumerator_close (enumerator, NULL, &local_error); | ||
248 | + g_assert_no_error (local_error); | ||
249 | + g_clear_object (&enumerator); | ||
250 | + | ||
251 | + /* Double-check that `target` doesn’t exist */ | ||
252 | + g_assert_false (g_file_query_exists (target_file, NULL)); | ||
253 | + | ||
254 | + /* Check the content of `source`. */ | ||
255 | + g_file_load_contents (source_file, | ||
256 | + NULL, | ||
257 | + &contents, | ||
258 | + &length, | ||
259 | + NULL, | ||
260 | + &local_error); | ||
261 | + g_assert_no_error (local_error); | ||
262 | + g_assert_cmpstr (contents, ==, new_contents); | ||
263 | + g_assert_cmpuint (length, ==, strlen (new_contents)); | ||
264 | + g_free (contents); | ||
265 | + | ||
266 | + /* Tidy up. */ | ||
267 | + g_file_delete (source_file, NULL, &local_error); | ||
268 | + g_assert_no_error (local_error); | ||
269 | + | ||
270 | + g_file_delete (tmpdir, NULL, &local_error); | ||
271 | + g_assert_no_error (local_error); | ||
272 | + | ||
273 | + g_clear_object (&target_file); | ||
274 | + g_clear_object (&source_file); | ||
275 | + g_clear_object (&tmpdir); | ||
276 | +#else /* if !G_OS_UNIX */ | ||
277 | + g_test_skip ("Symlink replacement tests can only be run on Unix") | ||
278 | +#endif | ||
279 | +} | ||
280 | + | ||
281 | static void | ||
282 | on_file_deleted (GObject *object, | ||
283 | GAsyncResult *result, | ||
284 | @@ -1798,6 +1905,7 @@ main (int argc, char *argv[]) | ||
285 | g_test_add_data_func ("/file/async-create-delete/4096", GINT_TO_POINTER (4096), test_create_delete); | ||
286 | g_test_add_func ("/file/replace-load", test_replace_load); | ||
287 | g_test_add_func ("/file/replace-cancel", test_replace_cancel); | ||
288 | + g_test_add_func ("/file/replace-symlink", test_replace_symlink); | ||
289 | g_test_add_func ("/file/async-delete", test_async_delete); | ||
290 | g_test_add_func ("/file/copy-preserve-mode", test_copy_preserve_mode); | ||
291 | g_test_add_func ("/file/measure", test_measure); | ||
292 | -- | ||
293 | 2.17.1 | ||
294 | |||
diff --git a/meta/recipes-core/glib-2.0/glib-2.0/0005-glocalfileoutputstream-Add-a-missing-O_CLOEXEC-flag-.patch b/meta/recipes-core/glib-2.0/glib-2.0/0005-glocalfileoutputstream-Add-a-missing-O_CLOEXEC-flag-.patch new file mode 100644 index 0000000000..0ab9a750ab --- /dev/null +++ b/meta/recipes-core/glib-2.0/glib-2.0/0005-glocalfileoutputstream-Add-a-missing-O_CLOEXEC-flag-.patch | |||
@@ -0,0 +1,60 @@ | |||
1 | From ab4ee65fb5778964fa3cca9b3d6749711ef9ba19 Mon Sep 17 00:00:00 2001 | ||
2 | From: Philip Withnall <pwithnall@endlessos.org> | ||
3 | Date: Wed, 24 Feb 2021 17:42:24 +0000 | ||
4 | Subject: [PATCH 5/5] glocalfileoutputstream: Add a missing O_CLOEXEC flag to | ||
5 | replace() | ||
6 | |||
7 | Signed-off-by: Philip Withnall <pwithnall@endlessos.org> | ||
8 | |||
9 | CVE: CVE-2021-28153 | ||
10 | |||
11 | Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/glib/-/issues/2325] | ||
12 | |||
13 | Signed-off-by: Chen Qi <Qi.Chen@windriver.com> | ||
14 | --- | ||
15 | gio/glocalfileoutputstream.c | 15 ++++++++++++--- | ||
16 | 1 file changed, 12 insertions(+), 3 deletions(-) | ||
17 | |||
18 | diff --git a/gio/glocalfileoutputstream.c b/gio/glocalfileoutputstream.c | ||
19 | index a2c7e3c..4c512ea 100644 | ||
20 | --- a/gio/glocalfileoutputstream.c | ||
21 | +++ b/gio/glocalfileoutputstream.c | ||
22 | @@ -63,6 +63,12 @@ | ||
23 | #define O_BINARY 0 | ||
24 | #endif | ||
25 | |||
26 | +#ifndef O_CLOEXEC | ||
27 | +#define O_CLOEXEC 0 | ||
28 | +#else | ||
29 | +#define HAVE_O_CLOEXEC 1 | ||
30 | +#endif | ||
31 | + | ||
32 | struct _GLocalFileOutputStreamPrivate { | ||
33 | char *tmp_filename; | ||
34 | char *original_filename; | ||
35 | @@ -1239,7 +1245,7 @@ _g_local_file_output_stream_replace (const char *filename, | ||
36 | sync_on_close = FALSE; | ||
37 | |||
38 | /* If the file doesn't exist, create it */ | ||
39 | - open_flags = O_CREAT | O_EXCL | O_BINARY; | ||
40 | + open_flags = O_CREAT | O_EXCL | O_BINARY | O_CLOEXEC; | ||
41 | if (readable) | ||
42 | open_flags |= O_RDWR; | ||
43 | else | ||
44 | @@ -1269,8 +1275,11 @@ _g_local_file_output_stream_replace (const char *filename, | ||
45 | set_error_from_open_errno (filename, error); | ||
46 | return NULL; | ||
47 | } | ||
48 | - | ||
49 | - | ||
50 | +#if !defined(HAVE_O_CLOEXEC) && defined(F_SETFD) | ||
51 | + else | ||
52 | + fcntl (fd, F_SETFD, FD_CLOEXEC); | ||
53 | +#endif | ||
54 | + | ||
55 | stream = g_object_new (G_TYPE_LOCAL_FILE_OUTPUT_STREAM, NULL); | ||
56 | stream->priv->fd = fd; | ||
57 | stream->priv->sync_on_close = sync_on_close; | ||
58 | -- | ||
59 | 2.17.1 | ||
60 | |||
diff --git a/meta/recipes-core/glib-2.0/glib-2.0_2.66.7.bb b/meta/recipes-core/glib-2.0/glib-2.0_2.66.7.bb index 3909b76ddf..e5e65a4aad 100644 --- a/meta/recipes-core/glib-2.0/glib-2.0_2.66.7.bb +++ b/meta/recipes-core/glib-2.0/glib-2.0_2.66.7.bb | |||
@@ -50,6 +50,16 @@ SRC_URI += "\ | |||
50 | file://0028-gresource-Fix-a-pointer-mismatch-with-an-atomic-load.patch \ | 50 | file://0028-gresource-Fix-a-pointer-mismatch-with-an-atomic-load.patch \ |
51 | file://0029-docs-Document-not-to-use-volatile-qualifiers.patch \ | 51 | file://0029-docs-Document-not-to-use-volatile-qualifiers.patch \ |
52 | " | 52 | " |
53 | |||
54 | # Fix CVE-2021-28153 | ||
55 | SRC_URI += "\ | ||
56 | file://0001-glocalfileoutputstream-Fix-a-typo-in-a-comment.patch \ | ||
57 | file://0002-tests-Stop-using-g_test_bug_base-in-file-tests.patch \ | ||
58 | file://0003-glocalfileoutputstream-Factor-out-a-flag-check.patch \ | ||
59 | file://0004-glocalfileoutputstream-Fix-CREATE_REPLACE_DESTINATIO.patch \ | ||
60 | file://0005-glocalfileoutputstream-Add-a-missing-O_CLOEXEC-flag-.patch \ | ||
61 | " | ||
62 | |||
53 | SRC_URI_append_class-native = " file://relocate-modules.patch" | 63 | SRC_URI_append_class-native = " file://relocate-modules.patch" |
54 | 64 | ||
55 | SRC_URI[sha256sum] = "09f158769f6f26b31074e15b1ac80ec39b13b53102dfae66cfe826fb2cc65502" | 65 | SRC_URI[sha256sum] = "09f158769f6f26b31074e15b1ac80ec39b13b53102dfae66cfe826fb2cc65502" |