From: Christian Grothoff Date: Sun, 30 Nov 2014 00:44:56 +0000 (+0000) Subject: -avoid use after free during set intersection completion X-Git-Tag: initial-import-from-subversion-38251~3043 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=991f51dc78d1690bdf169bca8028a3d0c5fbb177;p=oweals%2Fgnunet.git -avoid use after free during set intersection completion --- diff --git a/src/set/gnunet-service-set.c b/src/set/gnunet-service-set.c index 44f34a492..c40ac9c53 100644 --- a/src/set/gnunet-service-set.c +++ b/src/set/gnunet-service-set.c @@ -1458,7 +1458,8 @@ dispatch_p2p_message (void *cls, * @param cfg configuration to use */ static void -run (void *cls, struct GNUNET_SERVER_Handle *server, +run (void *cls, + struct GNUNET_SERVER_Handle *server, const struct GNUNET_CONFIGURATION_Handle *cfg) { static const struct GNUNET_SERVER_MessageHandler server_handlers[] = { diff --git a/src/set/gnunet-service-set_intersection.c b/src/set/gnunet-service-set_intersection.c index ed29033b4..ceb6a3ccb 100644 --- a/src/set/gnunet-service-set_intersection.c +++ b/src/set/gnunet-service-set_intersection.c @@ -549,13 +549,15 @@ send_remaining_elements (void *cls) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending done and destroy because iterator ran out\n"); + op->keep = GNUNET_NO; send_client_done_and_destroy (op); return; } ee = nxt; element = &ee->element; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Sending element (size %u) to client (full set)\n", + "Sending element %s:%u to client (full set)\n", + GNUNET_h2s (&ee->element_hash), element->size); GNUNET_assert (0 != op->spec->client_request_id); ev = GNUNET_MQ_msg_extra (rm, @@ -901,9 +903,11 @@ finish_and_destroy (struct Operation *op) if (GNUNET_SET_RESULT_FULL == op->spec->result_mode) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Sending full result set\n"); + "Sending full result set (%u elements)\n", + GNUNET_CONTAINER_multihashmap_size (op->state->my_elements)); op->state->full_result_iter = GNUNET_CONTAINER_multihashmap_iterator_create (op->state->my_elements); + op->keep = GNUNET_YES; send_remaining_elements (op); return; } @@ -993,7 +997,8 @@ handle_p2p_done (void *cls, return; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got final DONE\n"); + "Got IntersectionDoneMessage, have %u elements in intersection\n", + op->state->my_element_count); op->state->phase = PHASE_FINISHED; finish_and_destroy (op); } diff --git a/src/set/set_api.c b/src/set/set_api.c index 20a9d149a..453a235b2 100644 --- a/src/set/set_api.c +++ b/src/set/set_api.c @@ -306,6 +306,10 @@ handle_result (void *cls, msg = (const struct GNUNET_SET_ResultMessage *) mh; GNUNET_assert (NULL != set->mq); result_status = ntohs (msg->result_status); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Got result message with status %d\n", + result_status); + oh = GNUNET_MQ_assoc_get (set->mq, ntohl (msg->request_id)); if (NULL == oh) @@ -331,6 +335,19 @@ handle_result (void *cls, oh->result_cb (oh->result_cls, NULL, result_status); + switch (result_status) + { + case GNUNET_SET_STATUS_OK: + break; + case GNUNET_SET_STATUS_FAILURE: + oh->result_cb = NULL; + break; + case GNUNET_SET_STATUS_HALF_DONE: + break; + case GNUNET_SET_STATUS_DONE: + oh->result_cb = NULL; + break; + } GNUNET_free (oh); return; } @@ -417,7 +434,8 @@ handle_client_set_error (void *cls, struct GNUNET_SET_Handle *set = cls; LOG (GNUNET_ERROR_TYPE_DEBUG, - "Handling client set error\n"); + "Handling client set error %d\n", + error); while (NULL != set->ops_head) { if (NULL != set->ops_head->result_cb) @@ -479,7 +497,8 @@ GNUNET_SET_create (const struct GNUNET_CONFIGURATION_Handle *cfg, } set->mq = GNUNET_MQ_queue_for_connection_client (set->client, mq_handlers, - &handle_client_set_error, set); + &handle_client_set_error, + set); GNUNET_assert (NULL != set->mq); mqm = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_SET_CREATE); diff --git a/src/set/test_set_intersection_result_full.c b/src/set/test_set_intersection_result_full.c index 1baf667dd..d1eb18a26 100644 --- a/src/set/test_set_intersection_result_full.c +++ b/src/set/test_set_intersection_result_full.c @@ -53,6 +53,7 @@ result_cb_set1 (void *cls, enum GNUNET_SET_Status status) { static int count; + switch (status) { case GNUNET_SET_STATUS_OK: