diff options
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" |
