Open Bug 1817004 Opened 1 year ago Updated 2 months ago

[regression] Timezone is always set to UTC in a build with privacy.resistFingerprinting=true


(Core :: JavaScript: Internationalization API, defect, P3)

Firefox 102





(Reporter: maxim.cournoyer, Unassigned)


(Blocks 1 open bug)


Steps to reproduce:

  1. Apply the following diff to make resistFingerprinting enabled by default:
diff -r 63b1870239fb browser/app/profile/firefox.js
--- a/browser/app/profile/firefox.js    Tue Feb 14 15:37:31 2023 -0500
+++ b/browser/app/profile/firefox.js    Wed Feb 15 12:07:35 2023 -0500
@@ -1447,6 +1447,8 @@
 pref("services.sync.prefs.sync.spellchecker.dictionary", true);
 pref("services.sync.prefs.sync.ui.osk.enabled", true);
+pref("privacy.resistFingerprinting", true);
 // A preference which, if false, means sync will only apply incoming preference
 // changes if there's already a local services.sync.prefs.sync.* control pref.
 // If true, all incoming preferences will be applied and the local "control
  1. Build then run with ./mach run. Notice the time at is in UTC as expected.

  2. Go to about:config, and set privacy.resistFingerprinting to false.

  3. Close and restart with ./mach run. Notice that although the option is false, still reports the date as UTC (or Date() in the JavaScript console.

Actual results:

The time is always UTC, even after a user switches privacy.resistFingerprinting back to false.

ltrace shows that the TZ environment variable got set to UTC:

$ ltrace -f -e getenv python ./mach run |& grep TZ
[pid 31839]>getenv("TZ")                                   = nil
[pid 31955]>getenv("TZ")                                   = ":/etc/localtime"
[pid 31839]>getenv("TZ")                                = ":/etc/localtime"
[pid 32004]>getenv("TZ")                                   = ":/etc/localtime"
[pid 32061]>getenv("TZ")                                   = ":/etc/localtime"
[pid 32063]>getenv("TZ")                                   = ":/etc/localtime"
[pid 32081]>getenv("TZ")                                   = ":/etc/localtime

And running with ./mach run --debug and putting a breakpoint on nsRFPService::UpdateRFPPref, we can see that the first time it executes it, privacyResistFingerprinting is true ; apparently the user preferences have not already been read.

Expected results:

It should obey the user setting privacy.resistFingerprinting and display the local time when its value is false. This used to work fine in ESR 91 so it appears to be a regression.

Component: Untriaged → JavaScript: Internationalization API
Flags: needinfo?(andrebargull)
Product: Firefox → Core

I confirm that the bug didn't exist in 91.13.1esr, using the same reproducer as above.

I will try to reproduce this; if you have it handy, what is the stack for the first UpdateRFPPref call; I'm curious where in the startup sequence we are that we're hitting it now (as opposed to before) before user prefs are initialized...

Some more details from Matrix: This happened using the system icu which doesn't support / use the /etc/localtime file.

Maybe on ESR 91 we didn't hit UpdateRFPPrefs before user prefs were read; but now we do. But that isn't necessarily the problem. The problem really seems to be that our attempt to reset the timezone by saying PR_SetEnv("TZ=:/etc/localtime"); doesn't work on some systems.

Here's the backtrace in the first UpdateRFPPref call:

(gdb) p privacyResistFingerprinting
$3 = true
(gdb) bt
#0  mozilla::nsRFPService::UpdateRFPPref (this=this@entry=0x7fffeb4307c0)
    at /home/mcournoyer/src/mozilla-unified/toolkit/components/resistfingerprinting/nsRFPService.cpp:720
#1  0x00007ffff20730ce in mozilla::nsRFPService::Init (this=0x7fffeb4307c0)
    at /home/mcournoyer/src/mozilla-unified/toolkit/components/resistfingerprinting/nsRFPService.cpp:682
#2  0x00007ffff2072fa8 in mozilla::nsRFPService::GetOrCreate ()
    at /home/mcournoyer/src/mozilla-unified/toolkit/components/resistfingerprinting/nsRFPService.cpp:148
#3  0x00007fffef795b3c in nsContentUtils::Init () at /home/mcournoyer/src/mozilla-unified/dom/base/nsContentUtils.cpp:798
#4  0x00007ffff1487892 in nsLayoutStatics::Initialize () at /home/mcournoyer/src/mozilla-unified/layout/build/nsLayoutStatics.cpp:164
#5  0x00007ffff14877f2 in nsLayoutModuleInitialize () at /home/mcournoyer/src/mozilla-unified/layout/build/nsLayoutModule.cpp:104
#6  0x00007fffeea96500 in nsComponentManagerImpl::Init (this=0x7ffff7815c10)
    at /home/mcournoyer/src/mozilla-unified/xpcom/components/nsComponentManager.cpp:408
#7  0x00007fffeead1388 in NS_InitXPCOM (aResult=0x7ffff7814848, aBinDirectory=0x7ffff78b19d0, aAppFileLocationProvider=0x7fffffffb7b0, 
    aInitJSContext=false) at /home/mcournoyer/src/mozilla-unified/xpcom/build/XPCOMInit.cpp:446
#8  0x00007ffff214bb60 in ScopedXPCOMStartup::Initialize (this=0x7ffff7814848, aInitJSContext=false)
    at /home/mcournoyer/src/mozilla-unified/toolkit/xre/nsAppRunner.cpp:1715
#9  XREMain::XRE_main (this=this@entry=0x7fffffffb770, argc=argc@entry=4, argv=argv@entry=0x7fffffffc9f8, aConfig=...)
    at /home/mcournoyer/src/mozilla-unified/toolkit/xre/nsAppRunner.cpp:5430
#10 0x00007ffff214be80 in XRE_main (argc=1, argv=0x57, aConfig=...) at /home/mcournoyer/src/mozilla-unified/toolkit/xre/nsAppRunner.cpp:5493
#11 0x000055555556125d in do_main (argc=1, argv=0x7fffffffc9f8, envp=0x7fffffffca20)
    at /home/mcournoyer/src/mozilla-unified/browser/app/nsBrowserApp.cpp:225
#12 main (argc=<optimized out>, argv=<optimized out>, envp=0x7fffffffca20)
    at /home/mcournoyer/src/mozilla-unified/browser/app/nsBrowserApp.cpp:378

The thing about the colon prefix :/etc/localtime not working discussed on Matrix was observed on my system with the following program that tests the exercised procedure C procedure from ICU in this case:

#include <stdio.h>
#include <stdlib.h>

#include <unicode/ucal.h>
#include <unicode/ustring.h>

int main() {
    UChar result[100]; /* char16_t array */
    UErrorCode errorCode = U_ZERO_ERROR;
    char timezone[200];

    ucal_getHostTimeZone(result, 100, &errorCode);

    if (!u_austrncpy(timezone, result, 100)) {
        printf("error: failed to convert UChar array to byte string\n");

    printf("host timezone: %s\n", timezone);
$ TZ=:/etc/localtime ./icu-repro
host timezone: /etc/localtime

The returned timezone is not a valid Oslo timezone ID. When encountering a ':', it expects some zoneinfo file name, no a copy as it is on my system.

I hope this helps.

I see you already pinned down the problem to TZ=:/etc/localtime. Maybe we could just unset TZ like we do on Windows?

I first thought this was a different issue that I've run into before. We remember the TZ variable during startup and before setting it to TZ=UTC as mInitialTZValue. However this doesn't really work for child processes that are started after TZ=UTC is set in the parent process due to RFP. They inherit TZ=UTC and remember that as their mInitialTZValue. So in child processes disabling resistFingerprinting will just set it back to UTC again ... What usually works is opening enough new tabs until we spawn a new processes for them.

I have some hopes that maybe we can quickly stop setting the TZ variable after bug 1709867 lands.

See Also: → 1709867

I tried this, but it doesn't help:

$ hg diff
diff -r a0606487f7a1 toolkit/components/resistfingerprinting/nsRFPService.cpp
--- a/toolkit/components/resistfingerprinting/nsRFPService.cpp  Wed Feb 15 14:35:11 2023 -0500
+++ b/toolkit/components/resistfingerprinting/nsRFPService.cpp  Fri Feb 17 09:13:06 2023 -0500
@@ -714,15 +714,7 @@
     } else {
-#if defined(XP_WIN)
-      // For Windows, we reset the TZ to an empty string. This will make Windows
-      // to use its system timezone.
-      // For POSIX like system, we reset the TZ to the /etc/localtime, which is
-      // the system timezone.
-      PR_SetEnv("TZ=:/etc/localtime");
Severity: -- → S4
Priority: -- → P3

We support the TZ=:/etc/localtime format in js::DateTimeInfo::internalResyncICUDefaultTimeZone(). But we still require /etc/localtime to be a symlink to the actual time zone file. So it won't work when a time zone file was copied as a file to /etc/localtime, see bug 1817701.

Flags: needinfo?(andrebargull)

This sounds like a reported problem in Support Forum - on Windows 11 OS

Thunderbird 102.10.1
User in Spain and Windows 11 set up correctly for Date/Time and Timezone
Using Thunderbird English GB
regardless of whether using Settings > General > Date & Time Formating - 'Application locale' en-GB or 'Regional settings locale' Spain
Date column in Message List and Message Pane header is always UTC
Error console using Date() always returns UTC/GMT
privacy.resistFingerprinting = false
User has provided good images and info at link.

privacy.resistFingerprinting = true will cause Date to be UTC and ignore correct date/times
privacy.resistFingerprinting = false normally means correct date time is shown, but in this instance it fails.

Attempting to reset to true, restart Thunderbird then reset to 'false' and restart Thunderbird had no effect.
Stuck on UTC time.

Thunderbird users require correct time/date for emails so by default need 'privacy.resistFingerprinting' = 'false' - I'm not sure whether anyone would require it setting to anything else for obvious reasons. Why is it even a setting in Thunderbird ? Getting a fix on this is important and urgent.

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