diff options
author | Bart Polot <bart@net.in.tum.de> | 2011-09-21 15:42:32 +0000 |
---|---|---|
committer | Bart Polot <bart@net.in.tum.de> | 2011-09-21 15:42:32 +0000 |
commit | c49bdc2e3f448a02d1031ab296ecc0805f4d8c61 (patch) | |
tree | 59721e3b978e310ac66dd45df11074f1fb4c3dca /src/mesh | |
parent | 7ed59b4939c09f65ce21f77fca3abcdd8061c570 (diff) | |
download | gnunet-c49bdc2e3f448a02d1031ab296ecc0805f4d8c61.tar.gz gnunet-c49bdc2e3f448a02d1031ab296ecc0805f4d8c61.zip |
Fixed use of uninitialized memory from realloc leading to segfaults and bus errors
Diffstat (limited to 'src/mesh')
-rw-r--r-- | src/mesh/mesh_tunnel_tree.c | 38 | ||||
-rw-r--r-- | src/mesh/mesh_tunnel_tree.h | 10 | ||||
-rw-r--r-- | src/mesh/test_mesh_path_api.c | 43 |
3 files changed, 66 insertions, 25 deletions
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, | |||
293 | unsigned int i; | 293 | unsigned int i; |
294 | unsigned int j; | 294 | unsigned int j; |
295 | 295 | ||
296 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
297 | "test: Adding path [%u] towards peer %u to peer %u.\n", | ||
298 | p->length, | ||
299 | p->peers[p->length - 1], | ||
300 | t->me->peer); | ||
296 | GNUNET_assert(0 != p->length); | 301 | GNUNET_assert(0 != p->length); |
297 | n = t->root; | 302 | parent = n = t->root; |
298 | if (n->peer != p->peers[0]) | 303 | if (n->peer != p->peers[0]) |
299 | { | 304 | { |
300 | GNUNET_break (0); | 305 | GNUNET_break (0); |
@@ -309,13 +314,21 @@ tree_add_path (struct MeshTunnelTree *t, const struct MeshPeerPath *p, | |||
309 | * - Length of the path is expected to be log N (size of whole network). | 314 | * - Length of the path is expected to be log N (size of whole network). |
310 | * - Each level of the tree is expected to have log n children (size of tree). | 315 | * - Each level of the tree is expected to have log n children (size of tree). |
311 | */ | 316 | */ |
312 | for (i = 0, me = -1; i < p->length; i++) | 317 | me = t->root->peer == myid ? 0 : -1; |
318 | for (i = 1; i < p->length; i++) | ||
313 | { | 319 | { |
320 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
321 | "test: Looking for peer %u.\n", | ||
322 | p->peers[i]); | ||
314 | parent = n; | 323 | parent = n; |
315 | if (p->peers[i] == myid) | 324 | if (p->peers[i] == myid) |
316 | me = i; | 325 | me = i; |
317 | for (j = 0; j < n->nchildren; j++) | 326 | for (j = 0; j < n->nchildren; j++) |
318 | { | 327 | { |
328 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
329 | "test: Child %u. is %u\n", | ||
330 | j, | ||
331 | n->children[j].peer); | ||
319 | if (n->children[j].peer == p->peers[i]) | 332 | if (n->children[j].peer == p->peers[i]) |
320 | { | 333 | { |
321 | n = &n->children[j]; | 334 | n = &n->children[j]; |
@@ -327,6 +340,8 @@ tree_add_path (struct MeshTunnelTree *t, const struct MeshPeerPath *p, | |||
327 | if (parent == n) | 340 | if (parent == n) |
328 | break; | 341 | break; |
329 | } | 342 | } |
343 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
344 | "test: All childen visited.\n"); | ||
330 | if (-1 == me) | 345 | if (-1 == me) |
331 | { | 346 | { |
332 | /* New path deviates from tree before reaching us. What happened? */ | 347 | /* New path deviates from tree before reaching us. What happened? */ |
@@ -336,22 +351,38 @@ tree_add_path (struct MeshTunnelTree *t, const struct MeshPeerPath *p, | |||
336 | /* Add the rest of the path as a branch from parent. */ | 351 | /* Add the rest of the path as a branch from parent. */ |
337 | while (i < p->length) | 352 | while (i < p->length) |
338 | { | 353 | { |
354 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
355 | "test: Adding peer %u, to %u.\n", | ||
356 | p->peers[i], | ||
357 | parent->peer); | ||
339 | parent->nchildren++; | 358 | parent->nchildren++; |
359 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
360 | "test: realloc %p, %u\n", parent->children, | ||
361 | parent->nchildren * | ||
362 | sizeof(struct MeshTunnelTreeNode)); | ||
340 | parent->children = GNUNET_realloc (parent->children, | 363 | parent->children = GNUNET_realloc (parent->children, |
341 | parent->nchildren * | 364 | parent->nchildren * |
342 | sizeof(struct MeshTunnelTreeNode)); | 365 | sizeof(struct MeshTunnelTreeNode)); |
366 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
367 | "test: done: %p\n", parent->children); | ||
343 | n = &parent->children[parent->nchildren - 1]; | 368 | n = &parent->children[parent->nchildren - 1]; |
344 | if (i == p->length - 1 && NULL != oldnode) | 369 | if (i == p->length - 1 && NULL != oldnode) |
345 | { | 370 | { |
371 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
372 | "test: Putting old note into place.\n"); | ||
346 | /* Assignation and free can be misleading, using explicit mempcy */ | 373 | /* Assignation and free can be misleading, using explicit mempcy */ |
347 | memcpy (n, oldnode, sizeof (struct MeshTunnelTreeNode)); | 374 | memcpy (n, oldnode, sizeof (struct MeshTunnelTreeNode)); |
348 | GNUNET_free (oldnode); | 375 | tree_node_destroy(oldnode); |
349 | } | 376 | } |
350 | else | 377 | else |
351 | { | 378 | { |
379 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
380 | "test: Creating new node.\n"); | ||
352 | n->t = t->t; | 381 | n->t = t->t; |
353 | n->status = MESH_PEER_RELAY; | 382 | n->status = MESH_PEER_RELAY; |
354 | n->peer = p->peers[i]; | 383 | n->peer = p->peers[i]; |
384 | n->nchildren = 0; | ||
385 | n->children = NULL; | ||
355 | } | 386 | } |
356 | n->parent = parent; | 387 | n->parent = parent; |
357 | i++; | 388 | i++; |
@@ -421,5 +452,4 @@ tree_destroy (struct MeshTunnelTree *t) | |||
421 | GNUNET_free(t->root); | 452 | GNUNET_free(t->root); |
422 | GNUNET_CONTAINER_multihashmap_iterate(t->first_hops, &iterate_free, NULL); | 453 | GNUNET_CONTAINER_multihashmap_iterate(t->first_hops, &iterate_free, NULL); |
423 | GNUNET_CONTAINER_multihashmap_destroy(t->first_hops); | 454 | GNUNET_CONTAINER_multihashmap_destroy(t->first_hops); |
424 | |||
425 | } \ No newline at end of file | 455 | } \ 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 | |||
266 | tree_add_path (struct MeshTunnelTree *t, const struct MeshPeerPath *p, | 266 | tree_add_path (struct MeshTunnelTree *t, const struct MeshPeerPath *p, |
267 | MeshNodeDisconnectCB cb); | 267 | MeshNodeDisconnectCB cb); |
268 | 268 | ||
269 | |||
270 | /** | ||
271 | * Destroy the node and all children | ||
272 | * | ||
273 | * @param n Parent node to be destroyed | ||
274 | */ | ||
275 | void | ||
276 | tree_node_destroy (struct MeshTunnelTreeNode *n); | ||
277 | |||
278 | |||
269 | /** | 279 | /** |
270 | * Destroy the whole tree and free all used memory and Peer_Ids | 280 | * Destroy the whole tree and free all used memory and Peer_Ids |
271 | * | 281 | * |
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[]) | |||
84 | { | 84 | { |
85 | struct MeshTunnelTreeNode *node; | 85 | struct MeshTunnelTreeNode *node; |
86 | struct MeshTunnelTreeNode *node2; | 86 | struct MeshTunnelTreeNode *node2; |
87 | struct MeshPeerPath *path[10]; | 87 | struct MeshPeerPath *path; |
88 | struct MeshPeerPath *path1; | ||
88 | unsigned int i; | 89 | unsigned int i; |
89 | 90 | ||
90 | failed = 0; | 91 | failed = 0; |
@@ -108,24 +109,24 @@ main (int argc, char *argv[]) | |||
108 | tree->root = GNUNET_malloc(sizeof(struct MeshTunnelTreeNode)); | 109 | tree->root = GNUNET_malloc(sizeof(struct MeshTunnelTreeNode)); |
109 | tree->root->peer = 0; | 110 | tree->root->peer = 0; |
110 | tree->me = tree->root; | 111 | tree->me = tree->root; |
111 | path[0] = GNUNET_malloc(sizeof(struct MeshPeerPath)); | 112 | path = GNUNET_malloc(sizeof(struct MeshPeerPath)); |
112 | path[0]->peers = GNUNET_malloc(sizeof(GNUNET_PEER_Id) * 4); | 113 | path->peers = GNUNET_malloc(sizeof(GNUNET_PEER_Id) * 4); |
113 | path[0]->peers[0] = 0; | 114 | path->peers[0] = 0; |
114 | path[0]->peers[1] = 1; | 115 | path->peers[1] = 1; |
115 | path[0]->peers[2] = 2; | 116 | path->peers[2] = 2; |
116 | path[0]->peers[3] = 3; | 117 | path->peers[3] = 3; |
117 | path[0]->length = 4; | 118 | path->length = 4; |
118 | 119 | ||
120 | tree_add_path(tree, path, &cb); | ||
119 | finish(); | 121 | finish(); |
120 | tree_add_path(tree, path[0], &cb); | 122 | path1 = tree_get_path_to_peer(tree, 3); |
121 | path[1] = tree_get_path_to_peer(tree, 3); | 123 | if (path->length != path1->length || |
122 | if (path[0]->length != path[1]->length || | 124 | memcmp(path->peers, path1->peers, path->length) != 0) |
123 | memcmp(path[0]->peers, path[1]->peers, path[0]->length) != 0) | ||
124 | { | 125 | { |
125 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved path != original\n"); | 126 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Retrieved path != original\n"); |
126 | failed++; | 127 | failed++; |
127 | } | 128 | } |
128 | path_destroy(path[1]); | 129 | path_destroy(path1); |
129 | node = tree_find_peer(tree->root, 3); | 130 | node = tree_find_peer(tree->root, 3); |
130 | if (node->peer != 3) | 131 | if (node->peer != 3) |
131 | { | 132 | { |
@@ -184,8 +185,8 @@ main (int argc, char *argv[]) | |||
184 | failed++; | 185 | failed++; |
185 | } | 186 | } |
186 | 187 | ||
187 | path[0]->length--; | 188 | path->length--; |
188 | tree_add_path(tree, path[0], &cb); | 189 | tree_add_path(tree, path, &cb); |
189 | 190 | ||
190 | node = tree_find_peer(tree->root, 2); | 191 | node = tree_find_peer(tree->root, 2); |
191 | if (node->peer != 2) | 192 | if (node->peer != 2) |
@@ -231,9 +232,9 @@ main (int argc, char *argv[]) | |||
231 | failed++; | 232 | failed++; |
232 | } | 233 | } |
233 | 234 | ||
234 | path[0]->length++; | 235 | path->length++; |
235 | path[0]->peers[3] = 4; | 236 | path->peers[3] = 4; |
236 | tree_add_path(tree, path[0], &cb); | 237 | tree_add_path(tree, path, &cb); |
237 | 238 | ||
238 | node = tree_find_peer(tree->root, 2); | 239 | node = tree_find_peer(tree->root, 2); |
239 | if (node->peer != 2) | 240 | if (node->peer != 2) |
@@ -316,10 +317,10 @@ main (int argc, char *argv[]) | |||
316 | failed++; | 317 | failed++; |
317 | } | 318 | } |
318 | 319 | ||
319 | path[0]->length = 2; | 320 | path->length = 2; |
320 | path[0]->peers[1] = 3; | 321 | path->peers[1] = 3; |
321 | cb_call = 1; | 322 | cb_call = 1; |
322 | tree_add_path(tree, path[0], cb); | 323 | tree_add_path(tree, path, cb); |
323 | if (cb_call != 0) | 324 | if (cb_call != 0) |
324 | { | 325 | { |
325 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "%u callbacks missed!\n", cb_call); | 326 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "%u callbacks missed!\n", cb_call); |