Closed Bug 2036977 Opened 14 days ago Closed 14 days ago

Honor fp-contract=no to reduce fingerprinting in Web Audio

Categories

(Core :: Web Audio, enhancement)

enhancement

Tracking

()

RESOLVED FIXED
152 Branch
Tracking Status
firefox152 --- fixed

People

(Reporter: tjr, Assigned: tjr)

References

(Blocks 2 open bugs)

Details

Attachments

(3 files)

Analysis of the Web Audio fingerprints gather from the fingerprinting telemetry showed that audio fingerprints were grouped into three buckets:

  1. x64-64 with a FMA3 CPU
  2. x86-64 without FMA3 (plus x86)
  3. aarch64 (NEON instructions)

The instruction in question is xsimd:fma. Now fused-multiply-add is supposed to be disabled via fp-contract=off but we have one explicit call to it in the code and that call is separating the two two buckets from collapsing. Replacing that call with a multiply+add will make bucket 1 match bucket 2.

The performance impact is small on a specifically designed benchmark:

    Performance impact (AMD Zen 4, single-threaded, 10M iterations of a
    128-sample block, taskset-pinned, mean of 3 runs):
    
       variant                                   ns/block   ns/sample  delta
       xsimd::fma  / fma3<sse4_2>  (current)        14.1     0.110     baseline
       vmul+vadd   / fma3<sse4_2>  (proposed)       15.0     0.117     +6.4%
       xsimd::fma  / sse2          (current)        14.1     0.110     baseline
       vmul+vadd   / sse2          (proposed)       14.7     0.115     +4.3%
    

I'd like to also collapse that neon bucket, but I'll need to do more testing for that.

Telemetry showed three audio fingerprint buckets that were correlated
to specific CPUs/CPU features:

3574997209385037 x86-64 with FMA3-capable CPU
3574996822327375 32-bit + x86-64 without FMA3
3574996626004576 aarch64 (NEON FMLA path)

The cause was eventually narrowed down to a single fma call. fma is
supposed to be prevented by a project-wide -ffp-contract=off

Replacing the fused multiply-add with a separate vmul + vadd produces
bit-identical output for the first two scenarios across all four SIMD
tiers (verified locally on x86-64 with -msse2, -msse4.2 -mfma, and
-mavx2 -mfma builds: same bit-exact 128-sample buffer in all three;
1-ULP-per-sample difference in the FMA build).

It should produce the same value for NEON as well. (going to test that though)

Assignee: nobody → tom
Status: NEW → ASSIGNED

Serves as both a regression test and a confirmation
its working as intended on all platforms.

Status: ASSIGNED → RESOLVED
Closed: 14 days ago
Resolution: --- → FIXED
Target Milestone: --- → 152 Branch

There's no need to ask for the fma3 isa if we don't use any of the
new instruction. Plus it gives strong guarantee that the compiler won't
generate the fma instruction we don't want to use.

Attachment #9583621 - Attachment description: Bug 2036977 - Pass the appropriate compiler flags to prevent fma usage in webaudio/AudioNodeEngine.cpp r=padenot → Bug 2036977 - Pass the appropriate compiler flags to prevent fma usage in webaudio/AudioNodeEngine.cpp r=padenot!
Pushed by sguelton@mozilla.com: https://github.com/mozilla-firefox/firefox/commit/45f9203b1f96 https://hg.mozilla.org/integration/autoland/rev/fd8bdb65a300 Pass the appropriate compiler flags to prevent fma usage in webaudio/AudioNodeEngine.cpp r=padenot

A patch has been attached on this bug, which was already closed. Filing a separate bug will ensure better tracking. If this was not by mistake and further action is needed, please alert the appropriate party. (Or: if the patch doesn't change behavior -- e.g. landing a test case, or fixing a typo -- then feel free to disregard this message)

(In reply to Tom Ritter [:tjr] from comment #1)

It should produce the same value for NEON as well. (going to test that though)

I currently lack an ARM64/aarch64 device. Using https://arkenfox.github.io/TZP/tzp.html#audio, tom can you (or pierov) please confirm that before this patch such a device returned a34c73cd and with the patch it now returns a7c1fbb6 - so I can update my test code - thanks

https://github.com/arkenfox/TZP/blob/b40e686a6a453ef16d373c4371407bb42eee136e/js/audio.js#L164-L169

if (true === isArch) { // isArch means 64bit
	if ('a7c1fbb6' == hashC) {notation = sgtick+'x86_64/amd_64]'+sc
	} else if ('a34c73cd' == hashC) {notation = sgtick+'ARM64/aarch64]'+sc}
} else {
	if ('24fc63ce' == hashC) {notation = sgtick+'x86/i686/ARMv7]'+sc}
}
Flags: needinfo?(pierov)

Thorin: you should be able to test this in your mac and/or in your phone.

Flags: needinfo?(pierov)

my phone (samsung galaxy S24 FE) on nightly build 2026 05 11 090215 still reports as a34c73cd i.e no change to stable

  • edit: build 2026 05 12... no change - I don't think this is working as intended - @tjr

mac - I can't install multiple FF channels on mac, it always uses the same profile and corrupts everything

Flags: needinfo?(tom)
Blocks: 2040494

I've filed Bug 2040494 for followup...

Flags: needinfo?(tom)
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: