summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGert Doering <gert@greenie.muc.de>2012-12-25 13:41:50 +0100
committerDavid Sommerseth <davids@redhat.com>2013-01-02 13:20:50 +0100
commit2e3b853dd1070435d60a1f11ff4364631c83d6a9 (patch)
tree220faa655dd4a6ba24bc28d49c19ccd1484153b4 /src
parenta28048a20f46f718c3df3af95e230ab72234f915 (diff)
downloadopenvpn-2e3b853dd1070435d60a1f11ff4364631c83d6a9.tar.gz
openvpn-2e3b853dd1070435d60a1f11ff4364631c83d6a9.tar.xz
openvpn-2e3b853dd1070435d60a1f11ff4364631c83d6a9.zip
Fix client crash on double PUSH_REPLY.
Introduce an extra bool variable c2.pulled_options_md5_init_done to keep track of md5_init state of pulled_options_state - avoid accessing uninitialized state when a second PUSH_REPLY comes in (which only happens under very particular circumstances). Bug tracked down by Arne Schwabe <arne@rfc2549.rrg>. Signed-off-by: Gert Doering <gert@greenie.muc.de> Acked-by: Arne Schwabe <arne@rfc2549.org> Message-Id: 20121225124856.GT22465@greenie.muc.de URL: http://article.gmane.org/gmane.network.openvpn.devel/7216 Signed-off-by: David Sommerseth <davids@redhat.com> (cherry picked from commit 1978db4b9657f0db134f1deaeb1e8400bf6a033e)
Diffstat (limited to 'src')
-rw-r--r--src/openvpn/openvpn.h1
-rw-r--r--src/openvpn/push.c7
2 files changed, 7 insertions, 1 deletions
diff --git a/src/openvpn/openvpn.h b/src/openvpn/openvpn.h
index 7abfb08..bdfa685 100644
--- a/src/openvpn/openvpn.h
+++ b/src/openvpn/openvpn.h
@@ -474,6 +474,7 @@ struct context_2
bool did_pre_pull_restore;
/* hash of pulled options, so we can compare when options change */
+ bool pulled_options_md5_init_done;
struct md5_state pulled_options_state;
struct md5_digest pulled_options_digest;
diff --git a/src/openvpn/push.c b/src/openvpn/push.c
index 05a38e0..be50bef 100644
--- a/src/openvpn/push.c
+++ b/src/openvpn/push.c
@@ -446,10 +446,14 @@ process_incoming_push_msg (struct context *c,
if (ch == ',')
{
struct buffer buf_orig = buf;
+ if (!c->c2.pulled_options_md5_init_done)
+ {
+ md5_state_init (&c->c2.pulled_options_state);
+ c->c2.pulled_options_md5_init_done = true;
+ }
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;
}
if (apply_push_options (&c->options,
@@ -463,6 +467,7 @@ process_incoming_push_msg (struct context *c,
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);
+ c->c2.pulled_options_md5_init_done = false;
ret = PUSH_MSG_REPLY;
break;
case 2: