问题
The following code is used to convert a sockaddr
to a sockaddr_in6
to get the IPv6 address:
extension sockaddr {
private var addressV6: String {
var me = self
var buffer = [Int8](repeating: 0, count: Int(INET6_ADDRSTRLEN))
withUnsafePointer(to: &me) {
$0.withMemoryRebound(to: sockaddr_in6.self, capacity: 1) {
var addrV6 = $0.pointee.sin6_addr
inet_ntop(AF_INET6, &addrV6, &buffer, socklen_t(INET6_ADDRSTRLEN))
}
}
return String(cString: buffer)
}
}
When I run the code in Xcode 9 beta with the Address Sanitizer, execution stops on this line:
var addrV6 = $0.pointee.sin6_addr
With the following message (plus a lot of memory info):
AddressSanitizer: stack-buffer-overflow on address 0x000131810077 at pc 0x00010a3c06d5 bp 0x7fff55ded010 sp 0x7fff55ded008 READ of size 16 at 0x000131810077 thread T0
I can understand that the ASAN is concerned that I'm reading past the boundaries of the sockaddr
to get the full sockaddr_in6
(the sockaddr
is 16 bytes, the sockaddr_in6
is 28 bytes).
But I can't seem to test the rest of my app with the ASAN because of this. It seems a bit weird that any use of withMemoryRebound
would trip the ASAN.
I've tried to write it in different ways, even using Data
as a vessle for the bytes. But I always seem to end up with a solution that triggers the ASAN.
Is there something wrong with my code?
Or can I somehow ignore this function in the ASAN?
回答1:
The pointer returned by the getifaddrs
function looks like a sockaddr
pointer but is actually a pointer to sockaddr_in
or sockaddr_in6
. By moving the addressV6
function to an extension on sockaddr
, the memory was copied and cut to the size of a sockaddr
struct. In case of IPv6 valuable address information would get lost.
The new (trimmed) sockaddr
could never be converted to a sockaddr_in6
triggering the SAN.
For more information see: Swift getnameinfo unreliable results for IPv6
Thank you @MartinR for helping me with this!
来源:https://stackoverflow.com/questions/44426911/xcode-address-sanitizer-issue-with-sockaddr