Summary
UaF in DeferredTaskHandler::BreakConnections
Product
Chrome
CVE
CVE-2020-6428
Tested Version
Chromium version: master branch build e577636 Also tested on release google Chrome 80.3987.122 Operating System: linux 18.04
Details
When HandlePreRenderTask is called during the rendering, it will check whether any source node should be stopped[1]. If an AudioScheduleSourceNode, (e.g. ConstantSourceNode) is to be stopped at or before the frame [2], it will then call the AudioScheduledSourceHandler::Finish() method, which calls FinishWithoutOnEnded. This has 2 effects:
-
It calls BaseAudioContext::NotifySourceNodeFinishedProcessing[3], which will add theAudioScheduledSourceHandlerin thefinished_source_handlers_vector, as raw pointer.
void BaseAudioContext::NotifySourceNodeFinishedProcessing(
AudioHandler* handler) {
DCHECK(IsAudioThread());
GetDeferredTaskHandler().GetFinishedSourceHandlers()->push_back(handler);
}
- It sets the playback state of the
AudioScheduledSourceHandlertoFINISHED_STATE, allowing theAudioScheduledSourceNodeto be deleted[4].
If a suspend is also scheduled at the same frame, we can then return to main thread and delete the AudioScheduleSourceNode. This is ok as the AudioScheduleSourceHandler is also being kept alive in |
active_source_handlers_ |
when the start method of the source node is called[5], which is held in the BaseAudioContext. |
void BaseAudioContext::NotifySourceNodeStartedProcessing(AudioNode* node) {
DCHECK(IsMainThread());
GraphAutoLocker locker(this);
GetDeferredTaskHandler().GetActiveSourceHandlers()->insert(&node->Handler());
node->Handler().MakeConnection();
}
When the BaseAudioContext is resumed, it will call the DeferredTaskHandler::BreakConnection method in the HandlePostRenderTasks method[6] to finish off with the AudioScheduleSourceNode:
void DeferredTaskHandler::BreakConnections() {
...
wtf_size_t size = finished_source_handlers_.size();
if (size > 0) {
for (auto* finished : finished_source_handlers_) {
active_source_handlers_.erase(finished); //<-- finished is now free'd
finished->BreakConnectionWithLock(); //<-- UaF
}
finished_source_handlers_.clear();
}
}
The problem, however, is that BreakConnections first erase the handler before using it in the next line. As the handler is now only kept alive by |
active_source_handlers_ |
, this deletes the handler and causes UaF. |
-
https://source.chromium.org/chromium/chromium/src/+/71825939c432c440fa53ef4016372076e2c6114a:third_party/blink/renderer/modules/webaudio/offline_audio_context.cc;l=413;drc=b892cf58e162a8f66cd76d7472f129fe0fb6a7d1;bpv=1;bpt=1?originalUrl=https:%2F%2Fcs.chromium.org%2F
-
https://source.chromium.org/chromium/chromium/src/+/71825939c432c440fa53ef4016372076e2c6114a:third_party/blink/renderer/modules/webaudio/constant_source_node.cc;l=117;bpv=1;bpt=1?originalUrl=https:%2F%2Fcs.chromium.org%2F
-
https://source.chromium.org/chromium/chromium/src/+/71825939c432c440fa53ef4016372076e2c6114a:third_party/blink/renderer/modules/webaudio/audio_scheduled_source_node.cc;l=242;bpv=1;bpt=1?originalUrl=https:%2F%2Fcs.chromium.org%2F
-
https://source.chromium.org/chromium/chromium/src/+/71825939c432c440fa53ef4016372076e2c6114a:third_party/blink/renderer/modules/webaudio/audio_scheduled_source_node.cc;l=243;bpv=1;bpt=1?originalUrl=https:%2F%2Fcs.chromium.org%2F
-
https://source.chromium.org/chromium/chromium/src/+/71825939c432c440fa53ef4016372076e2c6114a:third_party/blink/renderer/modules/webaudio/audio_scheduled_source_node.cc;l=199;drc=b892cf58e162a8f66cd76d7472f129fe0fb6a7d1;bpv=1;bpt=1?originalUrl=https:%2F%2Fcs.chromium.org%2F
-
https://source.chromium.org/chromium/chromium/src/+/71825939c432c440fa53ef4016372076e2c6114a:third_party/blink/renderer/modules/webaudio/offline_audio_context.cc;l=426;drc=b892cf58e162a8f66cd76d7472f129fe0fb6a7d1;bpv=1;bpt=1?originalUrl=https:%2F%2Fcs.chromium.org%2F
Impact
Use-after-free in renderer.
Coordinated Disclosure Timeline
- 02/03/2020 Reported as Chromium Issue 1057593
- 18/03/2020 Fixed in version 80.0.3987.149
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-037 in any communication regarding this issue.