From: Lev Stipakov Date: Thu, 12 Mar 2020 06:08:29 +0000 (+0200) Subject: tun.c: fix 'use after free' error X-Git-Tag: v2.5_beta1~189 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5d28b47c51f4fcef631f9dae83f9cbc7120c6812;p=thirdparty%2Fopenvpn.git tun.c: fix 'use after free' error Commit 509c45f has factored out code blocks of open_tun() into separate functions and introduced "use after free" bug: Variable "device_guid" is allocated inside tun_open_device() function and used outside of it. Allocation happens with local gc_arena, which is freed at the end of tun_open_device(), making futher access to "device_guid" invalid. Fix by ensuring that gc_arena scope covers all access to "device_guid". Signed-off-by: Lev Stipakov Acked-by: Simon Rozman Message-Id: <20200312060829.19468-1-lstipakov@gmail.com> URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg19547.html Signed-off-by: Gert Doering --- diff --git a/src/openvpn/tun.c b/src/openvpn/tun.c index a81842fb7..f61c2a359 100644 --- a/src/openvpn/tun.c +++ b/src/openvpn/tun.c @@ -6239,12 +6239,11 @@ tun_try_open_device(struct tuntap *tt, const char *device_guid, const struct dev } static void -tun_open_device(struct tuntap *tt, const char *dev_node, const char **device_guid) +tun_open_device(struct tuntap *tt, const char *dev_node, const char **device_guid, struct gc_arena *gc) { - struct gc_arena gc = gc_new(); - const struct tap_reg *tap_reg = get_tap_reg(&gc); - const struct panel_reg *panel_reg = get_panel_reg(&gc); - const struct device_instance_id_interface *device_instance_id_interface = get_device_instance_id_interface(&gc); + const struct tap_reg *tap_reg = get_tap_reg(gc); + const struct panel_reg *panel_reg = get_panel_reg(gc); + const struct device_instance_id_interface *device_instance_id_interface = get_device_instance_id_interface(gc); char actual_buffer[256]; at_least_one_tap_win(tap_reg); @@ -6257,7 +6256,7 @@ tun_open_device(struct tuntap *tt, const char *dev_node, const char **device_gui enum windows_driver_type windows_driver = WINDOWS_DRIVER_UNSPECIFIED; /* Get the device GUID for the device specified with --dev-node. */ - *device_guid = get_device_guid(dev_node, actual_buffer, sizeof(actual_buffer), &windows_driver, tap_reg, panel_reg, &gc); + *device_guid = get_device_guid(dev_node, actual_buffer, sizeof(actual_buffer), &windows_driver, tap_reg, panel_reg, gc); if (!*device_guid) { @@ -6289,7 +6288,7 @@ tun_open_device(struct tuntap *tt, const char *dev_node, const char **device_gui tap_reg, panel_reg, &windows_driver, - &gc); + gc); if (!*device_guid) { @@ -6317,8 +6316,6 @@ next: msg(M_INFO, "%s device [%s] opened", print_windows_driver(tt->windows_driver), tt->actual_name); tt->adapter_index = get_adapter_index(*device_guid); - - gc_free(&gc); } static void @@ -6424,13 +6421,16 @@ open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tun msg(M_FATAL|M_NOPREFIX, "Unknown virtual device type: '%s'", dev); } - tun_open_device(tt, dev_node, &device_guid); + struct gc_arena gc = gc_new(); /* used also for device_guid allocation */ + tun_open_device(tt, dev_node, &device_guid, &gc); if (tt->windows_driver == WINDOWS_DRIVER_TAP_WINDOWS6) { tuntap_post_open(tt, device_guid); } + gc_free(&gc); + /*netcmd_semaphore_release ();*/ }