]> git.ipfire.org Git - thirdparty/wireguard-apple.git/commitdiff
Kit: Adapter: use more reliable utun detection technique
authorJason A. Donenfeld <Jason@zx2c4.com>
Wed, 16 Jun 2021 15:09:40 +0000 (17:09 +0200)
committerJason A. Donenfeld <Jason@zx2c4.com>
Wed, 16 Jun 2021 15:40:12 +0000 (17:40 +0200)
Rather than hoping that the AF_SYSTEM fd is of type utun, and then
calling "2" on it to get the name -- which could be defined as something
else for a different AF_SYSTEM socket type -- instead simply query the
AF_SYSTEM control socket ID with getpeername. This has one catch, which
is that the ID is dynamically allocated, so we resolve it using the
qualified name. Normally we'd make a new AF_SYSTEM socket for this, but
since that's not allowed in the sandbox, we reuse the AF_SYSTEM socket
that we're checking. At this point in the flow, we know that it's a
proper AF_SYSTEM one, based on the first sockaddr member; we just don't
know that it's a utun variety.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Sources/WireGuardKit/WireGuardAdapter.swift
Sources/WireGuardKitC/WireGuardKitC.h

index b18769e4cd815fe715f466b7ef37828c8d1415f9..57e0b58111755d1994ab3365d4bdbae9cb09f3ab 100644 (file)
@@ -57,10 +57,31 @@ public class WireGuardAdapter {
 
     /// Tunnel device file descriptor.
     private var tunnelFileDescriptor: Int32? {
-        var buf = [CChar](repeating: 0, count: Int(IFNAMSIZ))
+        var ctlInfo = ctl_info()
+        withUnsafeMutablePointer(to: &ctlInfo.ctl_name) {
+            $0.withMemoryRebound(to: CChar.self, capacity: MemoryLayout.size(ofValue: $0.pointee)) {
+                _ = strcpy($0, "com.apple.net.utun_control")
+            }
+        }
         for fd: Int32 in 0...1024 {
-            var len = socklen_t(buf.count)
-            if getsockopt(fd, SYSPROTO_CONTROL, 2, &buf, &len) == 0 && String(cString: buf).hasPrefix("utun") {
+            var addr = sockaddr_ctl()
+            var ret: Int32 = -1
+            var len = socklen_t(MemoryLayout.size(ofValue: addr))
+            withUnsafeMutablePointer(to: &addr) {
+                $0.withMemoryRebound(to: sockaddr.self, capacity: 1) {
+                    ret = getpeername(fd, $0, &len)
+                }
+            }
+            if ret != 0 || addr.sc_family != AF_SYSTEM {
+                continue
+            }
+            if ctlInfo.ctl_id == 0 {
+                ret = ioctl(fd, CTLIOCGINFO, &ctlInfo)
+                if ret != 0 {
+                    continue
+                }
+            }
+            if addr.sc_id == ctlInfo.ctl_id {
                 return fd
             }
         }
index d50a4fe61eb020dc851c4aef12fc44af3d678fa8..212fc22a5bd7d4c3ab30a4ecbe509dd847637e4b 100644 (file)
@@ -3,3 +3,18 @@
 
 #include "key.h"
 #include "x25519.h"
+
+/* From <sys/kern_control.h> */
+#define CTLIOCGINFO 0xc0644e03UL
+struct ctl_info {
+    u_int32_t   ctl_id;
+    char        ctl_name[96];
+};
+struct sockaddr_ctl {
+    u_char      sc_len;
+    u_char      sc_family;
+    u_int16_t   ss_sysaddr;
+    u_int32_t   sc_id;
+    u_int32_t   sc_unit;
+    u_int32_t   sc_reserved[5];
+};