]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
svn merge -r 734:737 $SO/trunk/openvpn
authorjames <james@e7ae566f-a301-0410-adde-c780ea21d3b5>
Mon, 31 Oct 2005 03:49:25 +0000 (03:49 +0000)
committerjames <james@e7ae566f-a301-0410-adde-c780ea21d3b5>
Mon, 31 Oct 2005 03:49:25 +0000 (03:49 +0000)
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
init.c
init.h
multi.c
openvpn.h
options.c

index edfc588a4da23a0895b652dc62f5b036730d1778..62307b2018c7ee0e46d95ad01771312b717c8580 100644 (file)
--- 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 5f1a9bb5e346a975baa2d16172e1a78d25a3c653..d6c13b2b33d05799f50739f8f5b31ebbe3027410 100644 (file)
--- 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 edc9aee5fcaff493adc8c71ecf9adda8f9505be4..3c159d53282c7bed3551e8814380d5c2f614ed90 100644 (file)
--- 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 45cdf5c98a9e002236175142b6d3a330abd00c8b..a425c196cde0ff8ff1654bc9aaefe17a10c25f5a 100644 (file)
--- 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;
 
index a8d4f5e2af313cbe33eaf56983a65b2b6159b84b..318f10d8344ecf2cf4662909682db450ed13bdd4 100644 (file)
--- 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
index 324d525be0f9594c51c7cba265ca393586160e20..fbaef42ba306f8decf1a683cb2623c6b08595875 100644 (file)
--- 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;
            }
        }