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

Already on GitHub? Sign in to your account

Olm is prone to race conditions across multiple tabs #2325

Open
richvdh opened this Issue Sep 21, 2016 · 8 comments

Comments

Projects

Ready to Start in E2E Usability and Stability

4 participants
Contributor

richvdh commented Sep 21, 2016 edited

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 from Olm is prone to race conditions to Olm is prone to race conditions across multiple tabs Sep 21, 2016

@richvdh richvdh added the type:e2e label Sep 21, 2016

@richvdh richvdh added the p1 label Oct 3, 2016

Contributor

richvdh commented Oct 3, 2016

I think this is important.

@richvdh richvdh added major bug labels Oct 31, 2016

Contributor

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

Contributor

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

Contributor

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.

Contributor

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.

Owner

lampholder commented Apr 3, 2017 edited

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

@lampholder lampholder referenced this issue in vector-im/riot-meta Apr 12, 2017

Open

E2E stability and usability. #63

0 of 4 tasks complete
Owner

dbkr commented Apr 27, 2017

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

Contributor

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment