swift - Xcode Address Sanitizer 与 sockaddr 的问题

标签 swift xcode pointers 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: stack-buffer-overflow on address 0x000131810077 at pc 0x00010a3c06d5 bp 0x7fff55ded010 sp 0x7fff55ded008 READ of size 16 at 0x000131810077 thread T0

我可以理解,ASAN 担心我读取的内容超出了 sockaddr 的边界,以获取完整的 sockaddr_in6(sockaddr > 为 16 字节,sockaddr_in6 为 28 字节)。

但因此我似乎无法使用 ASAN 测试我的应用程序的其余部分。任何使用 withMemoryRebound 都会使 ASAN 出错,这似乎有点奇怪。

我尝试以不同的方式编写它,甚至使用Data作为字节的容器。但我似乎总是最终得到一个触发 ASAN 的解决方案。

我的代码有问题吗?
或者我可以以某种方式忽略 ASAN 中的这个功能吗?

最佳答案

getifaddrs 返回的指针函数看起来像 sockaddr指针但实际上是指向 sockaddr_in 的指针或sockaddr_in6 。通过移动addressV6函数 sockaddr 上的扩展,内存被复制并剪切为 sockaddr 的大小结构。如果使用 IPv6,有值(value)的地址信息将会丢失。

新的(已修剪)sockaddr永远无法转换为 sockaddr_in6触发 SAN。

欲了解更多信息,请参阅: Swift getnameinfo unreliable results for IPv6

感谢@MartinR 帮助我解决这个问题!

关于swift - Xcode Address Sanitizer 与 sockaddr 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44426911/

相关文章:

iOS 自动布局 - 尽管设置了限制,但图像和屏幕顶部之间存在间隙

c++ - C++ 类上下文中的引用和指针

c++ - DWORD 在 LPVOID 上的类型转换返回什么?

ios - 隐藏通过 NotificationService Extension 收到的通知

swift - Swift 中的 CoreMIDI 回调

ios - 使用广播 UI 扩展显示 UI(可能是 Storyboard)

iphone - 如何向用户显示我的App当前的项目版本?

c++ - 使用 pop_back 时防止指针失效

ios - 创建需要(依赖于)另一个框架的框架

ios - View Debug 中的 Collection View Frame 与代码不同