public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
From: Adrian Vovk <avovk@redhat.com>
To: git-commits@fedoraproject.org
Subject: [rpms/gvfs] f43: Fix CVE-2026-842{67..70}
Date: Tue, 01 Sep 2026 23:09:48 GMT [thread overview]
Message-ID: <178830418829.1.4210013193695481846.rpms-gvfs-7be53a6f52bb@fedoraproject.org> (raw)
A new commit has been pushed.
Repo : rpms/gvfs
Branch : f43
Commit : 7be53a6f52bb35b4086f8bdaa37d480848236e94
Author : Adrian Vovk <avovk@redhat.com>
Date : 2026-09-01T19:05:57-04:00
Stats : +630/-0 in 5 file(s)
URL : https://src.fedoraproject.org/rpms/gvfs/c/7be53a6f52bb35b4086f8bdaa37d480848236e94?branch=f43
Log:
Fix CVE-2026-842{67..70}
---
diff --git a/CVE-2026-84267.patch b/CVE-2026-84267.patch
new file mode 100644
index 0000000..27d5e34
--- /dev/null
+++ b/CVE-2026-84267.patch
@@ -0,0 +1,100 @@
+From 015bf91450370a0717b91742feeb8f22e8b0243e Mon Sep 17 00:00:00 2001
+From: Ondrej Holy <oholy@redhat.com>
+Date: Mon, 27 Jul 2026 12:42:57 +0200
+Subject: [PATCH] sftp: Validate that reads fully complete before using data
+
+Currently, several places in the SFTP backend use `g_input_stream_read_all()`
+without checking that the requested number of bytes was actually read. A short
+read leaves parts of the allocated buffer uninitialised, which can lead to
+use of invalid data. Let's verify that `bytes_read` matches the expected length
+and treat short reads as protocol errors.
+
+Fixes: https://gitlab.gnome.org/GNOME/gvfs/-/issues/861
+
+Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
+---
+ daemon/gvfsbackendsftp.c | 22 ++++++++++++++++------
+ 1 file changed, 16 insertions(+), 6 deletions(-)
+
+diff --git a/daemon/gvfsbackendsftp.c b/daemon/gvfsbackendsftp.c
+index c7e738ae..c834d9af 100644
+--- a/daemon/gvfsbackendsftp.c
++++ b/daemon/gvfsbackendsftp.c
+@@ -741,8 +741,11 @@ read_reply_sync (Connection *conn, gsize *len_out, GError **error)
+
+ if (!g_input_stream_read_all (conn->reply_stream,
+ array->data, len,
+- &bytes_read, NULL, error))
++ &bytes_read, NULL, NULL) ||
++ bytes_read != len)
+ {
++ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
++ _("Invalid reply received"));
+ g_byte_array_free (array, TRUE);
+ return NULL;
+ }
+@@ -779,6 +782,7 @@ read_string (GDataInputStream *stream, gsize *len_out)
+ guint32 len;
+ char *data;
+ GError *error;
++ gsize bytes_read;
+
+ error = NULL;
+ len = g_data_input_stream_read_uint32 (stream, NULL, &error);
+@@ -790,7 +794,8 @@ read_string (GDataInputStream *stream, gsize *len_out)
+
+ data = g_malloc (len + 1);
+
+- if (!g_input_stream_read_all (G_INPUT_STREAM (stream), data, len, NULL, NULL, NULL))
++ if (!g_input_stream_read_all (G_INPUT_STREAM (stream), data, len, &bytes_read, NULL, NULL) ||
++ bytes_read != len)
+ {
+ g_free (data);
+ return NULL;
+@@ -2869,7 +2874,8 @@ read_reply (GVfsBackendSftp *backend,
+ {
+ SftpHandle *handle;
+ guint32 count;
+-
++ gsize bytes_read;
++
+ handle = user_data;
+
+ if (reply_type == SSH_FXP_STATUS)
+@@ -2890,13 +2896,14 @@ read_reply (GVfsBackendSftp *backend,
+
+ if (!g_input_stream_read_all (G_INPUT_STREAM (reply),
+ G_VFS_JOB_READ (job)->buffer, count,
+- NULL, NULL, NULL))
++ &bytes_read, NULL, NULL) ||
++ bytes_read != count)
+ {
+ g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_FAILED,
+ _("Invalid reply received"));
+ return;
+ }
+-
++
+ handle->offset += count;
+
+ g_vfs_job_read_set_size (G_VFS_JOB_READ (job), count);
+@@ -6649,12 +6656,15 @@ pull_read_reply (GVfsBackendSftp *backend,
+ }
+ else
+ {
++ gsize bytes_read;
++
+ request->response_len = g_data_input_stream_read_uint32 (reply, NULL, NULL);
+ request->buffer = g_slice_alloc (request->response_len);
+
+ if (g_input_stream_read_all (G_INPUT_STREAM (reply),
+ request->buffer, request->response_len,
+- NULL, NULL, NULL))
++ &bytes_read, NULL, NULL) &&
++ bytes_read == request->response_len)
+ {
+ handle->queued_writes = g_list_append (handle->queued_writes, request);
+ pull_try_start_write (handle);
+--
+GitLab
+
diff --git a/CVE-2026-84268.patch b/CVE-2026-84268.patch
new file mode 100644
index 0000000..e99fa6f
--- /dev/null
+++ b/CVE-2026-84268.patch
@@ -0,0 +1,33 @@
+From ea1322daab1979b30cf96b3e39ed6db5e45fc041 Mon Sep 17 00:00:00 2001
+From: Ondrej Holy <oholy@redhat.com>
+Date: Mon, 22 Jun 2026 16:21:54 +0200
+Subject: [PATCH] sftp: Clamp `read_reply` count to requested buffer size
+
+Currently, the `count` value from the server response is used
+as the read length without checking it against
+`bytes_requested`. A buggy server returning a larger count
+would overflow the job buffer. Let's clamp `count` to
+`bytes_requested`.
+
+Fixes: https://gitlab.gnome.org/GNOME/gvfs/-/issues/862
+
+Made-with: Cursor
+---
+ daemon/gvfsbackendsftp.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/daemon/gvfsbackendsftp.c b/daemon/gvfsbackendsftp.c
+index 5696cf31..cb288b9e 100644
+--- a/daemon/gvfsbackendsftp.c
++++ b/daemon/gvfsbackendsftp.c
+@@ -2862,6 +2862,7 @@ read_reply (GVfsBackendSftp *backend,
+ }
+
+ count = g_data_input_stream_read_uint32 (reply, NULL, NULL);
++ count = MIN (count, G_VFS_JOB_READ (job)->bytes_requested);
+
+ if (!g_input_stream_read_all (G_INPUT_STREAM (reply),
+ G_VFS_JOB_READ (job)->buffer, count,
+--
+GitLab
+
diff --git a/CVE-2026-84269.patch b/CVE-2026-84269.patch
new file mode 100644
index 0000000..d63713c
--- /dev/null
+++ b/CVE-2026-84269.patch
@@ -0,0 +1,452 @@
+From 81525b2c917950554255784542674222bfee797d Mon Sep 17 00:00:00 2001
+From: Ondrej Holy <oholy@redhat.com>
+Date: Mon, 27 Jul 2026 15:26:42 +0200
+Subject: [PATCH] afp: Validate reply size in DSI read reply handling
+
+Currently, a DSI read reply with `totalDataLength` larger than the
+requested `ReqCount` causes a heap buffer overflow of the pre-sized
+`reply_buf`. Let's validate the reply size and return an "Invalid reply
+received" error. The oversized data is skipped from the stream to
+maintain DSI framing for subsequent operations.
+
+Fixes: https://gitlab.gnome.org/GNOME/gvfs/-/issues/863
+
+Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
+---
+ daemon/gvfsafpconnection.c | 167 +++++++++++++++++++++++++++++++++++--
+ daemon/gvfsafpconnection.h | 1 +
+ daemon/gvfsafpserver.c | 4 +-
+ daemon/gvfsafpvolume.c | 35 ++++----
+ 4 files changed, 180 insertions(+), 27 deletions(-)
+
+diff --git a/daemon/gvfsafpconnection.c b/daemon/gvfsafpconnection.c
+index a275038b..2c1e38e9 100644
+--- a/daemon/gvfsafpconnection.c
++++ b/daemon/gvfsafpconnection.c
+@@ -711,6 +711,8 @@ typedef struct
+
+ GVfsAfpCommand *command;
+ char *reply_buf;
++ gsize reply_buf_size;
++ GError *error;
+ GTask *task;
+
+ GVfsAfpConnection *conn;
+@@ -769,6 +771,7 @@ free_request_data (RequestData *req_data)
+ {
+ if (req_data->command)
+ g_object_unref (req_data->command);
++ g_clear_error (&req_data->error);
+ if (req_data->task)
+ g_object_unref (req_data->task);
+
+@@ -962,6 +965,97 @@ read_all_finish (GInputStream *stream,
+ return g_task_propagate_boolean (G_TASK (res), error);
+ }
+
++typedef struct
++{
++ gsize count;
++ gsize bytes_skipped;
++} SkipAllData;
++
++static void
++free_skip_all_data (SkipAllData *skip_data)
++{
++ g_slice_free (SkipAllData, skip_data);
++}
++
++static void skip_all_async (GInputStream *stream,
++ gsize count,
++ int io_priority,
++ GCancellable *cancellable,
++ GAsyncReadyCallback callback,
++ gpointer user_data);
++
++static void
++skip_all_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
++{
++ GInputStream *stream = G_INPUT_STREAM (source_object);
++ GTask *task = G_TASK (user_data);
++ gssize bytes_skipped;
++ GError *err = NULL;
++ SkipAllData *skip_data = g_task_get_task_data (task);
++
++ bytes_skipped = g_input_stream_skip_finish (stream, res, &err);
++ if (bytes_skipped == -1)
++ {
++ g_task_return_error (task, err);
++ g_object_unref (task);
++ return;
++ }
++ else if (bytes_skipped == 0)
++ {
++ g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_CLOSED, _("Got EOS"));
++ g_object_unref (task);
++ return;
++ }
++
++ skip_data->bytes_skipped += bytes_skipped;
++ if (skip_data->bytes_skipped < skip_data->count)
++ {
++ g_input_stream_skip_async (stream,
++ skip_data->count - skip_data->bytes_skipped,
++ g_task_get_priority (task), g_task_get_cancellable (task),
++ skip_all_cb, task);
++ return;
++ }
++
++ g_task_return_boolean (task, TRUE);
++ g_object_unref (task);
++}
++
++static void
++skip_all_async (GInputStream *stream,
++ gsize count,
++ int io_priority,
++ GCancellable *cancellable,
++ GAsyncReadyCallback callback,
++ gpointer user_data)
++{
++ SkipAllData *skip_data;
++ GTask *task;
++
++ task = g_task_new (stream, cancellable, callback, user_data);
++ g_task_set_source_tag (task, skip_all_async);
++ g_task_set_priority (task, io_priority);
++
++ skip_data = g_slice_new0 (SkipAllData);
++ skip_data->count = count;
++
++ g_task_set_task_data (task, skip_data, (GDestroyNotify)free_skip_all_data);
++
++ g_input_stream_skip_async (stream, count, io_priority, cancellable,
++ skip_all_cb, task);
++}
++
++static gboolean
++skip_all_finish (GInputStream *stream,
++ GAsyncResult *res,
++ GError **error)
++{
++ g_return_val_if_fail (g_task_is_valid (res, stream), FALSE);
++ g_return_val_if_fail (g_async_result_is_tagged (res, skip_all_async), FALSE);
++
++ return g_task_propagate_boolean (G_TASK (res), error);
++}
++
+ static void
+ dispatch_reply (GVfsAfpConnection *afp_connection)
+ {
+@@ -1017,13 +1111,20 @@ dispatch_reply (GVfsAfpConnection *afp_connection)
+ GUINT_TO_POINTER ((guint)dsi_header->requestID));
+ if (req_data)
+ {
+- GVfsAfpReply *reply;
++ if (req_data->error)
++ {
++ g_task_return_error (req_data->task, g_steal_pointer (&req_data->error));
++ }
++ else
++ {
++ GVfsAfpReply *reply;
+
+- reply = g_vfs_afp_reply_new (dsi_header->errorCode, priv->reply_buf,
+- dsi_header->totalDataLength, priv->free_reply_buf);
+- priv->free_reply_buf = FALSE;
++ reply = g_vfs_afp_reply_new (dsi_header->errorCode, priv->reply_buf,
++ dsi_header->totalDataLength, priv->free_reply_buf);
++ priv->free_reply_buf = FALSE;
+
+- g_task_return_pointer (req_data->task, reply, g_object_unref);
++ g_task_return_pointer (req_data->task, reply, g_object_unref);
++ }
+
+ g_hash_table_remove (priv->request_hash,
+ GUINT_TO_POINTER ((guint)dsi_header->requestID));
+@@ -1036,6 +1137,43 @@ dispatch_reply (GVfsAfpConnection *afp_connection)
+ }
+ }
+
++static void
++skip_data_cb (GObject *object, GAsyncResult *res, gpointer user_data)
++{
++ GInputStream *input = G_INPUT_STREAM (object);
++ GVfsAfpConnection *afp_connection = G_VFS_AFP_CONNECTION (user_data);
++ GVfsAfpConnectionPrivate *priv = afp_connection->priv;
++
++ gboolean result;
++ GError *err = NULL;
++
++ if (g_atomic_int_get (&priv->atomic_state) == STATE_PENDING_CLOSE)
++ {
++ if (!priv->send_loop_running)
++ close_connection (afp_connection);
++ return;
++ }
++
++ result = skip_all_finish (input, res, &err);
++ if (!result)
++ {
++ if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CLOSED) ||
++ g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CONNECTION_CLOSED))
++ {
++ g_message (_("Host closed connection"));
++ }
++ else
++ {
++ g_warning ("FAIL!!! \"%s\"\n", err->message);
++ }
++ exit (0);
++ }
++
++ dispatch_reply (afp_connection);
++
++ read_reply (afp_connection);
++}
++
+ static void
+ read_data_cb (GObject *object, GAsyncResult *res, gpointer user_data)
+ {
+@@ -1124,8 +1262,19 @@ read_dsi_header_cb (GObject *object, GAsyncResult *res, gpointer user_data)
+ GUINT_TO_POINTER ((guint)dsi_header->requestID));
+ if (req_data && req_data->reply_buf)
+ {
+- priv->reply_buf = req_data->reply_buf;
+- priv->free_reply_buf = FALSE;
++ if (dsi_header->totalDataLength > req_data->reply_buf_size)
++ {
++ g_set_error (&req_data->error,
++ G_IO_ERROR, G_IO_ERROR_FAILED,
++ _("Invalid reply received"));
++ skip_all_async (input, dsi_header->totalDataLength, 0,
++ priv->read_cancellable, skip_data_cb,
++ afp_conn);
++ return;
++ }
++
++ priv->reply_buf = req_data->reply_buf;
++ priv->free_reply_buf = FALSE;
+ }
+ else
+ {
+@@ -1448,6 +1597,7 @@ void
+ g_vfs_afp_connection_send_command (GVfsAfpConnection *afp_connection,
+ GVfsAfpCommand *command,
+ char *reply_buf,
++ gsize reply_buf_size,
+ GAsyncReadyCallback callback,
+ GCancellable *cancellable,
+ gpointer user_data)
+@@ -1471,6 +1621,7 @@ g_vfs_afp_connection_send_command (GVfsAfpConnection *afp_connection,
+ req_data->type = REQUEST_TYPE_COMMAND;
+ req_data->command = g_object_ref (command);
+ req_data->reply_buf = reply_buf;
++ req_data->reply_buf_size = reply_buf_size;
+ req_data->conn = afp_connection;
+ req_data->task = task;
+
+@@ -1616,7 +1767,7 @@ g_vfs_afp_connection_send_command_sync (GVfsAfpConnection *afp_connection,
+
+ sync_data_init (&sync_data, afp_connection, NULL);
+
+- g_vfs_afp_connection_send_command (afp_connection, command, NULL,
++ g_vfs_afp_connection_send_command (afp_connection, command, NULL, 0,
+ send_command_sync_cb, cancellable, &sync_data);
+
+ sync_data_wait (&sync_data);
+diff --git a/daemon/gvfsafpconnection.h b/daemon/gvfsafpconnection.h
+index df26e0a7..44d2ffa5 100644
+--- a/daemon/gvfsafpconnection.h
++++ b/daemon/gvfsafpconnection.h
+@@ -364,6 +364,7 @@ GVfsAfpReply* g_vfs_afp_connection_send_command_finish (GVfsAfpConnection *
+ void g_vfs_afp_connection_send_command (GVfsAfpConnection *afp_connection,
+ GVfsAfpCommand *command,
+ char *reply_buf,
++ gsize reply_buf_size,
+ GAsyncReadyCallback callback,
+ GCancellable *cancellable,
+ gpointer user_data);
+diff --git a/daemon/gvfsafpserver.c b/daemon/gvfsafpserver.c
+index a3ab24ca..00cdd890 100644
+--- a/daemon/gvfsafpserver.c
++++ b/daemon/gvfsafpserver.c
+@@ -1384,7 +1384,7 @@ g_vfs_afp_server_get_volumes (GVfsAfpServer *server,
+
+ task = g_task_new (server, cancellable, callback, user_data);
+ g_task_set_source_tag (task, g_vfs_afp_server_get_volumes);
+- g_vfs_afp_connection_send_command (server->priv->conn, comm, NULL, get_volumes_cb,
++ g_vfs_afp_connection_send_command (server->priv->conn, comm, NULL, 0, get_volumes_cb,
+ cancellable, task);
+ }
+
+@@ -1778,7 +1778,7 @@ g_vfs_afp_server_map_id (GVfsAfpServer *server,
+ g_task_set_source_tag (task, g_vfs_afp_server_map_id);
+ g_task_set_task_data (task, GINT_TO_POINTER (map_function), NULL);
+
+- g_vfs_afp_connection_send_command (priv->conn, comm, NULL,
++ g_vfs_afp_connection_send_command (priv->conn, comm, NULL, 0,
+ map_id_cb, cancellable, task);
+ g_object_unref (comm);
+ }
+diff --git a/daemon/gvfsafpvolume.c b/daemon/gvfsafpvolume.c
+index c1b3537a..34cf69fa 100644
+--- a/daemon/gvfsafpvolume.c
++++ b/daemon/gvfsafpvolume.c
+@@ -313,7 +313,7 @@ g_vfs_afp_volume_get_parms (GVfsAfpVolume *volume,
+ task = g_task_new (volume, cancellable, callback, user_data);
+ g_task_set_source_tag (task, g_vfs_afp_volume_get_parms);
+
+- g_vfs_afp_connection_send_command (priv->conn, comm, NULL, get_vol_parms_cb,
++ g_vfs_afp_connection_send_command (priv->conn, comm, NULL, 0, get_vol_parms_cb,
+ cancellable, task);
+ g_object_unref (comm);
+ }
+@@ -486,7 +486,7 @@ g_vfs_afp_volume_open_fork (GVfsAfpVolume *volume,
+ task = g_task_new (volume, cancellable, callback, user_data);
+ g_task_set_source_tag (task, g_vfs_afp_volume_open_fork);
+
+- g_vfs_afp_connection_send_command (priv->conn, comm, NULL,
++ g_vfs_afp_connection_send_command (priv->conn, comm, NULL, 0,
+ open_fork_cb, cancellable, task);
+ g_object_unref (comm);
+ }
+@@ -597,7 +597,7 @@ g_vfs_afp_volume_close_fork (GVfsAfpVolume *volume,
+ task = g_task_new (volume, cancellable, callback, user_data);
+ g_task_set_source_tag (task, g_vfs_afp_volume_close_fork);
+
+- g_vfs_afp_connection_send_command (priv->conn, comm, NULL,
++ g_vfs_afp_connection_send_command (priv->conn, comm, NULL, 0,
+ close_fork_cb, cancellable, task);
+ g_object_unref (comm);
+ }
+@@ -727,7 +727,7 @@ g_vfs_afp_volume_delete (GVfsAfpVolume *volume,
+ task = g_task_new (volume, cancellable, callback, user_data);
+ g_task_set_source_tag (task, g_vfs_afp_volume_delete);
+
+- g_vfs_afp_connection_send_command (priv->conn, comm, NULL,
++ g_vfs_afp_connection_send_command (priv->conn, comm, NULL, 0,
+ delete_cb, cancellable, task);
+ g_object_unref (comm);
+ }
+@@ -871,7 +871,7 @@ create_file_get_filedir_parms_cb (GObject *source_object, GAsyncResult *res, gpo
+ g_vfs_afp_command_put_pathname (comm, basename);
+ g_free (basename);
+
+- g_vfs_afp_connection_send_command (priv->conn, comm, NULL, create_file_cb,
++ g_vfs_afp_connection_send_command (priv->conn, comm, NULL, 0, create_file_cb,
+ g_task_get_cancellable (task), task);
+ g_object_unref (comm);
+ }
+@@ -1050,7 +1050,7 @@ create_directory_get_filedir_parms_cb (GObject *source_object, GAsyncResult *res
+ /* Pathname */
+ g_vfs_afp_command_put_pathname (comm, cdd->basename);
+
+- g_vfs_afp_connection_send_command (volume->priv->conn, comm, NULL, make_directory_cb,
++ g_vfs_afp_connection_send_command (volume->priv->conn, comm, NULL, 0, make_directory_cb,
+ g_task_get_cancellable (task), task);
+ g_object_unref (comm);
+ }
+@@ -1240,7 +1240,7 @@ rename_get_filedir_parms_cb (GObject *source_object,
+ /* NewName */
+ g_vfs_afp_command_put_pathname (comm, rd->new_name);
+
+- g_vfs_afp_connection_send_command (volume->priv->conn, comm, NULL, rename_cb,
++ g_vfs_afp_connection_send_command (volume->priv->conn, comm, NULL, 0, rename_cb,
+ g_task_get_cancellable (task), task);
+ g_object_unref (comm);
+ }
+@@ -1433,7 +1433,7 @@ g_vfs_afp_volume_move_and_rename (GVfsAfpVolume *volume,
+ task = g_task_new (volume, cancellable, callback, user_data);
+ g_task_set_source_tag (task, g_vfs_afp_volume_move_and_rename);
+
+- g_vfs_afp_connection_send_command (priv->conn, comm, NULL,
++ g_vfs_afp_connection_send_command (priv->conn, comm, NULL, 0,
+ move_and_rename_cb, cancellable, task);
+ g_object_unref (comm);
+ }
+@@ -1588,7 +1588,7 @@ g_vfs_afp_volume_copy_file (GVfsAfpVolume *volume,
+ task = g_task_new (volume, cancellable, callback, user_data);
+ g_task_set_source_tag (task, g_vfs_afp_volume_copy_file);
+
+- g_vfs_afp_connection_send_command (priv->conn, comm, NULL,
++ g_vfs_afp_connection_send_command (priv->conn, comm, NULL, 0,
+ copy_file_cb, cancellable, task);
+ g_object_unref (comm);
+ }
+@@ -1735,7 +1735,7 @@ g_vfs_afp_volume_get_filedir_parms (GVfsAfpVolume *volume,
+ task = g_task_new (volume, cancellable, callback, user_data);
+ g_task_set_source_tag (task, g_vfs_afp_volume_get_filedir_parms);
+
+- g_vfs_afp_connection_send_command (priv->conn, comm, NULL,
++ g_vfs_afp_connection_send_command (priv->conn, comm, NULL, 0,
+ get_filedir_parms_cb, cancellable,
+ task);
+ g_object_unref (comm);
+@@ -1855,7 +1855,7 @@ g_vfs_afp_volume_get_fork_parms (GVfsAfpVolume *volume,
+ task = g_task_new (volume, cancellable, callback, user_data);
+ g_task_set_source_tag (task, g_vfs_afp_volume_get_fork_parms);
+
+- g_vfs_afp_connection_send_command (priv->conn, comm, NULL,
++ g_vfs_afp_connection_send_command (priv->conn, comm, NULL, 0,
+ get_fork_parms_cb, cancellable,
+ task);
+ g_object_unref (comm);
+@@ -1978,7 +1978,7 @@ g_vfs_afp_volume_set_fork_size (GVfsAfpVolume *volume,
+ task = g_task_new (volume, cancellable, callback, user_data);
+ g_task_set_source_tag (task, g_vfs_afp_volume_set_fork_size);
+
+- g_vfs_afp_connection_send_command (priv->conn, comm, NULL,
++ g_vfs_afp_connection_send_command (priv->conn, comm, NULL, 0,
+ set_fork_parms_cb, cancellable, task);
+ g_object_unref (comm);
+ }
+@@ -2117,7 +2117,7 @@ g_vfs_afp_volume_set_unix_privs (GVfsAfpVolume *volume,
+ task = g_task_new (volume, cancellable, callback, user_data);
+ g_task_set_source_tag (task, g_vfs_afp_volume_set_unix_privs);
+
+- g_vfs_afp_connection_send_command (priv->conn, comm, NULL,
++ g_vfs_afp_connection_send_command (priv->conn, comm, NULL, 0,
+ set_unix_privs_cb, cancellable, task);
+ g_object_unref (comm);
+ }
+@@ -2336,7 +2336,7 @@ g_vfs_afp_volume_enumerate (GVfsAfpVolume *volume,
+ /* Pathname */
+ g_vfs_afp_command_put_pathname (comm, directory);
+
+- g_vfs_afp_connection_send_command (priv->conn, comm, NULL,
++ g_vfs_afp_connection_send_command (priv->conn, comm, NULL, 0,
+ enumerate_cb, cancellable, task);
+ g_object_unref (comm);
+ }
+@@ -2471,7 +2471,7 @@ g_vfs_afp_volume_exchange_files (GVfsAfpVolume *volume,
+ task = g_task_new (volume, cancellable, callback, user_data);
+ g_task_set_source_tag (task, g_vfs_afp_volume_exchange_files);
+
+- g_vfs_afp_connection_send_command (priv->conn, comm, NULL,
++ g_vfs_afp_connection_send_command (priv->conn, comm, NULL, 0,
+ close_replace_exchange_files_cb,
+ cancellable, task);
+ g_object_unref (comm);
+@@ -2604,7 +2604,7 @@ g_vfs_afp_volume_write_to_fork (GVfsAfpVolume *volume,
+ task = g_task_new (volume, cancellable, callback, user_data);
+ g_task_set_source_tag (task, g_vfs_afp_volume_write_to_fork);
+
+- g_vfs_afp_connection_send_command (volume->priv->conn, comm, NULL,
++ g_vfs_afp_connection_send_command (volume->priv->conn, comm, NULL, 0,
+ write_ext_cb, cancellable, task);
+ g_object_unref (comm);
+ }
+@@ -2730,7 +2730,8 @@ g_vfs_afp_volume_read_from_fork (GVfsAfpVolume *volume,
+ g_task_set_source_tag (task, g_vfs_afp_volume_read_from_fork);
+
+ g_vfs_afp_connection_send_command (volume->priv->conn, comm, buffer,
+- read_ext_cb, cancellable, task);
++ req_count, read_ext_cb, cancellable,
++ task);
+ g_object_unref (comm);
+ }
+
+--
+GitLab
+
diff --git a/CVE-2026-84270.patch b/CVE-2026-84270.patch
new file mode 100644
index 0000000..aa207a0
--- /dev/null
+++ b/CVE-2026-84270.patch
@@ -0,0 +1,40 @@
+From 25add8b5103384c7edc8ad74722ed93eb3f6f077 Mon Sep 17 00:00:00 2001
+From: Ondrej Holy <oholy@redhat.com>
+Date: Mon, 27 Jul 2026 15:38:21 +0200
+Subject: [PATCH] mtp: Validate read size returned by device
+
+Currently, `do_read` copies `actual` bytes from the device response
+into `buffer` without checking that `actual` does not exceed
+`bytes_requested`. If the device returns more data than requested,
+this causes a heap buffer overflow. Let's validate the size and
+return an "Invalid reply received" error instead.
+
+Fixes: https://gitlab.gnome.org/GNOME/gvfs/-/issues/864
+
+Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
+---
+ daemon/gvfsbackendmtp.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/daemon/gvfsbackendmtp.c b/daemon/gvfsbackendmtp.c
+index 9a8ac502..f2a26adf 100644
+--- a/daemon/gvfsbackendmtp.c
++++ b/daemon/gvfsbackendmtp.c
+@@ -2575,6 +2575,14 @@ do_read (GVfsBackend *backend,
+ goto exit;
+ }
+
++ if (actual > bytes_requested) {
++ free (temp);
++ g_vfs_job_failed_literal (G_VFS_JOB (job),
++ G_IO_ERROR, G_IO_ERROR_FAILED,
++ _("Invalid reply received"));
++ goto exit;
++ }
++
+ memcpy (buffer, temp, actual);
+ free (temp);
+ } else {
+--
+GitLab
+
diff --git a/gvfs.spec b/gvfs.spec
index 4f0e8ea..8c6d29f 100644
--- a/gvfs.spec
+++ b/gvfs.spec
@@ -30,6 +30,11 @@ License: LGPL-2.0-or-later AND GPL-3.0-only AND MPL-2.0 AND BSD-3-Clause-Sun
URL: https://wiki.gnome.org/Projects/gvfs
Source0: https://download.gnome.org/sources/gvfs/1.58/gvfs-%{version}.tar.xz
+Patch0: CVE-2026-84268.patch
+Patch1: CVE-2026-84270.patch
+Patch2: CVE-2026-84269.patch
+Patch3: CVE-2026-84267.patch
+
BuildRequires: meson
BuildRequires: gcc
BuildRequires: pkgconfig(glib-2.0) >= %{glib2_version}
reply other threads:[~2026-09-01 23:09 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=178830418829.1.4210013193695481846.rpms-gvfs-7be53a6f52bb@fedoraproject.org \
--to=avovk@redhat.com \
--cc=git-commits@fedoraproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox