session: fix use after free of session->devs as reported by valgrind

==7478== Invalid write of size 8
==7478==    at 0x4E59182: sr_session_dev_remove_all (session.c:302)
==7478==    by 0x4E591CD: sr_session_destroy (session.c:265)
==7478==    by 0x4095D9: load_input_file_module (input.c:143)
==7478==    by 0x4097AB: load_input_file (input.c:157)
==7478==    by 0x40531E: main (main.c:288)
==7478==  Address 0x7877eb8 is 88 bytes inside a block of size 96 free'd
==7478==    at 0x4C2A37C: free (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==7478==    by 0x4E5F454: sr_input_free (input.c:573)
==7478==    by 0x4095C3: load_input_file_module (input.c:140)
==7478==    by 0x4097AB: load_input_file (input.c:157)
==7478==    by 0x40531E: main (main.c:288)
This commit is contained in:
Stefan Brüns 2015-11-26 02:30:42 +01:00 committed by Uwe Hermann
parent b3cfc6e98e
commit fe7b8efc6b
3 changed files with 44 additions and 0 deletions

View File

@ -111,6 +111,8 @@ SR_API int sr_session_destroy(struct sr_session *session);
SR_API int sr_session_dev_remove_all(struct sr_session *session); SR_API int sr_session_dev_remove_all(struct sr_session *session);
SR_API int sr_session_dev_add(struct sr_session *session, SR_API int sr_session_dev_add(struct sr_session *session,
struct sr_dev_inst *sdi); struct sr_dev_inst *sdi);
SR_API int sr_session_dev_remove(struct sr_session *session,
struct sr_dev_inst *sdi);
SR_API int sr_session_dev_list(struct sr_session *session, GSList **devlist); SR_API int sr_session_dev_list(struct sr_session *session, GSList **devlist);
SR_API int sr_session_trigger_set(struct sr_session *session, struct sr_trigger *trig); SR_API int sr_session_trigger_set(struct sr_session *session, struct sr_trigger *trig);

View File

@ -261,6 +261,9 @@ SR_PRIV void sr_dev_inst_free(struct sr_dev_inst *sdi)
} }
g_slist_free(sdi->channel_groups); g_slist_free(sdi->channel_groups);
if (sdi->session)
sr_session_dev_remove(sdi->session, sdi);
g_free(sdi->vendor); g_free(sdi->vendor);
g_free(sdi->model); g_free(sdi->model);
g_free(sdi->version); g_free(sdi->version);

View File

@ -403,6 +403,45 @@ SR_API int sr_session_dev_list(struct sr_session *session, GSList **devlist)
return SR_OK; return SR_OK;
} }
/**
* Remove a device instance from a session.
*
* @param session The session to remove from. Must not be NULL.
* @param sdi The device instance to remove from a session. Must not
* be NULL. Also, sdi->driver and sdi->driver->dev_open must
* not be NULL.
*
* @retval SR_OK Success.
* @retval SR_ERR_ARG Invalid argument.
*
* @since 0.4.0
*/
SR_API int sr_session_dev_remove(struct sr_session *session,
struct sr_dev_inst *sdi)
{
if (!sdi) {
sr_err("%s: sdi was NULL", __func__);
return SR_ERR_ARG;
}
if (!session) {
sr_err("%s: session was NULL", __func__);
return SR_ERR_ARG;
}
/* If sdi->session is not session, the device is not in this
* session. */
if (sdi->session != session) {
sr_err("%s: not assigned to this session", __func__);
return SR_ERR_ARG;
}
session->devs = g_slist_remove(session->devs, sdi);
sdi->session = NULL;
return SR_OK;
}
/** /**
* Remove all datafeed callbacks in a session. * Remove all datafeed callbacks in a session.
* *