summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon Burgess <jburgess777@gmail.com>2018-10-14 18:49:52 +0100
committerUwe Hermann <uwe@hermann-uwe.de>2018-10-21 16:39:33 +0200
commit611a73404f1a42aa92fb32f00ca5407e1cdb2c71 (patch)
treefe4323992f2a26693bb90ae23e965795c372f3e9
parent3a063627c5658a65790ff52a9c0ed9a1f660a0fb (diff)
downloadlibsigrokdecode-611a73404f1a42aa92fb32f00ca5407e1cdb2c71.tar.gz
libsigrokdecode-611a73404f1a42aa92fb32f00ca5407e1cdb2c71.zip
Fix bad memory accesses during srd_exit()
When the decoder and session unload functions are called they remove themselves from the list. The code walking the list must be careful to avoid accessing the next pointer which might now be invalid. The g_slist_foreach() takes care of this. Reports from Valgrind before fix: ==175436== Invalid read of size 8 -- ==175436== Address 0xe3f2598 is 8 bytes inside a block of size 16 free'd ==175436== at 0x4C2FDAC: free (vg_replace_malloc.c:530) ==175436== by 0x563C541: g_free (in /usr/lib64/libglib-2.0.so.0.5600.3) ==175436== by 0x5654783: g_slice_free1 (in /usr/lib64/libglib-2.0.so.0.5600.3) ==175436== by 0x56552A2: g_slist_remove (in /usr/lib64/libglib-2.0.so.0.5600.3) ==175436== by 0x4E3FEFF: srd_session_destroy (session.c:343) ==175436== by 0x4E3F5C7: srd_exit (srd.c:311) ==175436== by 0x40336F: test_inst_new (inst.c:40) ==175436== by 0x53E51D5: srunner_run_tagged (in /usr/lib64/libcheck.so.0.0.0) ==175436== by 0x401237: main (main.c:51) ==175436== Block was alloc'd at ==175436== at 0x4C2EBAB: malloc (vg_replace_malloc.c:299) ==175436== by 0x563C435: g_malloc (in /usr/lib64/libglib-2.0.so.0.5600.3) ==175436== by 0x5654056: g_slice_alloc (in /usr/lib64/libglib-2.0.so.0.5600.3) ==175436== by 0x5655797: g_slist_append (in /usr/lib64/libglib-2.0.so.0.5600.3) ==175436== by 0x4E3FC75: srd_session_new (session.c:71) ==175436== by 0x403345: test_inst_new (inst.c:37) ==175436== by 0x53E51D5: srunner_run_tagged (in /usr/lib64/libcheck.so.0.0.0) ==175436== by 0x401237: main (main.c:51)
-rw-r--r--decoder.c10
-rw-r--r--srd.c11
2 files changed, 17 insertions, 4 deletions
diff --git a/decoder.c b/decoder.c
index 7374b77..260f636 100644
--- a/decoder.c
+++ b/decoder.c
@@ -1068,6 +1068,13 @@ SRD_API int srd_decoder_load_all(void)
return SRD_OK;
}
+static void srd_decoder_unload_cb(void *arg, void *ignored)
+{
+ (void)ignored;
+
+ srd_decoder_unload((struct srd_decoder *)arg);
+}
+
/**
* Unload all loaded protocol decoders.
*
@@ -1077,8 +1084,7 @@ SRD_API int srd_decoder_load_all(void)
*/
SRD_API int srd_decoder_unload_all(void)
{
- for (GSList *l = pd_list; l; l = l->next)
- srd_decoder_unload(l->data);
+ g_slist_foreach(pd_list, srd_decoder_unload_cb, NULL);
g_slist_free(pd_list);
pd_list = NULL;
diff --git a/srd.c b/srd.c
index 535ea12..248d8e5 100644
--- a/srd.c
+++ b/srd.c
@@ -289,6 +289,12 @@ SRD_API int srd_init(const char *path)
return SRD_OK;
}
+static void srd_session_destroy_cb(void *arg, void *ignored)
+{
+ (void)ignored; // Prevent unused warning
+ srd_session_destroy((struct srd_session *)arg);
+}
+
/**
* Shutdown libsigrokdecode.
*
@@ -307,8 +313,9 @@ SRD_API int srd_exit(void)
{
srd_dbg("Exiting libsigrokdecode.");
- for (GSList *l = sessions; l; l = l->next)
- srd_session_destroy(l->data);
+ g_slist_foreach(sessions, srd_session_destroy_cb, NULL);
+ g_slist_free(sessions);
+ sessions = NULL;
srd_decoder_unload_all();
g_slist_free_full(searchpaths, g_free);