Summary

UaP in AudioScheduledSourceHandler::NotifyEnded

Product

Chrome

CVE

CVE-2020-6429

Tested Version

Chrome version: master branch build e577636, release build 80.3987.122 Operating System: Ubuntu 18.04

Details

This issue is similar to 1055788, in that an AudioHandler is being posted to a task queue as a scoped_refptr and the context_ UntracedMember is destroyed while it is waiting in the task queue.

The AudioScheduledSourceHandler::Finish method is called in the pre-rendering stage when DeferredTaskHandler::HandlePreRenderTask is called and a stop is scheduled. (OfflineAudioContext::HandlePreRenderTasks -> HandleStoppableSourceNodes -> AudioScheduledSourceHandler::HandleStoppableSourceNode -> AudioScheduledSourceHandler::Finish)

This method posts a task to the main thread, wrapping the handler as a scoped_refptr:

void AudioScheduledSourceHandler::Finish() {
  FinishWithoutOnEnded();

  PostCrossThreadTask(
      *task_runner_, FROM_HERE,
      CrossThreadBindOnce(&AudioScheduledSourceHandler::NotifyEnded,
                          WrapRefCounted(this)));
}

The AudioScheduledSourceHandler::NotifyEnded method then calls GetExecutionContext. However, it is possible for context_ to be destroyed while NotifyEnded is waiting in the queue. This will cause UaP/UaF when Context()->GetExecutionContext() is called in NotifyEnded.

void AudioScheduledSourceHandler::NotifyEnded() {
  DCHECK(IsMainThread());
  if (!Context() || !Context()->GetExecutionContext()) 
    return;
  if (GetNode())
    GetNode()->DispatchEvent(*Event::Create(event_type_names::kEnded));
}

A more detailed analysis can be found in ticket 1055788.

Impact

Use-after-free in renderer.

Coordinated Disclosure Timeline

Credit

This issue was discovered and reported by GHSL team member @m-y-mo (Man Yue Mo).

Contact

You can contact the GHSL team at securitylab@github.com, please include the GHSL-2020-038 in any communication regarding this issue.