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:
parent
b3cfc6e98e
commit
fe7b8efc6b
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue