[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r31240 - in gnunet/src: set util
From: |
gnunet |
Subject: |
[GNUnet-SVN] r31240 - in gnunet/src: set util |
Date: |
Mon, 9 Dec 2013 21:27:32 +0100 |
Author: dold
Date: 2013-12-09 21:27:32 +0100 (Mon, 09 Dec 2013)
New Revision: 31240
Modified:
gnunet/src/set/gnunet-service-set.c
gnunet/src/set/gnunet-service-set.h
gnunet/src/set/gnunet-service-set_union.c
gnunet/src/set/test_set_union_result_full.c
gnunet/src/util/mq.c
Log:
- fix use after free in set union (#3178)
Modified: gnunet/src/set/gnunet-service-set.c
===================================================================
--- gnunet/src/set/gnunet-service-set.c 2013-12-09 19:58:51 UTC (rev 31239)
+++ gnunet/src/set/gnunet-service-set.c 2013-12-09 20:27:32 UTC (rev 31240)
@@ -955,8 +955,8 @@
GNUNET_CONTAINER_DLL_insert (set->ops_head, set->ops_tail, op);
op->channel = GNUNET_MESH_channel_create (mesh, op, &msg->target_peer,
- GNUNET_APPLICATION_TYPE_SET,
- GNUNET_MESH_OPTION_RELIABLE);
+ GNUNET_APPLICATION_TYPE_SET,
+ GNUNET_MESH_OPTION_RELIABLE);
op->mq = GNUNET_MESH_mq_create (op->channel);
@@ -1261,17 +1261,28 @@
*/
static void
channel_end_cb (void *cls,
- const struct GNUNET_MESH_Channel *channel, void *channel_ctx)
+ const struct GNUNET_MESH_Channel *channel, void *channel_ctx)
{
struct Operation *op = channel_ctx;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"channel end cb called\n");
op->channel = NULL;
+ /* the vt can be null if a client already requested canceling op. */
if (NULL != op->vt)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "calling peer disconnect due to channel end\n");
op->vt->peer_disconnect (op);
+ }
+
+ if (GNUNET_YES == op->keep)
+ return;
+
/* mesh will never call us with the context again! */
GNUNET_free (channel_ctx);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "channel end cb finished\n");
}
Modified: gnunet/src/set/gnunet-service-set.h
===================================================================
--- gnunet/src/set/gnunet-service-set.h 2013-12-09 19:58:51 UTC (rev 31239)
+++ gnunet/src/set/gnunet-service-set.h 2013-12-09 20:27:32 UTC (rev 31240)
@@ -311,8 +311,6 @@
/**
* GNUNET_YES if this is not a "real" set operation yet, and we still
* need to wait for the other peer to give us more details.
- *
- * //TODO: replace with state-enum
*/
int is_incoming;
@@ -346,6 +344,12 @@
* a linked list.
*/
struct Operation *prev;
+
+ /**
+ * Set to GNUNET_YES if the set service should not free
+ * the operation, as it is still needed (e.g. in some scheduled task).
+ */
+ int keep;
};
Modified: gnunet/src/set/gnunet-service-set_union.c
===================================================================
--- gnunet/src/set/gnunet-service-set_union.c 2013-12-09 19:58:51 UTC (rev
31239)
+++ gnunet/src/set/gnunet-service-set_union.c 2013-12-09 20:27:32 UTC (rev
31240)
@@ -982,12 +982,15 @@
struct Operation *op = cls;
struct GNUNET_MQ_Envelope *ev;
struct GNUNET_SET_ResultMessage *rm;
+ int keep = op->keep;
ev = GNUNET_MQ_msg (rm, GNUNET_MESSAGE_TYPE_SET_RESULT);
rm->request_id = htonl (op->spec->client_request_id);
rm->result_status = htons (GNUNET_SET_STATUS_DONE);
rm->element_type = htons (0);
GNUNET_MQ_send (op->spec->set->client_mq, ev);
_GSS_operation_destroy (op);
+ if (GNUNET_YES == keep)
+ GNUNET_free (op);
}
@@ -1060,6 +1063,8 @@
if (GNUNET_SET_RESULT_FULL == op->spec->result_mode)
{
+ /* prevent that the op is free'd by the tunnel end handler */
+ op->keep = GNUNET_YES;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "sending full result set\n");
GNUNET_assert (NULL == op->state->full_result_iter);
op->state->full_result_iter =
Modified: gnunet/src/set/test_set_union_result_full.c
===================================================================
--- gnunet/src/set/test_set_union_result_full.c 2013-12-09 19:58:51 UTC (rev
31239)
+++ gnunet/src/set/test_set_union_result_full.c 2013-12-09 20:27:32 UTC (rev
31240)
@@ -28,6 +28,8 @@
#include "gnunet_set_service.h"
+static int ret;
+
static struct GNUNET_PeerIdentity local_id;
static struct GNUNET_HashCode app_id;
@@ -50,6 +52,7 @@
break;
case GNUNET_SET_STATUS_FAILURE:
printf ("set 1: failure\n");
+ ret = 1;
break;
case GNUNET_SET_STATUS_DONE:
printf ("set 1: done\n");
@@ -72,6 +75,7 @@
break;
case GNUNET_SET_STATUS_FAILURE:
printf ("set 2: failure\n");
+ ret = 1;
break;
case GNUNET_SET_STATUS_DONE:
printf ("set 2: done\n");
@@ -245,11 +249,12 @@
int
main (int argc, char **argv)
{
- int ret;
-
- ret = GNUNET_TESTING_peer_run ("test_set_api",
- "test_set.conf",
- &run, NULL);
+ if (0 != GNUNET_TESTING_peer_run ("test_set_api",
+ "test_set.conf",
+ &run, NULL))
+ {
+ return 0;
+ }
return ret;
}
Modified: gnunet/src/util/mq.c
===================================================================
--- gnunet/src/util/mq.c 2013-12-09 19:58:51 UTC (rev 31239)
+++ gnunet/src/util/mq.c 2013-12-09 20:27:32 UTC (rev 31240)
@@ -268,6 +268,9 @@
struct GNUNET_MQ_Handle *mq = cls;
struct GNUNET_MQ_Envelope *current_envelope;
+ if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
+ return;
+
mq->continue_task = GNUNET_SCHEDULER_NO_TASK;
/* call is only valid if we're actually currently sending
* a message */
@@ -466,6 +469,12 @@
{
struct ServerClientSocketState *state = impl_state;
+ if (NULL != state->th)
+ {
+ GNUNET_SERVER_notify_transmit_ready_cancel (state->th);
+ state->th = NULL;
+ }
+
GNUNET_assert (NULL != mq);
GNUNET_assert (NULL != state);
GNUNET_SERVER_client_drop (state->client);
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r31240 - in gnunet/src: set util,
gnunet <=