sockaddr的Xcode Address Sanitizer问题 [英] Xcode Address Sanitizer issue with sockaddr

查看:158
本文介绍了sockaddr的Xcode Address Sanitizer问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码用于将sockaddr转换为sockaddr_in6以获得IPv6地址:

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)
  }
}

当我使用Address Sanitizer在Xcode 9 beta中运行代码时,执行在这一行停止:

var addrV6 = $0.pointee.sin6_addr

显示以下消息(以及大量的内存信息):

AddressSanitizer:地址0x000131810077处的堆栈缓冲区溢出 pc 0x00010a3c06d5 bp 0x7fff55ded010 sp 0x7fff55ded008读取大小16 在0x000131810077线程T0

我可以理解ASAN担心我正在读取sockaddr的边界以获取完整的sockaddr_in6(sockaddr是16个字节,sockaddr_in6是28个字节). /p>

但是,由于这个原因,我似乎无法使用ASAN测试应用程序的其余部分.任何使用withMemoryRebound都会使ASAN跳闸似乎有点不可思议.

我试图以不同的方式编写它,甚至使用Data作为字节的容器.但是我似乎总是以触发ASAN的解决方案告终.

我的代码有问题吗?
还是可以以某种方式忽略ASAN中的此功能?

解决方案

getifaddrs函数返回的指针看起来像sockaddr指针,但实际上是指向sockaddr_insockaddr_in6的指针.通过将addressV6函数移动到sockaddr上的扩展名,可以复制内存并将其剪切为sockaddr结构的大小.如果使用IPv6,宝贵的地址信息将会丢失.

新的(修剪过的)sockaddr永远不会转换为触发SAN的sockaddr_in6.

有关更多信息,请参见: Swift getnameinfo对于IPv6的结果不可靠

感谢@MartinR为我提供帮助!

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?

解决方案

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!

这篇关于sockaddr的Xcode Address Sanitizer问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆