Swift 5.5 has serious stack corruption bugs!

after investigating further, it looks like bug #3, or at least a variant of it does in fact affect the 5.5-RELEASE toolchain.

a modified example program to reproduce this problem is given below:

struct Users
{
    enum Access 
    {
        case guest
        case admin(Int)
        case developer(Int, Int, Int, Int)
    }
    
    private 
    actor User 
    {
        init()
        {
        }
        
        func set(permissions:(Int, Access?))
        {
            print(permissions)
        }
    }
    
    private 
    let users:[Int: User] = [0: .init()]
    
    func set(permissions:(Int, Access?)) async 
    {
        print(permissions)
        guard let user:User = self.users[permissions.0]
        else 
        {
            print(" \(permissions.0) ")
            return  
        }
        await user.set(permissions: permissions)
    }
}

@main 
enum Main 
{
    static 
    func main() async
    {
        let coordinator:Users = .init()
        let stream:AsyncStream<Int> = .init 
        {
            for i in 0 ..< 10
            {
                $0.yield(i) 
            }
            $0.finish()
        }

        for await i:Int in stream
        {
            if i != 0 
            {
                continue 
            }
            await coordinator.set(permissions: (i, .guest))
        }
    }
}
$ swiftc --version
Swift version 5.5 (swift-5.5-RELEASE)
Target: x86_64-unknown-linux-gnu
$ swiftc -O -parse-as-library async-stack-corruption-5.5.swift
$ ./async-stack-corruption-5.5 
(0, Optional(main.Users.Access.admin(144)))
(0, Optional(main.Users.Access.admin(144)))

moreover, while investigating this bug, i also noticed that i could influence the specific enum cases that the real values are overwritten with based on user input. this means that (alongside SR-15225) SR-15240 represents a major security vulnerability in Swift 5.5. it is also highly chaotic — removing or reordering any of the print statements in this program completely changes the behavior — so it is extremely likely that a minor change in your codebase before a release could silently introduce a vulnerability.

again, i would urge anyone using the 5.5-RELEASE toolchain to either avoid concurrency features, or assume that all binaries compiled with it are compromised.

9 Likes