[PATCH] serial-port: fail open/reopen after a serial port is disposed
Ben Chan
benchan at chromium.org
Tue Dec 17 13:48:07 PST 2013
After a MMSerialPort object is disposed and closed, it may be opened again.
That could potentially lead to a crash if data_available is called after
the MMSerialPort object is finalized. This patch prevents such a
scenario by failing mm_serial_port_open / mm_serial_port_reopen on an
already disposed MMSerialPort object.
---
Dan / Aleksander,
The code shouldn't really call open/reopen on an already disposed MMSerialPort,
I wonder if we should use g_assert (!priv->disposed) instead of reporting an
error. That would allow us to pin point the source of the problem more easily.
How do you think?
Thanks,
Ben
src/mm-serial-port.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/src/mm-serial-port.c b/src/mm-serial-port.c
index 545e707..d3361d2 100644
--- a/src/mm-serial-port.c
+++ b/src/mm-serial-port.c
@@ -70,6 +70,7 @@ static guint signals[LAST_SIGNAL] = { 0 };
typedef struct {
guint32 open_count;
+ gboolean disposed;
gboolean forced_close;
int fd;
GHashTable *reply_cache;
@@ -875,6 +876,15 @@ mm_serial_port_open (MMSerialPort *self, GError **error)
priv = MM_SERIAL_PORT_GET_PRIVATE (self);
device = mm_port_get_device (MM_PORT (self));
+ if (priv->disposed) {
+ g_set_error (error,
+ MM_SERIAL_ERROR,
+ MM_SERIAL_ERROR_OPEN_FAILED,
+ "Could not open serial device %s: it is being disposed",
+ device);
+ return FALSE;
+ }
+
if (priv->reopen_id) {
g_set_error (error,
MM_SERIAL_ERROR,
@@ -1293,6 +1303,17 @@ mm_serial_port_reopen (MMSerialPort *self,
g_return_val_if_fail (MM_IS_SERIAL_PORT (self), FALSE);
priv = MM_SERIAL_PORT_GET_PRIVATE (self);
+ if (priv->disposed) {
+ GError *error;
+
+ error = g_error_new_literal (MM_CORE_ERROR,
+ MM_CORE_ERROR_FAILED,
+ "Serial port is being disposed.");
+ callback (self, error, user_data);
+ g_error_free (error);
+ return FALSE;
+ }
+
if (priv->reopen_id > 0) {
GError *error;
@@ -1691,6 +1712,9 @@ dispose (GObject *object)
serial_port_reopen_cancel (MM_SERIAL_PORT (object));
mm_serial_port_flash_cancel (MM_SERIAL_PORT (object));
+ /* Mark the serial port as disposed to fail subsequent attempts to open/reopen the port. */
+ priv->disposed = TRUE;
+
G_OBJECT_CLASS (mm_serial_port_parent_class)->dispose (object);
}
--
1.8.5.1
More information about the ModemManager-devel
mailing list