]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
tun: properly handle device interface list
authorLev Stipakov <lev@openvpn.net>
Sun, 14 Aug 2022 21:53:03 +0000 (23:53 +0200)
committerGert Doering <gert@greenie.muc.de>
Tue, 16 Aug 2022 06:00:52 +0000 (08:00 +0200)
Device interface is a path which is used by userspace
to access device. A driver can create one or more device
interfaces and specify "reference string", so that userspace
could enumerate all device interfaces in the list and pick
the corrct one which ends with reference string.

Before our code had an assumption that either driver
creates only one device interface or the "right" interface
is alwways first in the list. As it turned out, that assumtion
does not always hold, so here we iterate through all device
interfaces in the list.

In follow-up dco-win patch we pick the device interface
from the list which ends with specific reference string.

v3: change allocation to use regular gc_malloc() instead of buffer.

Signed-off-by: Lev Stipakov <lev@openvpn.net>
Acked-by: Antonio Quartulli <a@unstable.cc>
Message-Id: <20220814215303.305-1-lstipakov@gmail.com>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg24938.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
src/openvpn/tun.c
src/openvpn/tun.h

index 11025267e8b8adebea7e6c3298d0760b3a5ec807..501939398b7f4bc6555a09a7e97f12c7bbad7250 100644 (file)
@@ -3722,7 +3722,6 @@ get_device_instance_id_interface(struct gc_arena *gc)
         LONG status;
         ULONG dev_interface_list_size;
         CONFIGRET cr;
-        struct buffer dev_interface_list;
 
         ZeroMemory(&device_info_data, sizeof(SP_DEVINFO_DATA));
         device_info_data.cbSize = sizeof(SP_DEVINFO_DATA);
@@ -3775,9 +3774,9 @@ get_device_instance_id_interface(struct gc_arena *gc)
             goto next;
         }
 
-        dev_interface_list = alloc_buf_gc(dev_interface_list_size, gc);
+        char *dev_interface_list = gc_malloc(dev_interface_list_size, false, gc);
         cr = CM_Get_Device_Interface_List((LPGUID)&GUID_DEVINTERFACE_NET, device_instance_id,
-                                          BSTR(&dev_interface_list),
+                                          dev_interface_list,
                                           dev_interface_list_size,
                                           CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
         if (cr != CR_SUCCESS)
@@ -3785,21 +3784,29 @@ get_device_instance_id_interface(struct gc_arena *gc)
             goto next;
         }
 
-        struct device_instance_id_interface *dev_if;
-        ALLOC_OBJ_CLEAR_GC(dev_if, struct device_instance_id_interface, gc);
-        dev_if->net_cfg_instance_id = (unsigned char *)string_alloc((char *)net_cfg_instance_id, gc);
-        dev_if->device_interface_list = string_alloc(BSTR(&dev_interface_list), gc);
+        char *dev_if = dev_interface_list;
 
-        /* link into return list */
-        if (!first)
+        /* device interface list ends with empty string */
+        while (strlen(dev_if) > 0)
         {
-            first = dev_if;
-        }
-        if (last)
-        {
-            last->next = dev_if;
+            struct device_instance_id_interface *dev_iif;
+            ALLOC_OBJ_CLEAR_GC(dev_iif, struct device_instance_id_interface, gc);
+            dev_iif->net_cfg_instance_id = (unsigned char *)string_alloc((char *)net_cfg_instance_id, gc);
+            dev_iif->device_interface = string_alloc(dev_if, gc);
+
+            /* link into return list */
+            if (!first)
+            {
+                first = dev_iif;
+            }
+            if (last)
+            {
+                last->next = dev_iif;
+            }
+            last = dev_iif;
+
+            dev_if += strlen(dev_if) + 1;
         }
-        last = dev_if;
 
 next:
         RegCloseKey(dev_key);
@@ -6475,12 +6482,11 @@ tun_try_open_device(struct tuntap *tt, const char *device_guid, const struct dev
     {
         const struct device_instance_id_interface *dev_if;
 
-        /* Open Wintun adapter */
         for (dev_if = device_instance_id_interface; dev_if != NULL; dev_if = dev_if->next)
         {
             if (strcmp((const char *)dev_if->net_cfg_instance_id, device_guid) == 0)
             {
-                path = dev_if->device_interface_list;
+                path = dev_if->device_interface;
                 break;
             }
         }
index ea4946e929cb307e32a6e6f920830c46c0187d85..661e4d015d653287522804e78133a0494f422d5a 100644 (file)
@@ -388,7 +388,7 @@ struct panel_reg
 struct device_instance_id_interface
 {
     LPBYTE net_cfg_instance_id;
-    const char *device_interface_list;
+    const char *device_interface;
     struct device_instance_id_interface *next;
 };