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>
This commit is contained in:
parent
7f5ad3e503
commit
23bf3cfccb
|
@ -57,10 +57,31 @@ public class WireGuardAdapter {
|
||||||
|
|
||||||
/// Tunnel device file descriptor.
|
/// Tunnel device file descriptor.
|
||||||
private var tunnelFileDescriptor: Int32? {
|
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 {
|
for fd: Int32 in 0...1024 {
|
||||||
var len = socklen_t(buf.count)
|
var addr = sockaddr_ctl()
|
||||||
if getsockopt(fd, SYSPROTO_CONTROL, 2, &buf, &len) == 0 && String(cString: buf).hasPrefix("utun") {
|
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
|
return fd
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,3 +3,18 @@
|
||||||
|
|
||||||
#include "key.h"
|
#include "key.h"
|
||||||
#include "x25519.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];
|
||||||
|
};
|
||||||
|
|
Loading…
Reference in New Issue