[cc:ing [email protected] as the main pipex maintainer on openbsd]
On Fri, 5 Jul 2013, Philip Guenther wrote:
...
> Regarding your pipex crash, the location pipex_close_session+0xc4
> indicates that it crashed in the LIST_REMOVE() macro in
> pipex_close_session() when trying to update the 'prev' pointer in the
> *next* element. I.e., either this item isn't really on a list, or the
> _next_ item was freed while it was still on the list. I believe the
> latter occurred: I think pipex_destroy_session() can be closed on a
> session in the PIPEX_STATE_CLOSE_WAIT state, in which case that session
> is on the list headed by pipex_close_wait_list and needs to be removed
> from that before being freed.
>
> Please try the following diff.
After further examination, I think the state change in pipex_timer() is
also affected, leading to the revised diff below.
Philip Guenther
Index: net/pipex.c
===================================================================
RCS file: /cvs/src/sys/net/pipex.c,v
retrieving revision 1.42
diff -u -p -r1.42 pipex.c
--- net/pipex.c 8 Jun 2013 14:24:38 -0000 1.42
+++ net/pipex.c 5 Jul 2013 08:14:24 -0000
@@ -608,6 +608,9 @@ pipex_destroy_session(struct pipex_sessi
KASSERT(rn != NULL);
}
+ if (session->state == PIPEX_STATE_CLOSE_WAIT)
+ LIST_REMOVE(session, state_list);
+
LIST_REMOVE(session, id_chain);
LIST_REMOVE(session, session_list);
#ifdef PIPEX_PPTP
@@ -849,6 +852,8 @@ pipex_timer(void *ignored_arg)
break;
case PIPEX_STATE_CLOSE_WAIT:
+ LIST_REMOVE(session, state_list);
+ /* FALLTHROUGH */
case PIPEX_STATE_CLOSE_WAIT2:
session->stat.idle_time++;
if (session->stat.idle_time < PIPEX_CLOSE_TIMEOUT)