Hi,
On 05/11/2017 11:50 AM, Pau Espin Pedrol wrote:
Fixes following issue announced by valgrind:
ofonod[2870]: plugins/gobi.c:shutdown_cb()
ofonod[2870]: src/modem.c:modem_change_state() old state: 0, new state: 0
==2870== Invalid read of size 8
==2870== at 0x453ADE: shutdown_destroy (qmi.c:1254)
==2870== by 0x508A717: ??? (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4200.1)
==2870== by 0x508DB8B: g_main_context_dispatch (in
/lib/x86_64-linux-gnu/libglib-2.0.so.0.4200.1)
==2870== by 0x508DF47: ??? (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4200.1)
==2870== by 0x508E271: g_main_loop_run (in
/lib/x86_64-linux-gnu/libglib-2.0.so.0.4200.1)
==2870== by 0x4C680B: main (main.c:256)
==2870== Address 0x6a07518 is 152 bytes inside a block of size 168 free'd
==2870== at 0x4C29E90: free (vg_replace_malloc.c:473)
==2870== by 0x4532FF: qmi_device_unref (qmi.c:1003)
==2870== by 0x45E09B: shutdown_cb (gobi.c:120)
==2870== by 0x453B68: shutdown_callback (qmi.c:1268)
==2870== by 0x508E612: ??? (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4200.1)
==2870== by 0x508DB6C: g_main_context_dispatch (in
/lib/x86_64-linux-gnu/libglib-2.0.so.0.4200.1)
==2870== by 0x508DF47: ??? (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4200.1)
==2870== by 0x508E271: g_main_loop_run (in
/lib/x86_64-linux-gnu/libglib-2.0.so.0.4200.1)
==2870== by 0x4C680B: main (main.c:256)
==2870==
==2870== Invalid write of size 4
==2870== at 0x453B09: shutdown_destroy (qmi.c:1257)
==2870== by 0x508A717: ??? (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4200.1)
==2870== by 0x508DB8B: g_main_context_dispatch (in
/lib/x86_64-linux-gnu/libglib-2.0.so.0.4200.1)
==2870== by 0x508DF47: ??? (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4200.1)
==2870== by 0x508E271: g_main_loop_run (in
/lib/x86_64-linux-gnu/libglib-2.0.so.0.4200.1)
==2870== by 0x4C680B: main (main.c:256)
==2870== Address 0x6a07520 is 160 bytes inside a block of size 168 free'd
==2870== at 0x4C29E90: free (vg_replace_malloc.c:473)
==2870== by 0x4532FF: qmi_device_unref (qmi.c:1003)
==2870== by 0x45E09B: shutdown_cb (gobi.c:120)
==2870== by 0x453B68: shutdown_callback (qmi.c:1268)
==2870== by 0x508E612: ??? (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4200.1)
==2870== by 0x508DB6C: g_main_context_dispatch (in
/lib/x86_64-linux-gnu/libglib-2.0.so.0.4200.1)
==2870== by 0x508DF47: ??? (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4200.1)
==2870== by 0x508E271: g_main_loop_run (in
/lib/x86_64-linux-gnu/libglib-2.0.so.0.4200.1)
==2870== by 0x4C680B: main (main.c:256)
==2870==
---
drivers/qmimodem/qmi.c | 3 ++-
plugins/gobi.c | 2 +-
2 files changed, 3 insertions(+), 2 deletions(-)
Please refer to our patch submission guidelines, see HACKING,
'Submitting patches'.
diff --git a/drivers/qmimodem/qmi.c b/drivers/qmimodem/qmi.c
index 80c6adef..07daee9b 100644
--- a/drivers/qmimodem/qmi.c
+++ b/drivers/qmimodem/qmi.c
@@ -1251,10 +1251,11 @@ static void shutdown_destroy(gpointer user_data)
{
struct qmi_device *device = user_data;
+ device->shutdown_source = 0;
+
if (device->shutdown_destroy)
device->shutdown_destroy(device->shutdown_user_data);
- device->shutdown_source = 0;
}
static gboolean shutdown_callback(gpointer user_data)
diff --git a/plugins/gobi.c b/plugins/gobi.c
index a4985990..44c9c3ec 100644
--- a/plugins/gobi.c
+++ b/plugins/gobi.c
@@ -132,7 +132,7 @@ static void shutdown_device(struct ofono_modem *modem)
qmi_service_unref(data->dms);
data->dms = NULL;
- qmi_device_shutdown(data->device, shutdown_cb, modem, NULL);
+ qmi_device_shutdown(data->device, NULL, modem, shutdown_cb);
Semantically this is quite wrong. The destroy callback is used if the
user data has been newly allocated. It should be NULL otherwise. The
next time someone goes to use this API (in a semantically usual way),
the bug will again appear.
Anyway, the sequence of events is roughly:
1. timeout fires
2. glib calls timeout callback (e.g. shutdown_callback) which in turn
calls shutdown_func (gobi shutdown_cb) which in turn calls
qmi_device_unref()
3. qmi_device_unref calls g_source_remove, which doesn't call the
destroy callback (it is blocked)
4. qmi_device_unref then frees the memory used by device
5. glib then calls the source destroy callback (e.g. shutdown_destroy)
which results in just freed memory being used.
}
static void power_reset_cb(struct qmi_result *result, void *user_data)
Please try the attached patch.
Regards,
-Denis