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

Olm is prone to race conditions across multiple tabs #2325

Closed
richvdh opened this issue Sep 21, 2016 · 11 comments
Closed

Olm is prone to race conditions across multiple tabs #2325

richvdh opened this issue Sep 21, 2016 · 11 comments
Assignees
Labels
A-E2EE P1 S-Major Severely degrades major functionality or product features, with no satisfactory workaround T-Defect
Milestone

Comments

@richvdh
Copy link
Member

richvdh commented Sep 21, 2016

If you have multiple tabs open for the same account, they will fight over the localstorage and corrupt each other.

Simple example: Two tabs run the "generate ephemeral keys" timer at the same time. They generate different keys, but only one set is successfully persisted in the Olm account. I suspect this has been happening to trilobite17, who likes to have multiple tabs open.

Another example:

  • User sends a message in Tab 1. We do not have a session with Bob, so we claim a one-time key for him and half the rest of the room
  • Tab 1 starts generating outbound sessions with all of the devices in the room
  • Meanwhile, Tab 2 receives a prekey message from Bob. It creates the inbound session and removes the ephemeral key from the account (and saves the account and new session).
  • Tab 1 generates a new outbound session with Bob and saves it, dropping the inbound session
@richvdh richvdh changed the title Olm is prone to race conditions Olm is prone to race conditions across multiple tabs Sep 21, 2016
@richvdh richvdh added the A-E2EE label Sep 21, 2016
@richvdh richvdh added the P1 label Oct 3, 2016
@richvdh
Copy link
Member Author

richvdh commented Oct 3, 2016

I think this is important.

@richvdh richvdh added S-Major Severely degrades major functionality or product features, with no satisfactory workaround T-Defect labels Oct 31, 2016
@richvdh
Copy link
Member Author

richvdh commented Nov 20, 2016

I've been doing some thinking about this.

Implementing race-free concurrency between tabs via localstorage is hard, because Chrome (at least) just doesn't provide any promises in this area. We have no idea how long it takes a write in one process to be reflected in another, which makes any read-modify-write process inherently racy.

Some options might be:

  1. Something quite slow via localstorage, like writing to a slot to claim a lock, then sleeping for a while to check we got it.
  2. Use a shared Web Worker (ie, a single worker thread shared between all tabs on a domain), to do the crypto work. This would solve any concurrency problems for us, although it might introduce headaches in terms of how we manage upgrades of the worker thread. However, the main problem is that they aren't supported by Safari, nor do they look likely to be.
  3. Use a Service Worker (some sort of fancy-pants cache manager: again, shared between the tabs). All the problems of Shared Web Workers with none of the advantages (although Webkit are still thinking about implementing this one).
  4. Use IndexedDB for storage, instead of localstorage. This has the benefit of having defined transactional semantics; it may also provide a larger storage capacity. However, it isn't supported in Firefox incognito mode, currently.

I guess we want to use IndexedDB with fallback to Localstorage.

@ara4n ara4n added P2 and removed P1 labels Dec 7, 2016
@richvdh
Copy link
Member Author

richvdh commented Dec 21, 2016

This causes corrupted olm sessions, so really does need to be p1

@richvdh richvdh added P1 and removed P2 labels Dec 21, 2016
@richvdh
Copy link
Member Author

richvdh commented Jan 6, 2017

The situation is even worse with electron, which totally ignores updates which happen in another process: see electron/electron#2493. I have no idea how to fix this, currently.

@richvdh
Copy link
Member Author

richvdh commented Jan 30, 2017

I can definitely reproduce this. Opening riot in two tabs (and sending messages from them) can break communication with peers in both directions.

@lampholder
Copy link
Member

lampholder commented Apr 3, 2017

The secret third option is to bully people into only using one tab (but I don't like this).

I like the idea of using IndexedDB; falling back to localstorage sounds like it will still have all the same problems when we do fall back - could we consider just not supporting firefox incognito until we have the bandwidth to carve out a reliable localstorage fallback option?

@lampholder lampholder modified the milestones: RW002 - candidates, RW003 - candidates Apr 3, 2017
@dbkr
Copy link
Member

dbkr commented Apr 27, 2017

The electron app is now single-instance, so this should mitigate this on electron.

@richvdh
Copy link
Member Author

richvdh commented May 16, 2017

This will also be a problem for syncing device lists.

@lampholder lampholder modified the milestones: RW003, RW004 - candidates May 18, 2017
@dbkr
Copy link
Member

dbkr commented Nov 20, 2017

Conclusion for Firefox private tabs is to fall back to in-memory storage for the crypto store rather than trying to keep the localstorage-backed session store as a fallback. The one downside of this is that e2e data won't be persisted if you hit refresh.

@dbkr
Copy link
Member

dbkr commented Nov 22, 2017

Actually thinking about this more, the failure mode on upgrading would be terrible since you'd hit the update button in the new version bar and it would throw away all your e2e data. I've made it fall back to localstorage.

@dbkr
Copy link
Member

dbkr commented Feb 5, 2018

This should be fixed now all the various parts have been migrated to indexeddb!

@dbkr dbkr closed this as completed Feb 5, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-E2EE P1 S-Major Severely degrades major functionality or product features, with no satisfactory workaround T-Defect
Projects
None yet
Development

No branches or pull requests

4 participants