icera: avoid highly unlikely use of already unref-ed bearer
In the connection and disconnection sequences, we make sure that the Bearer object is valid by keeping a reference in the Dial3gppContext and Disconnect3gppContext (actually, another one kept by the GSimpleAsyncResult as well). But we are considering here the case where the context is completed and freed by an unsolicited message handler before we get the reply to the AT command, so to properly ensure that the bearer object is still valid when we try to check if the context is in the priv struct, we need to keep an extra ref around.
This commit is contained in:
@@ -345,6 +345,10 @@ disconnect_ipdpact_ready (MMBaseModem *modem,
|
|||||||
/* Try to recover the disconnection context. If none found, it means the
|
/* Try to recover the disconnection context. If none found, it means the
|
||||||
* context was already completed and we have nothing else to do. */
|
* context was already completed and we have nothing else to do. */
|
||||||
ctx = self->priv->disconnect_pending;
|
ctx = self->priv->disconnect_pending;
|
||||||
|
|
||||||
|
/* Balance refcount with the extra ref we passed to command_full() */
|
||||||
|
g_object_unref (self);
|
||||||
|
|
||||||
if (!ctx) {
|
if (!ctx) {
|
||||||
mm_dbg ("Disconnection context was finished already by an unsolicited message");
|
mm_dbg ("Disconnection context was finished already by an unsolicited message");
|
||||||
|
|
||||||
@@ -407,7 +411,7 @@ disconnect_3gpp (MMBroadbandBearer *bearer,
|
|||||||
FALSE,
|
FALSE,
|
||||||
NULL, /* cancellable */
|
NULL, /* cancellable */
|
||||||
(GAsyncReadyCallback)disconnect_ipdpact_ready,
|
(GAsyncReadyCallback)disconnect_ipdpact_ready,
|
||||||
ctx->self); /* we pass the bearer object! */
|
g_object_ref (ctx->self)); /* we pass the bearer object! */
|
||||||
g_free (command);
|
g_free (command);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -680,6 +684,10 @@ activate_ready (MMBaseModem *modem,
|
|||||||
/* Try to recover the connection context. If none found, it means the
|
/* Try to recover the connection context. If none found, it means the
|
||||||
* context was already completed and we have nothing else to do. */
|
* context was already completed and we have nothing else to do. */
|
||||||
ctx = self->priv->connect_pending;
|
ctx = self->priv->connect_pending;
|
||||||
|
|
||||||
|
/* Balance refcount with the extra ref we passed to command_full() */
|
||||||
|
g_object_unref (self);
|
||||||
|
|
||||||
if (!ctx) {
|
if (!ctx) {
|
||||||
mm_dbg ("Connection context was finished already by an unsolicited message");
|
mm_dbg ("Connection context was finished already by an unsolicited message");
|
||||||
|
|
||||||
@@ -743,7 +751,7 @@ deactivate_ready (MMBaseModem *modem,
|
|||||||
FALSE,
|
FALSE,
|
||||||
NULL, /* cancellable */
|
NULL, /* cancellable */
|
||||||
(GAsyncReadyCallback)activate_ready,
|
(GAsyncReadyCallback)activate_ready,
|
||||||
ctx->self); /* we pass the bearer object! */
|
g_object_ref (ctx->self)); /* we pass the bearer object! */
|
||||||
g_free (command);
|
g_free (command);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user