Authentication Cache + Storage crash application
Closed this issue · 2 comments
Describe the issue
Application crash because of a req.auth.require(Something.self)
Vapor version
4.84.2
Operating system and version
macos 14.4.1 (23E224) apple m2
Swift version
Swift Package Manager - Swift 5.10.0-dev
Steps to reproduce
create a simple Vapor application and use this as handle and build in release mode.
struct Test: Authenticatable { }
func test(req: Request) async throws -> Response {
await withThrowingTaskGroup(of: Void.self) { group in
for i in (0...5) {
group.addTask {
try? req.auth.require(Test.self)
}
}
}
return .init()
}
call the handle, usually around the second call it crashes.
I've dug into the code and I've found that the problem is the following pattern inside a concurrently executing code
if let existing = req.storage.get(Test.self) {
req.logger.info("get")
} else {
req.storage[Test.self] = .init()
req.logger.info("Set")
}
This is exactly what we find here
vapor/Sources/Vapor/Authentication/AuthenticationCache.swift
Lines 84 to 97 in 11cdb29
Something like this fixes the issue, but I suppose it's too simple of a solution and also I don't know the performances impact it may have.
let lock: NIOLock = .init()
lock.withLock {
if let existing = req.storage.get(Test.self) {
req.logger.info("get")
} else {
req.storage[Test.self] = .init()
req.logger.info("Set")
}
}
Outcome
The program goes boom 😄
Additional notes
The same issue arises in an amazon linux 2 container with swift 5.7
@MFranceschi6 have you tried the latest version of Vapor? These should all be fixed in 4.86.0
@0xTim thank you very much, I also did a swift package update
before testing the bug.
I don't know why it didn't update the version of vapor.
Yep, now I've 4.92.5 and it works flawlessly thank you again