Opened 14 years ago

Last modified 7 years ago

#109 closed defect (Fixed)

assert_cpath_layer_ok(): Unexpected state 171

Reported by: thomass Owned by:
Priority: Low Milestone:
Component: Core Tor/Tor Version: 0.0.9.5
Severity: Keywords:
Cc: Actual Points:
Parent ID: Points:
Reviewer: Sponsor:

Description

Mar 02 01:37:03.412 [err] assert_cpath_layer_ok(): Unexpected state 171
Mar 02 01:37:03.412 [err] circuitlist.c:426: assert_cpath_layer_ok:
Assertion 0 failed; aborting.
circuitlist.c:426 assert_cpath_layer_ok: Assertion 0 failed; aborting.
Abort

We are using Tor version 0.0.9.5. , compiled out of a source-tarball with no special compile-options

[Automatically added by flyspray2trac: Operating System: All]

Child Tickets

Change History (4)

comment:1 Changed 14 years ago by Steven

We have experienced this problem also (0.0.9.5 built on Windows 2003 Server with VC7). I believe the validation on the connection_t is not correct under rare circumstances. The assertion in assert_cpath_layer_ok results when the state is not 0, 1, or 2. When I looked at the memory, it was all 0xfeee (free does this under my configuration). Looking through the code, it looks like cpath_layer is a copy to the last crypt_path_t in the circuit. Looking at run_scheduled_events (main.c), circuit_close_all_marked is called which deallocates any circuits marked for closing (including all of their crypt_path_t's). Several lines later, conn_close_if_marked is called which deallocates any connections marked for closing. Before deallocating, assert_connection_ok is called which in turn calls assert_cpath_layer_ok for certain connections. If the circuit that the connection had a copy to has already been deallocated, the assert_cpath_layer_ok will look at freed memory and normally fail. I believe this does not happen very often, because conn_close_if_marked is called frequently in do_main_loop. I think it will only happen if a circuit is marked for closing between a call to conn_close_if_marked and circuit_close_all_marked (and the other connection conditions are met to get to assert_cpath_layer_ok). As a workaround, I only call assert_cpath_layer_ok if the connection is not marked to be closed (because it appears that if the connection is about to be closed, there is no guarantee that the cpath_layer is valid).

in connection.c assert_connection_ok
if (!conn->marked_for_close)

assert_cpath_layer_ok(conn->cpath_layer);

We have been running with this change for about a day with no problems (we used to see it every couple of hours under a relatively heavy load). I hope someone more knowledgeable of the source code can respond if the assumptions in this post are correct and this change won't cause something else to break.

Thanks


comment:2 Changed 14 years ago by Steven

This is a repost with all underscores replaced with dashes.

We have experienced this problem also (0.0.9.5 built on Windows 2003 Server VC7). I believe the validation on the connection-t is not correct under rare circumstances. The assertion in assert-cpath-layer-ok results when the state is not 0, 1, or 2. When I looked at the memory, it was all 0xfeee (apparently free does this on Windows). Looking through the code, it looks like cpath-layer is a copy to the last crypt-path-t in the circuit. Looking at run-scheduled-events (main.c), circuit-close-all-marked is called which deallocates any circuits marked for closing (including all of their crypt-path-t's. Several lines later conn-close-if-marked is called which deallocates any connections marked for closing. Before deallocating, assert-connection-ok is called which in turn calls assert-cpath-layer-ok for certain connections. If the circuit that the connection had a copy to has already been deallocated, the assert-cpath-layer-ok will look at freed memory and normally fail. I believe this does not happen very often, because conn-close-if-marked is called frequently in do-main-loop. I think it will only happen if a circuit is marked for closing between a call to conn-close-if-marked and circuit-close-all-marked (and the other connection conditions are met to get to assert-cpath-layer-ok). As a workaround, I only call assert-cpath-layer-ok if the connection is not marked to be closed (because it appears that if the connection is about to be closed, there is no guarantee that the cpath-layer is valid).

in connection.c assert-connection-ok

if (!conn->marked-for-close)

assert-cpath-layer-ok(conn->cpath-layer);

We have been running with this change for about a day with no problems. I hope someone more knowledgeable of the source code can respond if the assumptions in this post are correct and this change won't cause something else to break.

comment:3 Changed 14 years ago by nickm

flyspray2trac: bug closed.
Great detective work, Steven! Thanks to your help, we've got a fix for the bug in CVS that should appear in future versions.

comment:4 Changed 7 years ago by nickm

Component: Tor ClientTor
Note: See TracTickets for help on using tickets.