summaryrefslogtreecommitdiff
path: root/src/daemon/dlt_daemon_event_handler.c
diff options
context:
space:
mode:
authorFrederic Berat <fberat@de.adit-jv.com>2017-01-17 11:37:27 +0100
committerChristoph Lipka <clipka@jp.adit-jv.com>2017-02-01 12:14:55 +0900
commit0ce6e68d8835b13aa6be52ffdf2d81e1170a3834 (patch)
treea61dd79be59d2346be0c3614ed1f062f1ca147e2 /src/daemon/dlt_daemon_event_handler.c
parent03dce720baf91ff67eb82431f8d6ad24b4f4d657 (diff)
downloadDLT-daemon-0ce6e68d8835b13aa6be52ffdf2d81e1170a3834.tar.gz
dlt-daemon: Fix use after free potential issue
In dlt_daemon_send_all_multiple, if the connection was broken, we closed it before getting the next available connection. This must be avoided by having a temporary next pointer. The same kind of problem is valid for pointers coming from the epoll interface. The kernel can provide back connection pointer that are not valid any longer. Therefore, we need to use an ID instead of the pointer value to retrieve the connections. Signed-off-by: Frederic Berat <fberat@de.adit-jv.com> Signed-off-by: Christoph Lipka <clipka@jp.adit-jv.com>
Diffstat (limited to 'src/daemon/dlt_daemon_event_handler.c')
-rw-r--r--src/daemon/dlt_daemon_event_handler.c31
1 files changed, 29 insertions, 2 deletions
diff --git a/src/daemon/dlt_daemon_event_handler.c b/src/daemon/dlt_daemon_event_handler.c
index cfe61a4..9051f07 100644
--- a/src/daemon/dlt_daemon_event_handler.c
+++ b/src/daemon/dlt_daemon_event_handler.c
@@ -128,7 +128,9 @@ int dlt_daemon_handle_event(DltEventHandler *pEvent,
for (i = 0 ; i < nfds ; i++)
{
struct epoll_event *ev = &pEvent->events[i];
- DltConnection *con = (DltConnection *)ev->data.ptr;
+ DltConnectionId id = (DltConnectionId)ev->data.ptr;
+ DltConnection *con = dlt_event_handler_find_connection_by_id(pEvent,
+ id);
int fd = 0;
DltConnectionType type = DLT_CONNECTION_TYPE_MAX;
@@ -210,6 +212,31 @@ DltConnection *dlt_event_handler_find_connection(DltEventHandler *ev,
return temp;
}
+/** @brief Find connection with a specific \a id in the connection list.
+ *
+ * There can be only one event per \a fd. We can then find a specific connection
+ * based on this \a fd. That allows to check if a specific \a fd has already been
+ * registered.
+ *
+ * @param ev The event handler structure where the list of connection is.
+ * @param id The identifier of the connection to be found.
+ *
+ * @return The found connection pointer, NULL otherwise.
+ */
+DltConnection *dlt_event_handler_find_connection_by_id(DltEventHandler *ev,
+ DltConnectionId id)
+{
+
+ DltConnection *temp = ev->connections;
+
+ while ((temp != NULL) && (temp->id != id))
+ {
+ temp = temp->next;
+ }
+
+ return temp;
+}
+
/** @brief Remove a connection from the list and destroy it.
*
* This function will first look for the connection in the event handler list,
@@ -351,7 +378,7 @@ int dlt_connection_check_activate(DltEventHandler *evhdl,
{
struct epoll_event ev; /* Content will be copied by the kernel */
ev.events = con->ev_mask;
- ev.data.ptr = (void *)con;
+ ev.data.ptr = (void *)con->id;
snprintf(local_str,
DLT_DAEMON_TEXTBUFSIZE,