summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Chan <benchan@chromium.org>2018-06-28 13:49:27 -0700
committerAleksander Morgado <aleksander@aleksander.es>2018-07-06 11:45:40 +0200
commita67b993d1d2df869aa762da45dcd33e136f69ec4 (patch)
treed969056c6595420676bec8b6823ce02ebf88afca
parented457a700b3977699dc52660d1e7b21da4709181 (diff)
libqmi-glib,device: avoid closing same file descriptor twice
The GUnixInputStream and GUnixOutputStream object created in create_iostream_with_fd() references the same file descriptor and are both set to close the file descriptor when the stream is closed. That leads to the same file descriptor being closed twice, which isn't desirable. This patch addresses the issue by having the QmiDevice object to keep track of the file descriptor and close it, which avoids any potential race condition in the future. The issue was observed by Eric Caruso <ejcaruso@chromium.org> (cherry picked from commit a445e35393e66c3d7b8b6c12cbb11546cab733a9)
-rw-r--r--src/libqmi-glib/qmi-device.c19
1 files changed, 13 insertions, 6 deletions
diff --git a/src/libqmi-glib/qmi-device.c b/src/libqmi-glib/qmi-device.c
index 2bf6a40..c793171 100644
--- a/src/libqmi-glib/qmi-device.c
+++ b/src/libqmi-glib/qmi-device.c
@@ -107,6 +107,7 @@ struct _QmiDevicePrivate {
GArray *supported_services;
/* I/O stream, set when the file is open */
+ gint fd;
GInputStream *istream;
GOutputStream *ostream;
GSource *input_source;
@@ -125,6 +126,8 @@ struct _QmiDevicePrivate {
#define BUFFER_SIZE 2048
+static void destroy_iostream (QmiDevice *self);
+
/*****************************************************************************/
/* Message transactions (private) */
@@ -1603,10 +1606,7 @@ setup_iostream (GTask *task)
/* Check in/out streams */
if (!self->priv->istream || !self->priv->ostream) {
- g_clear_object (&self->priv->istream);
- g_clear_object (&self->priv->ostream);
- g_clear_object (&self->priv->socket_connection);
- g_clear_object (&self->priv->socket_client);
+ destroy_iostream (self);
g_task_return_new_error (task,
QMI_CORE_ERROR,
QMI_CORE_ERROR_FAILED,
@@ -1649,8 +1649,10 @@ create_iostream_with_fd (GTask *task)
return;
}
- self->priv->istream = g_unix_input_stream_new (fd, TRUE);
- self->priv->ostream = g_unix_output_stream_new (fd, TRUE);
+ g_assert (self->priv->fd < 0);
+ self->priv->fd = fd;
+ self->priv->istream = g_unix_input_stream_new (fd, FALSE);
+ self->priv->ostream = g_unix_output_stream_new (fd, FALSE);
setup_iostream (task);
}
@@ -2417,6 +2419,10 @@ destroy_iostream (QmiDevice *self)
g_clear_object (&self->priv->ostream);
g_clear_object (&self->priv->socket_connection);
g_clear_object (&self->priv->socket_client);
+ if (self->priv->fd >= 0) {
+ close (self->priv->fd);
+ self->priv->fd = -1;
+ }
}
#if defined MBIM_QMUX_ENABLED
@@ -3016,6 +3022,7 @@ qmi_device_init (QmiDevice *self)
NULL,
g_object_unref);
self->priv->proxy_path = g_strdup (QMI_PROXY_SOCKET_PATH);
+ self->priv->fd = -1;
}
static gboolean