gdbus: Cope with sending fds in a message that takes multiple writes

Suppose we are sending a 5K message with fds (so data->blob points
to 5K of data, data->blob_size is 5K, and fd_list is non-null), but
the kernel is only accepting up to 4K with each sendmsg().

The first time we get into write_message_continue_writing(),
data->total_written will be 0. We will try to write the entire message,
plus the attached file descriptors; or if the stream doesn't support
fd-passing (not a socket), we need to fail with
"Tried sending a file descriptor on unsupported stream".

Because the kernel didn't accept the entire message, we come back in.
This time, we won't enter the Unix-specific block that involves sending
fds, because now data->total_written is 4K, and it would be wrong to try
to attach the same fds again. However, we also need to avoid failing
with "Tried sending a file descriptor on unsupported stream" in this
case. We just want to write out the data of the rest of the message,
starting from (blob + total_written) (in this exaple, the last 1K).

Resolves: https://gitlab.gnome.org/GNOME/glib/-/issues/2074
Signed-off-by: Simon McVittie <smcv@collabora.com>
This commit is contained in:
Simon McVittie 2020-10-28 11:04:47 +00:00 committed by Philip Withnall
parent cfbab734d1
commit 40cd84d9e4

View File

@ -1085,8 +1085,11 @@ write_message_continue_writing (MessageToWriteData *data)
else
{
#ifdef G_OS_UNIX
if (fd_list != NULL)
if (data->total_written == 0 && fd_list != NULL)
{
/* We were trying to write byte 0 of the message, which needs
* the fd list to be attached to it, but this connection doesn't
* support doing that. */
g_task_return_new_error (task,
G_IO_ERROR,
G_IO_ERROR_FAILED,