Hello,
I fear we may have to delay the final release. While debugging a problem
with a user of my app I found a nasty bug which causes OpenVPN to crash
if two PUSH_CONTROL messages are received.
from push.c:
if (!c->c2.did_pre_pull_restore)
{
pre_pull_restore (&c->options);
md5_state_init (&c->c2.pulled_options_state);
c->c2.did_pre_pull_restore = true;
}
This is executed on the first push message and initializes the md5
state. On further push messages (continuation or new) this is not
executed again.
if (apply_push_options (&c->options,
&buf,
permission_mask,
option_types_found,
c->c2.es))
switch (c->options.push_continuation)
{
case 0:
case 1:
md5_state_update (&c->c2.pulled_options_state, BPTR(&buf_orig),
BLEN(&buf_orig));
md5_state_final (&c->c2.pulled_options_state,
&c->c2.pulled_options_digest);
ret = PUSH_MSG_REPLY;
This finalizes the md5 state. leaving pulled_options_state in a
uninitialized or at least undefined state. If a second push message
after a final message is received md5_state_update will use this
undefined context
break;
case 2:
md5_state_update (&c->c2.pulled_options_state, BPTR(&buf_orig),
BLEN(&buf_orig));
ret = PUSH_MSG_CONTINUATION;
break;
}
To trigger this issue there have multiple things.
* A OpenVPN 2.3 server (commit 5d4f5435a421299ed047485d8d99bdf9a0d22fd1
allows duplicate sending of this message), you can also simply duplicate
the send_push_something method call to trigger this bug on clients
* A bit flaky connection. The GSM/UMTS networks are great for this. They
sometimes wait a very long time to deliver the packet (like 30s) without
dropping packets
I think the bug also exists in 2.2 clients but I have not done extensive
checks. Since push_control messages have no sequence number or such it
is difficult to determine how to only apply the push messages only once.
A quick&dirty hack is to simply md5_state_init the state after the
md5_state_final.
Arne