Bug 2251620 - hang on maps.google.co.uk (maybe randomDataOnCanvasExtract/ RandomizePixels?) - downstream only?
Summary: hang on maps.google.co.uk (maybe randomDataOnCanvasExtract/ RandomizePixels?)...
Keywords:
Status: CLOSED DUPLICATE of bug 2251202
Alias: None
Product: Fedora
Classification: Fedora
Component: firefox
Version: 39
Hardware: Unspecified
OS: Linux
unspecified
medium
Target Milestone: ---
Assignee: Gecko Maintainer
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2023-11-27 01:32 UTC by Dr. David Alan Gilbert
Modified: 2023-11-27 02:57 UTC (History)
5 users (show)

Fixed In Version:
Clone Of:
Environment:
Last Closed: 2023-11-27 02:57:04 UTC
Type: ---
Embargoed:


Attachments (Terms of Use)

Description Dr. David Alan Gilbert 2023-11-27 01:32:53 UTC
In the last few days I've been seeing a hang on maps.google.co.uk; the map renders but then the page hangs solid, I can't interact with the UI in that tab, and sometimes closing the tab takes a few seconds.

I've gathered quite a bit of debug; first what does and doesn't work:

  a) Fails: Downstream firefox-120.0-2.fc39.x86_64 with my standard profile fails
  b) Works: Upstream mozilla.org 120.0 builds with the same profile
  c) Works: Downstream in 'troubleshooting' mode
  c) Fails: Downstream with all plugins disabled and hardware accel disabled still fails

Firefox support suggested I try their profiler and you can see the profile at:
   https://share.firefox.dev/47se8Zm

They also suggested tryign to get a backtrace of the process for the tab by sending it a segfault, instead I connected with gdb; 

mozilla::nsRFPService::RandomizePixels(nsICookieJarSettings*, unsigned char*, unsigned int, unsigned int, unsigned int, mozilla::gfx::SurfaceFormat) [clone .constprop.0] ()
    at /usr/src/debug/firefox-120.0-2.fc39.x86_64/toolkit/components/resistfingerprinting/nsRFPService.cpp:1370
Downloading source file /usr/src/debug/firefox-120.0-2.fc39.x86_64/toolkit/components/resistfingerprinting/nsRFPService.cpp
1370      for (uint8_t i = 0; i <= numNoises; i++) {                                                                 
(gdb) p numNoises
No symbol "numNoises" in current context.
(gdb) where
#0  mozilla::nsRFPService::RandomizePixels(nsICookieJarSettings*, unsigned char*, unsigned int, unsigned int, unsigned int, mozilla::gfx::SurfaceFormat) [clone .constprop.0] ()
    at /usr/src/debug/firefox-120.0-2.fc39.x86_64/toolkit/components/resistfingerprinting/nsRFPService.cpp:1370
#1  0x00007f79b6b8d862 in mozilla::dom::CanvasRenderingContext2D::GetImageDataArray(JSContext*, int, int, unsigned int, unsigned int, nsIPrincipal&, JSObject**) ()
    at /usr/src/debug/firefox-120.0-2.fc39.x86_64/dom/canvas/CanvasRenderingContext2D.cpp:5998
#2  mozilla::dom::CanvasRenderingContext2D::GetImageData(JSContext*, int, int, int, int, nsIPrincipal&, mozilla::ErrorResult&) () at /usr/src/debug/firefox-120.0-2.fc39.x86_64/dom/canvas/CanvasRenderingContext2D.cpp:5887
#3  0x00007f79b6830fe7 in getImageData() () at ../../../dom/bindings/CanvasRenderingContext2DBinding.cpp:5416
#4  0x000017678b558a84 in  ()
#5  0x0000000000000004 in  ()
#6  0x00007fff42eb1540 in  ()
#7  0x000017678b558a37 in  ()
#8  0x0000000000000000 in  ()

so in this randomise loop; I'm not sure if it's stuck there but there is a solid blue bar in the profiler?

1370	  for (uint8_t i = 0; i <= numNoises; i++) {
1371	    // Choose which RGB channel to add a noise. The pixel data is in either
1372	    // the BGRA or the ARGB format depending on the endianess. To choose the
1373	    // color channel we need to add the offset according the endianess.
1374	    uint32_t channel;
1371	    // Choose which RGB channel to add a noise. The pixel data is in either
1372	    // the BGRA or the ARGB format depending on the endianess. To choose the
1373	    // color channel we need to add the offset according the endianess.
1374	    uint32_t channel;
1375	    if (aSurfaceFormat == gfx::SurfaceFormat::B8G8R8A8) {
1376	      channel = rng1.next() % 3;
1377	    } else if (aSurfaceFormat == gfx::SurfaceFormat::A8R8G8B8) {
1378	      channel = rng1.next() % 3 + 1;
1379	    } else {
1380	      return NS_ERROR_INVALID_ARG;

(Possibly unrelated, but gathering the profile got me a mozilla crash;  https://crash-stats.mozilla.org/report/index/cae29340-bf09-450c-99e6-749480231127 )

Reproducible: Always

Steps to Reproduce:
1. Open Firefox tab
2. Bring up maps.google.co.uk
3.
Actual Results:  
Rendered front of the maps, hung tab

Expected Results:  
Working maps

Comment 1 Dr. David Alan Gilbert 2023-11-27 01:38:02 UTC
Given that backtrace I tried turning off:

privacy.resistFingerprinting.randomDataOnCanvasExtract

and it fixes it!

Comment 2 Dr. David Alan Gilbert 2023-11-27 02:48:43 UTC
To me this looks like that code is broken;

in nsRFPService.cpp:

  // Ensure at least 20 random changes may occur.
  uint8_t numNoises = std::clamp<uint8_t>(rnd3, 20, 255);


  for (uint8_t i = 0; i <= numNoises; i++) {

I don't think we're ever getting out of that loop, and I think that's because numNoises is 255 - which the clamp allows.

Comment 3 Dr. David Alan Gilbert 2023-11-27 02:57:04 UTC

*** This bug has been marked as a duplicate of bug 2251202 ***


Note You need to log in before you can comment on or make changes to this bug.