From: csagan5 <32685696+csagan5@users.noreply.github.com> Date: Sun, 25 Mar 2018 21:49:37 +0200 Subject: AudioBuffer, AnalyserNode: fp mitigations Truncate base latency precision to two digits License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html --- .../AudioBuffer-AnalyserNode-fp-mitigations.inc | 8 ++++++++ .../AudioBuffer-AnalyserNode-fp-mitigations.inc | 3 +++ .../AudioBuffer-AnalyserNode-fp-mitigations.inc | 1 + .../renderer/modules/webaudio/audio_buffer.cc | 14 ++++++++++++++ .../blink/renderer/modules/webaudio/audio_buffer.h | 2 ++ .../renderer/modules/webaudio/audio_context.cc | 5 ++++- .../modules/webaudio/base_audio_context.cc | 12 ++++++++++++ .../renderer/modules/webaudio/base_audio_context.h | 2 ++ .../modules/webaudio/offline_audio_context.cc | 1 + .../renderer/modules/webaudio/realtime_analyser.cc | 13 ++++++++++--- .../platform/runtime_enabled_features.json5 | 5 ++--- 11 files changed, 59 insertions(+), 7 deletions(-) create mode 100644 cromite_flags/chrome/browser/about_flags_cc/AudioBuffer-AnalyserNode-fp-mitigations.inc create mode 100644 cromite_flags/third_party/blink/common/features_cc/AudioBuffer-AnalyserNode-fp-mitigations.inc create mode 100644 cromite_flags/third_party/blink/common/features_h/AudioBuffer-AnalyserNode-fp-mitigations.inc diff --git a/cromite_flags/chrome/browser/about_flags_cc/AudioBuffer-AnalyserNode-fp-mitigations.inc b/cromite_flags/chrome/browser/about_flags_cc/AudioBuffer-AnalyserNode-fp-mitigations.inc new file mode 100644 --- /dev/null +++ b/cromite_flags/chrome/browser/about_flags_cc/AudioBuffer-AnalyserNode-fp-mitigations.inc @@ -0,0 +1,8 @@ +#ifdef FLAG_SECTION + + {"fingerprinting-audio-context-data-noise", + "Enable Audio Context fingerprint deception", + "Scale the output values of rendered data with a randomly selected factor.", kOsAll, + FEATURE_VALUE_TYPE(blink::features::kAudioContextShuffleEnabled)}, + +#endif diff --git a/cromite_flags/third_party/blink/common/features_cc/AudioBuffer-AnalyserNode-fp-mitigations.inc b/cromite_flags/third_party/blink/common/features_cc/AudioBuffer-AnalyserNode-fp-mitigations.inc new file mode 100644 --- /dev/null +++ b/cromite_flags/third_party/blink/common/features_cc/AudioBuffer-AnalyserNode-fp-mitigations.inc @@ -0,0 +1,3 @@ +CROMITE_FEATURE(kAudioContextShuffleEnabled, + "AudioContextShuffleEnabled", + base::FEATURE_ENABLED_BY_DEFAULT); diff --git a/cromite_flags/third_party/blink/common/features_h/AudioBuffer-AnalyserNode-fp-mitigations.inc b/cromite_flags/third_party/blink/common/features_h/AudioBuffer-AnalyserNode-fp-mitigations.inc new file mode 100644 --- /dev/null +++ b/cromite_flags/third_party/blink/common/features_h/AudioBuffer-AnalyserNode-fp-mitigations.inc @@ -0,0 +1 @@ +BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE(kAudioContextShuffleEnabled); diff --git a/third_party/blink/renderer/modules/webaudio/audio_buffer.cc b/third_party/blink/renderer/modules/webaudio/audio_buffer.cc --- a/third_party/blink/renderer/modules/webaudio/audio_buffer.cc +++ b/third_party/blink/renderer/modules/webaudio/audio_buffer.cc @@ -197,6 +197,20 @@ AudioBuffer::AudioBuffer(AudioBus* bus) } } +void AudioBuffer::ShuffleAudioData() { + for (unsigned i = 0; i < channels_.size(); ++i) { + if (NotShared array = getChannelData(i)) { + size_t len = array->length(); + if (len > 0) { + base::span destination = array->AsSpan(); + for (unsigned j = 0; j < len; ++j) { + destination[j] = BaseAudioContext::ShuffleAudioData(destination[j], j); + } + } + } + } +} + NotShared AudioBuffer::getChannelData( unsigned channel_index, ExceptionState& exception_state) { diff --git a/third_party/blink/renderer/modules/webaudio/audio_buffer.h b/third_party/blink/renderer/modules/webaudio/audio_buffer.h --- a/third_party/blink/renderer/modules/webaudio/audio_buffer.h +++ b/third_party/blink/renderer/modules/webaudio/audio_buffer.h @@ -115,6 +115,8 @@ class MODULES_EXPORT AudioBuffer final : public ScriptWrappable { std::unique_ptr CreateSharedAudioBuffer(); + void ShuffleAudioData(); + private: static DOMFloat32Array* CreateFloat32ArrayOrNull( uint32_t length, diff --git a/third_party/blink/renderer/modules/webaudio/audio_context.cc b/third_party/blink/renderer/modules/webaudio/audio_context.cc --- a/third_party/blink/renderer/modules/webaudio/audio_context.cc +++ b/third_party/blink/renderer/modules/webaudio/audio_context.cc @@ -22,6 +22,7 @@ #include "third_party/blink/public/common/mediastream/media_devices.h" #include "third_party/blink/public/mojom/permissions/permission_status.mojom-blink.h" #include "third_party/blink/public/platform/browser_interface_broker_proxy.h" +#include "third_party/blink/public/common/features.h" #include "third_party/blink/public/platform/modules/webrtc/webrtc_logging.h" #include "third_party/blink/public/platform/web_audio_latency_hint.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" @@ -1138,7 +1139,9 @@ double AudioContext::baseLatency() const { DCHECK_CALLED_ON_VALID_SEQUENCE(main_thread_sequence_checker_); DCHECK(destination()); - return base_latency_; + // remove precision past two decimal digits + int l = base_latency_ * 100; + return double(l)/100; } double AudioContext::outputLatency() const { diff --git a/third_party/blink/renderer/modules/webaudio/base_audio_context.cc b/third_party/blink/renderer/modules/webaudio/base_audio_context.cc --- a/third_party/blink/renderer/modules/webaudio/base_audio_context.cc +++ b/third_party/blink/renderer/modules/webaudio/base_audio_context.cc @@ -28,6 +28,7 @@ #include "base/metrics/histogram_functions.h" #include "build/build_config.h" #include "media/base/audio_bus.h" +#include "third_party/blink/public/common/features.h" #include "third_party/blink/public/mojom/devtools/console_message.mojom-blink.h" #include "third_party/blink/public/mojom/frame/lifecycle.mojom-shared.h" #include "third_party/blink/public/platform/platform.h" @@ -775,6 +776,17 @@ LocalDOMWindow* BaseAudioContext::GetWindow() const { return To(GetExecutionContext()); } +/*static*/ +float BaseAudioContext::ShuffleAudioData(float data, unsigned index) { + if (base::FeatureList::IsEnabled(features::kAudioContextShuffleEnabled)) { + float rnd = 1.0f + + (base::RandDouble() / 10000.0) * + (base::RandInt(0,10) > 5 ? 1.f : -1.f); + return data * rnd; + } + return data; +} + void BaseAudioContext::NotifySourceNodeStartedProcessing(AudioNode* node) { DCHECK(IsMainThread()); DeferredTaskHandler::GraphAutoLocker locker(this); diff --git a/third_party/blink/renderer/modules/webaudio/base_audio_context.h b/third_party/blink/renderer/modules/webaudio/base_audio_context.h --- a/third_party/blink/renderer/modules/webaudio/base_audio_context.h +++ b/third_party/blink/renderer/modules/webaudio/base_audio_context.h @@ -331,6 +331,8 @@ class MODULES_EXPORT BaseAudioContext // if the execution context does not exist. bool CheckExecutionContextAndThrowIfNecessary(ExceptionState&); + static float ShuffleAudioData(float data, unsigned index); + protected: enum class ContextType { kRealtimeContext, kOfflineContext }; diff --git a/third_party/blink/renderer/modules/webaudio/offline_audio_context.cc b/third_party/blink/renderer/modules/webaudio/offline_audio_context.cc --- a/third_party/blink/renderer/modules/webaudio/offline_audio_context.cc +++ b/third_party/blink/renderer/modules/webaudio/offline_audio_context.cc @@ -418,6 +418,7 @@ void OfflineAudioContext::FireCompletionEvent() { if (!rendered_buffer) { return; } + rendered_buffer->ShuffleAudioData(); // Call the offline rendering completion event listener and resolve the // promise too. diff --git a/third_party/blink/renderer/modules/webaudio/realtime_analyser.cc b/third_party/blink/renderer/modules/webaudio/realtime_analyser.cc --- a/third_party/blink/renderer/modules/webaudio/realtime_analyser.cc +++ b/third_party/blink/renderer/modules/webaudio/realtime_analyser.cc @@ -33,6 +33,7 @@ #include "base/compiler_specific.h" #include "media/base/audio_bus.h" +#include "third_party/blink/renderer/modules/webaudio/base_audio_context.h" #include "third_party/blink/renderer/platform/audio/audio_bus.h" #include "third_party/blink/renderer/platform/audio/audio_utilities.h" #include "third_party/blink/renderer/platform/audio/vector_math.h" @@ -117,7 +118,8 @@ void RealtimeAnalyser::GetFloatFrequencyData(DOMFloat32Array* destination_array, for (unsigned i = 0; i < len; ++i) { const float linear_value = magnitude_buffer_[i]; const double db_mag = audio_utilities::LinearToDecibels(linear_value); - destination[i] = static_cast(db_mag); + auto v = static_cast(db_mag); + destination[i] = BaseAudioContext::ShuffleAudioData(v, i); } } } @@ -153,9 +155,11 @@ void RealtimeAnalyser::GetByteFrequencyData(DOMUint8Array* destination_array, // The range m_minDecibels to m_maxDecibels will be scaled to byte values // from 0 to UCHAR_MAX. - const double scaled_value = + double scaled_value = UCHAR_MAX * (db_mag - min_decibels) * range_scale_factor; + scaled_value = BaseAudioContext::ShuffleAudioData(scaled_value, i); + // Clip to valid range. destination[i] = static_cast(ClampTo(scaled_value, 0, UCHAR_MAX)); @@ -184,6 +188,7 @@ void RealtimeAnalyser::GetFloatTimeDomainData( input_buffer_[(i + write_index - fft_size + kInputBufferSize) % kInputBufferSize]; + value = BaseAudioContext::ShuffleAudioData(value, i); destination[i] = value; } } @@ -205,10 +210,12 @@ void RealtimeAnalyser::GetByteTimeDomainData(DOMUint8Array* destination_array) { base::span destination = destination_array->AsSpan(); for (unsigned i = 0; i < len; ++i) { // Buffer access is protected due to modulo operation. - const float value = + float value = input_buffer_[(i + write_index - fft_size + kInputBufferSize) % kInputBufferSize]; + value = BaseAudioContext::ShuffleAudioData(value, i); + // Scale from nominal -1 -> +1 to unsigned byte. const double scaled_value = 128 * (value + 1); diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5 @@ -719,9 +719,8 @@ { // AudioContext.playoutStats interface. // https://chromestatus.com/feature/5172818344148992 - name: "AudioContextPlayoutStats", - origin_trial_feature_name: "AudioContextPlayoutStats", - status: "experimental", + name: "AudioContextPlayoutStats", // keep AudioContextPlayoutStats + status: "experimental", // experimental }, { name: "AudioContextSetSinkId", --