From 79df31c85ab06d24f9443e370160cc9c44b88b93 Mon Sep 17 00:00:00 2001 From: james Date: Mon, 31 Oct 2005 03:49:25 +0000 Subject: svn merge -r 734:737 $SO/trunk/openvpn Security fixes from 2.0.3 git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@740 e7ae566f-a301-0410-adde-c780ea21d3b5 --- ChangeLog | 19 +++++++++++++++++++ init.c | 8 ++++++-- init.h | 2 ++ multi.c | 2 +- openvpn.h | 9 +++++---- options.c | 2 +- 6 files changed, 34 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index edfc588..62307b2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,25 @@ $Id$ 2005.10.xx -- Version 2.1-beta5 +* Security fix -- Affects non-Windows OpenVPN clients of + version 2.0 or higher which connect to a malicious or + compromised server. A format string vulnerability + in the foreign_option function in options.c could + potentially allow a malicious or compromised server + to execute arbitrary code on the client. Only + non-Windows clients are affected. The vulnerability + only exists if (a) the client's TLS negotiation with + the server succeeds, (b) the server is malicious or + has been compromised such that it is configured to + push a maliciously crafted options string to the client, + and (c) the client indicates its willingness to accept + pushed options from the server by having "pull" or + "client" in its configuration file. +* Security fix -- Potential DoS vulnerability on the + server in TCP mode. If the TCP server accept() call + returns an error status, the resulting exception handler + may attempt to indirect through a NULL pointer, causing + a segfault. Affects all OpenVPN 2.0 versions. * Fix attempt of assertion at multi.c:1586 (note that this precise line number will vary across different versions of OpenVPN). diff --git a/init.c b/init.c index 5f1a9bb..d6c13b2 100644 --- a/init.c +++ b/init.c @@ -2682,7 +2682,7 @@ inherit_context_child (struct context *dest, #endif /* context init */ - init_instance (dest, src->c2.es, CC_USR1_TO_HUP | CC_GC_FREE); + init_instance (dest, src->c2.es, CC_NO_CLOSE | CC_USR1_TO_HUP); if (IS_SIG (dest)) return; @@ -2756,6 +2756,9 @@ inherit_context_top (struct context *dest, void close_context (struct context *c, int sig, unsigned int flags) { + ASSERT (c); + ASSERT (c->sig); + if (sig >= 0) c->sig->signal_received = sig; @@ -2766,7 +2769,8 @@ close_context (struct context *c, int sig, unsigned int flags) c->sig->signal_received = SIGHUP; } - close_instance (c); + if (!(flags & CC_NO_CLOSE)) + close_instance (c); if (flags & CC_GC_FREE) context_gc_free (c); diff --git a/init.h b/init.h index edc9aee..3c159d5 100644 --- a/init.h +++ b/init.h @@ -94,6 +94,8 @@ void inherit_context_top (struct context *dest, #define CC_GC_FREE (1<<0) #define CC_USR1_TO_HUP (1<<1) #define CC_HARD_USR1_TO_HUP (1<<2) +#define CC_NO_CLOSE (1<<3) + void close_context (struct context *c, int sig, unsigned int flags); struct context_buffers *init_context_buffers (const struct frame *frame); diff --git a/multi.c b/multi.c index 45cdf5c..a425c19 100644 --- a/multi.c +++ b/multi.c @@ -577,10 +577,10 @@ multi_create_instance (struct multi_context *m, const struct mroute_addr *real) generate_prefix (mi); } + mi->did_open_context = true; inherit_context_child (&mi->context, &m->top); if (IS_SIG (&mi->context)) goto err; - mi->did_open_context = true; mi->context.c2.context_auth = CAS_PENDING; diff --git a/openvpn.h b/openvpn.h index a8d4f5e..318f10d 100644 --- a/openvpn.h +++ b/openvpn.h @@ -398,10 +398,11 @@ struct context_2 in_addr_t push_ifconfig_remote_netmask; /* client authentication state */ -# define CAS_SUCCEEDED 0 -# define CAS_PENDING 1 -# define CAS_FAILED 2 -# define CAS_PARTIAL 3 /* at least one client-connect script/plugin +# define CAS_UNDEF 0 +# define CAS_SUCCEEDED 1 +# define CAS_PENDING 2 +# define CAS_FAILED 3 +# define CAS_PARTIAL 4 /* at least one client-connect script/plugin succeeded while a later one in the chain failed */ int context_auth; #endif diff --git a/options.c b/options.c index 324d525..fbaef42 100644 --- a/options.c +++ b/options.c @@ -2274,7 +2274,7 @@ foreign_option (struct options *o, char *argv[], int len, struct env_set *es) { if (!first) buf_printf (&value, " "); - buf_printf (&value, argv[i]); + buf_printf (&value, "%s", argv[i]); first = false; } } -- cgit