New issue
Advanced search Search tips

Issue 803878 link

Starred by 1 user

Issue metadata

Status: Fixed
Owner:
Closed: Feb 2018
Cc:
EstimatedDays: ----
NextAction: ----
OS: ----
Pri: 3
Type: Bug



Sign in to add a comment

Use-after-free on TabStatsDataStore::OnTabReplaced

Project Member Reported by sebmarchand@chromium.org, Jan 19 2018

Issue description

There's a UAF in TabStatsDataStore::OnTabReplaced caused by this change: https://chromium-review.googlesource.com/c/chromium/src/+/867073/2/chrome/browser/metrics/tab_stats_data_store.cc#90

The problematic line of code is this one:
  existing_tabs_[new_contents] = existing_tabs_[old_contents];

here existing_tabs_ is a flat_map, the problem is that iterator and references returned by operator[] are not stable when using a flat_map. In this particular case the reference to |existing_tabs_[old_contents]| gets pushed onto the stack before evaluating |existing_tabs_[new_contents]|, which might require the underlying vector used by the flat_map to grow as it's adding an element to it, in this case the reference to |existing_tabs_[old_contents]| will be invalid (it'll point to the previous flat_map underlying vector).


(see report https://crash.corp.google.com/browse?q=reportid=%2765b751228ac53ab5%27)
 
Cc: fdoray@chromium.org dcheng@chromium.org
Hey dcheng@, FYI I hit this UAF when using a flat_map and I was wondering if it's worth updating the doc (at the top of flat_map.h) to add that references returned by operator[] are also invalidated across mutations? Or is the "Assume that every operation invalidates iterators and references" comment around line 188 sufficient?

I wouldn't be too surprised if there was more issues like this one in the codebase, it look like a really simple to make (it's trivial to fix it once you know it's there).

Having a linter to prevent this would be cool.
I forgot to mention it here but I'll fix this by using a temporary variable to hold the return value of |existing_tabs_[old_contents]|

Comment 3 by dcheng@chromium.org, Jan 20 2018

Cc: vmp...@chromium.org
I'm not sure: on one hand, I feel like it's kind of implied since the underlying collection is backed by a vector, but on the other, I can understand it's kind of surprising.

I'd probably just update the class usage notes to mention that this applies to references returned from operator[] as well: there's already a bullet point that says "Iterators are invalidated across mutations".
Cc: etienneb@chromium.org
My suggestion would be to just update the comment you're referring to to: "Iterators and references returned by operator[] are  invalidated across mutations".

+etienneb@ said that it'd be trivial to write a linter for this pattern, it's quite easy to make this mistake (e.g. you replace a map class member by a flat_map but you fail to notice that there's a foo[a] = foo[b] in the code), so I wouldn't be too surprised if there was more occurrences of this.
Status: Fixed (was: Started)

Sign in to add a comment