[PATCH v3] options: fix use-after-free of DNS options on client connect

Gert Doering <[email protected]>
Newsgroups gmane.network.openvpn.devel
Message-ID <[email protected]>
From: Antonio Quartulli <[email protected]>

struct dns_options embeds its own gc_arena. When inherit_context_child()
/inherit_context_top() copy struct options by value, the child shares the
parent's DNS arena. options_detach() detached o->gc but not
o->dns_options.gc, so pre_connect_restore()'s gc_free() (and context
teardown) freed allocations the parent still referenced.

With one or more non-pushed --dhcp-option directives that yield a DNS
entry, a connecting client triggers this and the server crashes
(use-after-free in setenv_dns_options(), reported as a double free).

Detach o->dns_options.gc as well, mirroring the existing o->gc handling.

Change-Id: I49b37b5a90554fa2d4a83c8fc5608dad2a36b835
GitHub: closes openvpn/OpenVPN#1060
Signed-off-by: Antonio Quartulli <[email protected]>
Acked-by: Arne Schwabe <[email protected]>
Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/1715
---

This change was reviewed on Gerrit and approved by at least one
developer. I request to merge it to master.

Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/1715
This mail reflects revision 3 of this Change.

Acked-by according to Gerrit (reflected above):
Arne Schwabe <[email protected]>

        
diff --git a/src/openvpn/options.c b/src/openvpn/options.c
index 0c2866c..75bd87c 100644
--- a/src/openvpn/options.c
+++ b/src/openvpn/options.c
@@ -1531,7 +1531,18 @@
 void
 options_detach(struct options *o)
 {
+    /* The options struct carries two gc_arena's (one generic and one specific
+     * to the DNS settings), which the by-value options
+     * copy in inherit_context_child()/inherit_context_top() shares with the
+     * source.
+     *
+     * Detach both (i.e. re-initialize them), otherwise child's call of
+     * gc_free() (or context teardown) would free allocations the source
+     * context still references, leading to a use-after-free (and subsequent
+     * double-free).
+     */
     gc_detach(&o->gc);
+    gc_detach(&o->dns_options.gc);
     o->routes = NULL;
     o->client_nat = NULL;
     clone_push_list(o);
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.