<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Swift 5.5 爆嚴(yán)重堆棧損壞 BUG

          共 5496字,需瀏覽 11分鐘

           ·

          2021-10-11 15:34


          最近,開發(fā)者 taylorswift 在 Swift 論壇發(fā)表了題為 《Swift 5.5 has serious stack corruption bugs!》的帖子,作者發(fā)現(xiàn)了幾個(gè)與 async/await 相關(guān)的堆棧損壞 BUG,這些 BUG 可以在使用最新的 toolchain 進(jìn)行編譯時(shí)重現(xiàn),并且方法很簡單。作者目前確認(rèn)了 5.5-RELEASE 的 toolchain 中至少存在 4 個(gè)相關(guān) BUG。讓我們一起來看看這些問題。

          使用異步閉包返回的值時(shí)堆棧損壞

          異步閉包的返回值在混亂但確定性的內(nèi)存偏移處被破壞。以下代碼可以復(fù)現(xiàn)這個(gè)問題:

          // async-return-value-corruption.swift

          @main
          enum Main
          {
          actor A
          {
          init()
          {
          }

          func a(_ f:@Sendable () async -> (Int, (Int, Int, Int, Int))?)
          async -> Void
          {
          guard let (head, tail):(Int, (Int, Int, Int, Int)) = await f()
          else
          {
          return
          }

          print((head, tail))
          return
          }
          }

          static
          func p() async -> Bool
          {
          true
          }

          static
          func main() async
          {
          while true
          {
          let a:A = .init()

          async let task:Void = a.a
          {
          if await Self.p()
          {
          return (0, (0, 0, 0 ,0))
          }
          else
          {
          return nil
          }
          }
          await task
          }
          }
          }

          結(jié)果如下:

          $ swiftc --version
          Swift version 5.5 (swift-5.5-RELEASE)
          Target: x86_64-unknown-linux-gnu

          $ swiftc -parse-as-library -O async-return-value-corruption.swift
          $ ./async-return-value-corruption

          (139787763716080, (0, 0, 0, 0))
          (139787629498352, (0, 0, 0, 0))
          (139787965042672, (0, 0, 0, 0))
          (139787763716080, (0, 0, 0, 0))
          (139787629498352, (0, 0, 0, 0))
          ...

          使用 async let 時(shí)出現(xiàn)分段錯(cuò)誤

          相對簡單的 async 用法在調(diào)試和發(fā)布版本中都會(huì)遇到分段錯(cuò)誤。雖然作者最初認(rèn)為這僅限于在 main 函數(shù)中使用 async let ,但此后作者也在各種其他上下文中觀察到了這個(gè)問題。

          // async-let-segfault.swift 
          @main
          enum Main
          {
          static
          func foo() async -> [Void]
          {
          try? await Task.sleep(nanoseconds: 1)
          return []
          }
          static
          func main() async
          {
          async let task:Void =
          {
          () async -> () in
          try? await Task.sleep(nanoseconds: 1)
          }()
          while true
          {
          let _:[Void] = await Self.foo()
          }
          }
          }

          結(jié)果

          $ swiftc --version
          Swift version 5.5 (swift-5.5-RELEASE)
          Target: x86_64-unknown-linux-gnu

          $ swiftc -O -parse-as-library async-let-segfault.swift
          async-let-segfault.swift:23:15: warning: will never be executed
          await task
          ^
          async-let-segfault.swift:19:15: note: condition always evaluates to true
          while true
          ^
          $ ./async-let-segfault
          Segmentation fault (core dumped)

          將枚舉傳遞給 actor-isolated 的方法時(shí)堆棧損壞

          actor-isolated 方法接收到的枚舉值與調(diào)用者傳遞的值不同。作者在調(diào)試和發(fā)布版本中都觀察到了這個(gè)問題,但在調(diào)試版本中更為常見和可重現(xiàn)。所有最近的版本,包括 5.5-RELEASE、DEVELOPMENT-SNAPSHOT-2021-09-23-a,都會(huì)受到影響。

          // async-stack-corruption.swift 

          struct Users
          {
          enum Access
          {
          case guest
          case admin(Int)
          case developer(Int, Int, Int, Int)
          }
          actor State
          {
          init()
          {
          }
          func set(permissions:(user:Int, access:Access?))
          {
          print(permissions)
          }
          }

          let state:State = .init()

          func set(permissions:(user:Int, access:Access?)) async
          {
          await self.state.set(permissions: permissions)
          }
          }
          @main
          enum Main
          {
          static
          func main() async
          {
          let users:Users = .init()
          let stream:AsyncStream<Int> = .init
          {
          for i in 0 ..< 10
          {
          $0.yield(i)
          }
          $0.finish()
          }
          for await i:Int in stream
          {
          await users.set(permissions: (i, .guest))
          }
          }
          }

          結(jié)果

          $ swiftc --version
          Swift version 5.6-dev (LLVM ae102eaadf2d38c, Swift be2d00b32742678)
          Target: x86_64-unknown-linux-gnu
          $ swiftc -parse-as-library async-stack-corruption.swift
          $ ./async-stack-corruption
          (user: 0, access: Optional(main.Users.Access.admin(0)))
          (user: 1, access: Optional(main.Users.Access.admin(0)))
          (user: 2, access: Optional(main.Users.Access.admin(0)))
          (user: 3, access: Optional(main.Users.Access.admin(0)))
          (user: 4, access: Optional(main.Users.Access.admin(0)))
          (user: 5, access: Optional(main.Users.Access.admin(0)))
          (user: 6, access: Optional(main.Users.Access.admin(0)))
          (user: 7, access: Optional(main.Users.Access.admin(0)))
          (user: 8, access: Optional(main.Users.Access.admin(0)))
          (user: 9, access: Optional(main.Users.Access.admin(0)))

          作者遇到了額外的內(nèi)存損壞錯(cuò)誤,包括在 actor-isolated 的屬性(線程 8)上調(diào)用實(shí)例方法時(shí)有些奇怪,但這 3 個(gè)是作者本周遇到的問題,并已將它們歸檔為:

          1. SR-15225?https://bugs.swift.org/browse/SR-15225

          2. SR-15241?https://bugs.swift.org/browse/SR-15241

          3. SR-15240?https://bugs.swift.org/browse/SR-15240

          在作者看來,錯(cuò)誤 (1) 是迄今為止最危險(xiǎn)的,因?yàn)樗悄l(fā)生的,并且會(huì)影響 5.5 版本的工具鏈。與 bug (3) 一樣,bug (1) 也代表了一個(gè)潛在的安全漏洞,盡管它可能不容易在自然發(fā)生的代碼中被利用。

          作者發(fā)現(xiàn)錯(cuò)誤 (3) 確實(shí)出現(xiàn)在使用 5.5 版本工具鏈構(gòu)建的二進(jìn)制文件中,它們都根據(jù)微小的代碼更改變成段錯(cuò)誤,所以到目前為止只能作為段錯(cuò)誤重現(xiàn)的錯(cuò)誤 (2) 也可能表現(xiàn)為無形漏洞。

          作者建議使用并發(fā)特性的開發(fā)人員不應(yīng)該發(fā)布任何用 5.5 工具鏈編譯的東西,直到這些問題得到修復(fù)并發(fā)布補(bǔ)丁。

          SIMD 類型 BUG

          看起來任務(wù)組和具有廣泛對齊的 SIMD 類型還有另一個(gè)問題。作者已經(jīng)確認(rèn)這個(gè)問題也會(huì)影響 5.5-RELEASE 工具鏈,能夠在調(diào)試和發(fā)布版本中重現(xiàn)它。

          @main
          enum Main
          {
          static
          func main() async
          {
          await withTaskGroup(of: SIMD4<Int32>.self)
          {
          (group:inout TaskGroup) in
          group.addTask
          {
          return SIMD4<Int32>.init(repeating: 0)
          }
          }
          }
          }

          結(jié)果

          $ swiftc --version
          Swift version 5.5 (swift-5.5-RELEASE)
          Target: x86_64-unknown-linux-gnu
          $ swiftc -O -parse-as-library async-stack-corruption-simd.swift
          $ ./async-stack-corruption-simd
          Segmentation fault (core dumped)

          目前這個(gè)帖子在論壇中引起了廣泛的關(guān)注。Swift 5.5 給開發(fā)者帶來了很多新特性,特別是在異步編程方面。但似乎 Swift 還有許多路要走,要想獲得更廣泛的應(yīng)用,必須確保語言自身的穩(wěn)定性,相信核心團(tuán)隊(duì)也意識到這些問題。

          瀏覽 24
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚州精品天堂中文字幕 | 国产又黄又嫩又滑又白 | 伊人sv | 国产三级日本三级国产三级 | 人人看人人插摸 |