Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Race Condition when used in App Extension #164

Open
juliand665 opened this issue Mar 12, 2023 · 0 comments
Open

Race Condition when used in App Extension #164

juliand665 opened this issue Mar 12, 2023 · 0 comments

Comments

@juliand665
Copy link

I've been using KeychainSwift for a project of mine, and started running into issues when I added widgets. It was the most frustrating bug to track down, its reproduction at the mercy of iOS' decisions to update my widgets and of course happening so nondeterministically that I would have to wait for a week to be reasonably confident in any fix. Anyway, the bug was that I would lose data stored in the keychain from time to time.

When iOS spins up your app extension to update widgets, it can launch multiple processes, or the main app process might also be running, with the effect that you have multiple processes interfacing with the keychain at the same time. Because they are separate processes, the mutex mechanism you're using cannot do anything, so operations have to be atomic. However, this is not the case for the set function, because of this line:

deleteNoLock(key) // Delete any existing key before saving it

It does this to unify the code paths for adding a new value and updating an existing value. However, it makes it possible for another process to read the now-deleted value between the delete and add calls. Even without this unfortunate interleaving, it's possible that iOS terminates the process right in between these two as well. I'm not sure which of these caused the issue more often, because I wouldn't expect the former to result in the deletion being written back somehow, but the data would often disappear permanently, so something was definitely up.

Anyway, I ended up fixing the issue for myself by dropping the dependency on KeychainSwift and implementing the necessary logic myself, which turned out to not be as bad as I feared. Figured I'd let you know though!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant