aboutsummaryrefslogtreecommitdiffstats
path: root/Sources
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2021-06-16 17:09:40 +0200
committerJason A. Donenfeld <Jason@zx2c4.com>2021-06-16 17:40:12 +0200
commit23bf3cfccb5a6fa9faf85c35ca24ec4c3e29c3fe (patch)
tree17fdcb0327ab8bcf03da407beabef80c8702f17b /Sources
parentKit: Adapter: iterate through all FDs to find UTUN (diff)
downloadwireguard-apple-23bf3cfccb5a6fa9faf85c35ca24ec4c3e29c3fe.tar.xz
wireguard-apple-23bf3cfccb5a6fa9faf85c35ca24ec4c3e29c3fe.zip
Kit: Adapter: use more reliable utun detection technique
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>
Diffstat (limited to 'Sources')
-rw-r--r--Sources/WireGuardKit/WireGuardAdapter.swift27
-rw-r--r--Sources/WireGuardKitC/WireGuardKitC.h15
2 files changed, 39 insertions, 3 deletions
diff --git a/Sources/WireGuardKit/WireGuardAdapter.swift b/Sources/WireGuardKit/WireGuardAdapter.swift
index b18769e..57e0b58 100644
--- a/Sources/WireGuardKit/WireGuardAdapter.swift
+++ b/Sources/WireGuardKit/WireGuardAdapter.swift
@@ -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
}
}
diff --git a/Sources/WireGuardKitC/WireGuardKitC.h b/Sources/WireGuardKitC/WireGuardKitC.h
index d50a4fe..212fc22 100644
--- a/Sources/WireGuardKitC/WireGuardKitC.h
+++ b/Sources/WireGuardKitC/WireGuardKitC.h
@@ -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];
+};