summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Chan <benchan@chromium.org>2018-06-28 13:49:27 -0700
committerBen Chan <benchan@chromium.org>2018-06-28 14:06:21 -0700
commita445e35393e66c3d7b8b6c12cbb11546cab733a9 (patch)
treea9357d6509abddf04c321a08078d0ab43ee29aa3
parent9dd7e78db6eb59dd2d66617a0121d6a80cd6932d (diff)
downloadlibqmi-a445e35393e66c3d7b8b6c12cbb11546cab733a9.tar.gz
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>
-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 2bf6a400..c7931718 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