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 | 7 +++++++ 10 files changed, 54 insertions(+), 1 deletion(-) 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 @@ -196,6 +196,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) { + float* destination = array->Data(); + 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 @@ -11,6 +11,7 @@ #include "services/metrics/public/cpp/ukm_recorder.h" #include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/public/common/mediastream/media_devices.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" @@ -586,7 +587,9 @@ double AudioContext::baseLatency() const { DCHECK(IsMainThread()); 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 @@ -29,6 +29,7 @@ #include "base/metrics/histogram_functions.h" #include "build/build_config.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" @@ -721,6 +722,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()); 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 @@ -339,6 +339,8 @@ class MODULES_EXPORT BaseAudioContext // if the execution context does not exist. bool CheckExecutionContextAndThrowIfNecessary(ExceptionState&); + static float ShuffleAudioData(float data, unsigned index); + protected: enum 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 @@ -368,6 +368,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 @@ -31,6 +31,7 @@ #include #include +#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" @@ -155,6 +156,7 @@ void RealtimeAnalyser::GetFloatTimeDomainData( input_buffer[(i + write_index - fft_size + kInputBufferSize) % kInputBufferSize]; + value = BaseAudioContext::ShuffleAudioData(value, i); destination[i] = value; } } @@ -182,6 +184,8 @@ void RealtimeAnalyser::GetByteTimeDomainData(DOMUint8Array* destination_array) { input_buffer[(i + write_index - fft_size + kInputBufferSize) % kInputBufferSize]; + value = BaseAudioContext::ShuffleAudioData(value, i); + // Scale from nominal -1 -> +1 to unsigned byte. double scaled_value = 128 * (value + 1); @@ -301,6 +305,8 @@ void RealtimeAnalyser::ConvertToByteData(DOMUint8Array* destination_array) { 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)); @@ -320,6 +326,7 @@ void RealtimeAnalyser::ConvertFloatToDb(DOMFloat32Array* destination_array) { float linear_value = source[i]; double db_mag = audio_utilities::LinearToDecibels(linear_value); destination[i] = static_cast(db_mag); + destination[i] = BaseAudioContext::ShuffleAudioData(destination[i], i); } } } --