resource.[hc], net.c: fix use after free for query string

If a resource is observed, handle_request() passes the ownership
of a Uri-Query to the observer structure for later retrieval. In
this case, the query is not free'd in handle_request. However, if
the observer data structure ("subscription") was not created due
to insufficient memory, the query string must not be deleted as
it is used for the resource handler callback later in
handle_request(). The solution here passes ownership to the
observer only if case coap_add_observer() is successful.

This fixes CID 1483551.
This commit is contained in:
Olaf Bergmann committed 2020-06-19 16:27:51 +02:00
1 parent ec3dfda228
commit 48dc4538ce
3 files changed
+9 -4

No files matched your search

+2 -1
View File
@@ -419,7 +419,8 @@ coap_resource_t *coap_get_resource_from_uri_path(coap_context_t *context,
* @param session The observer's session
* @param token The token that identifies this subscription.
* @param query The query string, if any. subscription will
take ownership of the string.
* take ownership of the string unless this
* function returns NULL.
* @param has_block2 If Option Block2 defined.
* @param block2 Contents of Block2 if Block 2 defined.
* @return A pointer to the added/updated subscription
+4 -1
View File
@@ -2278,8 +2278,11 @@ handle_request(coap_context_t *context, coap_session_t *session, coap_pdu_t *pdu
has_block2 = 1;
}
subscription = coap_add_observer(resource, session, &token, query, has_block2, block2);
owns_query = 0;
if (subscription) {
/* Ownership of query is taken by subscription if not
* NULL. In this case, we must not delete query here
* hence owns_query is cleared. */
owns_query = 0;
coap_touch_observer(context, session, &token);
}
}
+3 -2
View File
@@ -674,8 +674,9 @@ coap_add_observer(coap_resource_t *resource,
s = COAP_MALLOC_TYPE(subscription);
if (!s) {
if (query)
coap_delete_string(query);
/* query is not deleted so it can be used in the calling function
* which must give up ownership of query only if this function
* does not return NULL. */
return NULL;
}