From: Bart Polot Date: Wed, 21 Sep 2011 15:42:32 +0000 (+0000) Subject: Fixed use of uninitialized memory from realloc leading to segfaults and bus errors X-Git-Tag: initial-import-from-subversion-38251~16986 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=c49bdc2e3f448a02d1031ab296ecc0805f4d8c61;p=oweals%2Fgnunet.git Fixed use of uninitialized memory from realloc leading to segfaults and bus errors --- diff --git a/src/mesh/mesh_tunnel_tree.c b/src/mesh/mesh_tunnel_tree.c index 30aaeadb3..185620125 100644 --- a/src/mesh/mesh_tunnel_tree.c +++ b/src/mesh/mesh_tunnel_tree.c @@ -293,8 +293,13 @@ tree_add_path (struct MeshTunnelTree *t, const struct MeshPeerPath *p, unsigned int i; unsigned int j; + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "test: Adding path [%u] towards peer %u to peer %u.\n", + p->length, + p->peers[p->length - 1], + t->me->peer); GNUNET_assert(0 != p->length); - n = t->root; + parent = n = t->root; if (n->peer != p->peers[0]) { GNUNET_break (0); @@ -309,13 +314,21 @@ tree_add_path (struct MeshTunnelTree *t, const struct MeshPeerPath *p, * - Length of the path is expected to be log N (size of whole network). * - Each level of the tree is expected to have log n children (size of tree). */ - for (i = 0, me = -1; i < p->length; i++) + me = t->root->peer == myid ? 0 : -1; + for (i = 1; i < p->length; i++) { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "test: Looking for peer %u.\n", + p->peers[i]); parent = n; if (p->peers[i] == myid) me = i; for (j = 0; j < n->nchildren; j++) { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "test: Child %u. is %u\n", + j, + n->children[j].peer); if (n->children[j].peer == p->peers[i]) { n = &n->children[j]; @@ -327,6 +340,8 @@ tree_add_path (struct MeshTunnelTree *t, const struct MeshPeerPath *p, if (parent == n) break; } + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "test: All childen visited.\n"); if (-1 == me) { /* New path deviates from tree before reaching us. What happened? */ @@ -336,22 +351,38 @@ tree_add_path (struct MeshTunnelTree *t, const struct MeshPeerPath *p, /* Add the rest of the path as a branch from parent. */ while (i < p->length) { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "test: Adding peer %u, to %u.\n", + p->peers[i], + parent->peer); parent->nchildren++; + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "test: realloc %p, %u\n", parent->children, + parent->nchildren * + sizeof(struct MeshTunnelTreeNode)); parent->children = GNUNET_realloc (parent->children, parent->nchildren * sizeof(struct MeshTunnelTreeNode)); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "test: done: %p\n", parent->children); n = &parent->children[parent->nchildren - 1]; if (i == p->length - 1 && NULL != oldnode) { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "test: Putting old note into place.\n"); /* Assignation and free can be misleading, using explicit mempcy */ memcpy (n, oldnode, sizeof (struct MeshTunnelTreeNode)); - GNUNET_free (oldnode); + tree_node_destroy(oldnode); } else { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "test: Creating new node.\n"); n->t = t->t; n->status = MESH_PEER_RELAY; n->peer = p->peers[i]; + n->nchildren = 0; + n->children = NULL; } n->parent = parent; i++; @@ -421,5 +452,4 @@ tree_destroy (struct MeshTunnelTree *t) GNUNET_free(t->root); GNUNET_CONTAINER_multihashmap_iterate(t->first_hops, &iterate_free, NULL); GNUNET_CONTAINER_multihashmap_destroy(t->first_hops); - } \ No newline at end of file diff --git a/src/mesh/mesh_tunnel_tree.h b/src/mesh/mesh_tunnel_tree.h index c7878359f..05972e0fe 100644 --- a/src/mesh/mesh_tunnel_tree.h +++ b/src/mesh/mesh_tunnel_tree.h @@ -266,6 +266,16 @@ int tree_add_path (struct MeshTunnelTree *t, const struct MeshPeerPath *p, MeshNodeDisconnectCB cb); + +/** + * Destroy the node and all children + * + * @param n Parent node to be destroyed + */ +void +tree_node_destroy (struct MeshTunnelTreeNode *n); + + /** * Destroy the whole tree and free all used memory and Peer_Ids * diff --git a/src/mesh/test_mesh_path_api.c b/src/mesh/test_mesh_path_api.c index 4680fda91..fc073df5f 100644 --- a/src/mesh/test_mesh_path_api.c +++ b/src/mesh/test_mesh_path_api.c @@ -84,7 +84,8 @@ main (int argc, char *argv[]) { struct MeshTunnelTreeNode *node; struct MeshTunnelTreeNode *node2; - struct MeshPeerPath *path[10]; + struct MeshPeerPath *path; + struct MeshPeerPath *path1; unsigned int i; failed = 0; @@ -108,24 +109,24 @@ main (int argc, char *argv[]) tree->root = GNUNET_malloc(sizeof(struct MeshTunnelTreeNode)); tree->root->peer = 0; tree->me = tree->root; - path[0] = GNUNET_malloc(sizeof(struct MeshPeerPath)); - path[0]->peers = GNUNET_malloc(sizeof(GNUNET_PEER_Id) * 4); - path[0]->peers[0] = 0; - path[0]->peers[1] = 1; - path[0]->peers[2] = 2; - path[0]->peers[3] = 3; - path[0]->length = 4; + path = GNUNET_malloc(sizeof(struct MeshPeerPath)); + path->peers = GNUNET_malloc(sizeof(GNUNET_PEER_Id) * 4); + path->peers[0] = 0; + path->peers[1] = 1; + path->peers[2] = 2; + path->peers[3] = 3; + path->length = 4; + tree_add_path(tree, path, &cb); finish(); - tree_add_path(tree, path[0], &cb); - path[1] = tree_get_path_to_peer(tree, 3); - if (path[0]->length != path[1]->length || - memcmp(path[0]->peers, path[1]->peers, path[0]->length) != 0) + path1 = tree_get_path_to_peer(tree, 3); + if (path->length != path1->length || + memcmp(path->peers, path1->peers, path->length) != 0) { GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved path != original\n"); failed++; } - path_destroy(path[1]); + path_destroy(path1); node = tree_find_peer(tree->root, 3); if (node->peer != 3) { @@ -184,8 +185,8 @@ main (int argc, char *argv[]) failed++; } - path[0]->length--; - tree_add_path(tree, path[0], &cb); + path->length--; + tree_add_path(tree, path, &cb); node = tree_find_peer(tree->root, 2); if (node->peer != 2) @@ -231,9 +232,9 @@ main (int argc, char *argv[]) failed++; } - path[0]->length++; - path[0]->peers[3] = 4; - tree_add_path(tree, path[0], &cb); + path->length++; + path->peers[3] = 4; + tree_add_path(tree, path, &cb); node = tree_find_peer(tree->root, 2); if (node->peer != 2) @@ -316,10 +317,10 @@ main (int argc, char *argv[]) failed++; } - path[0]->length = 2; - path[0]->peers[1] = 3; + path->length = 2; + path->peers[1] = 3; cb_call = 1; - tree_add_path(tree, path[0], cb); + tree_add_path(tree, path, cb); if (cb_call != 0) { GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "%u callbacks missed!\n", cb_call);