Switching language and format broken

Bug #1662031 reported by Gunnar Hjalmarsson on 2017-02-05
12
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Ubuntu GNOME
Undecided
Unassigned
gdm
Expired
Medium
gdm3 (Ubuntu)
High
Olivier Tilloy
Artful
High
Olivier Tilloy

Bug Description

In Ubuntu GNOME 16.10 it doesn't matter what display language I select - the effective language is still the one stated in /etc/default/locale. ~/.pam_environment is changed as expected, but the variables set in /etc/default/locale override ~/.pam_environment.

In Ubuntu GNOME 16.04 language switching takes effect, but the reason for that seems to be that /etc/default/locale is changed as well, so when a user changes the display language (or format), it changes it for all users on the system.

The overriding by /etc/default/locale is probably caused by some other package(s) but g-c-c.

tags: added: xenial yakkety
Jeremy Bicha (jbicha) wrote :

Gunnar, thanks for looking into this.

See also bug 1631750.

So I looked briefly at this today. By the time I filed that other bug, accountsservice hadn't really changed from xenial. gnome-settings-daemon doesn't look to me like it does stuff with language settings. gnome-control-center had been updated from 3.18 to 3.20. And then I found this commit:

https://git.gnome.org/browse/gnome-control-center/commit/?h=gnome-3-20&id=30470d721

Since the region panel didn't change much in 3.20 I suspect that commit might be our problem.
https://git.gnome.org/browse/gnome-control-center/log/panels/region?h=gnome-3-20
(Look at 2016 commits only)

Jeremy Bicha (jbicha) wrote :

(There were some November 2015 commits too but they didn't look important)

Gunnar Hjalmarsson (gunnarhj) wrote :

Did some testing on zesty. When I had switched to lightdm, language switching between already installed languages worked fine, so gdm3 seems to be the culprit.

Haven't been able to spot the applicable code in the gdm3 source. Tried the attached patch, but it didn't help.

If I set the variables in ~/.profile, it works, so gdm3 sets the system wide environment variables after PAM has read ~/.pam_environment but before it sources ~/.profile.

tags: added: patch
Gunnar Hjalmarsson (gunnarhj) wrote :

This issue is present on an artful daily build as well. gdm3 somehow overrides variables set by ~/.pam_environment. (With lightdm it works as expected.)

It should be noticed that the issue is present whether g-c-c or language-selector is used to change the display language.

Changed in gdm3 (Ubuntu):
importance: Undecided → High
milestone: none → ubuntu-17.10
status: New → Confirmed
tags: added: gnome-17.10
tags: added: rls-aa-incoming
Will Cooke (willcooke) on 2017-09-27
Changed in gdm3 (Ubuntu Artful):
assignee: nobody → Sebastien Bacher (seb128)
Changed in gnome-control-center (Ubuntu Artful):
assignee: nobody → Sebastien Bacher (seb128)
tags: removed: rls-aa-incoming
Gunnar Hjalmarsson (gunnarhj) wrote :

If nobody figures out what makes the variables in ~/.pam_environment be overridden by the variables in /etc/default/locale, I'm thinking of an ugly hack which may work.

~/.pam_environment is maintained by /usr/share/language-tools/save-to-pam-env. In case of a GNOME desktop we could make that file write to ~/.profile as well.

Olivier Tilloy (osomon) wrote :

Testing in an up-to-date artful VM, when switching languages in g-c-c, both LANG and LANGUAGE are updated in both ~/.pam_environment and /etc/default/locale.

That VM is an artful install that has been updated daily, not an upgrade from a previous release.

Gunnar Hjalmarsson (gunnarhj) wrote :

Olivier: Is /etc/default/locale written to also?? That's not what Sebastien and I observed. I'll go to a (relatively) fresh artful install and recheck then.

If that's the case, the issue may not be so urgent. But it's poor design, since it means that if a user changes language, s/he changes it for all users on the system.

Gunnar Hjalmarsson (gunnarhj) wrote :

The /etc/default/locale file was not altered when I just tested on an updated artful.

Gunnar Hjalmarsson (gunnarhj) wrote :

To clarify: I used the g-c-c interface to switch language. If I had clicked "Manage Installed Languages" to open Language Support and then clicked "Apply System-Wide", /etc/default/locale would have been updated too. But that 'does not count'. Language Support is available to work around the fact that installation of new languages from g-c-c does not work currently.

Olivier Tilloy (osomon) wrote :

I didn't click "Apply System-Wide". When I changed the language in g-c-c /etc/default/locale was written to (LANG and LANGUAGE were updated). I agree that this is unexpected behaviour though, I wouldn't expect the current user's setting to be applied system-wide unless explicitly requested.

Olivier Tilloy (osomon) wrote :

In /etc/pam.d/gdm-launch-environment:

    session required pam_env.so readenv=1 user_readenv=1 envfile=/etc/default/locale

In pam_env.c (handle_env function), the env should be set from /etc/default/locale and then overridden by ~/.pam_environment. If I add the 'debug' parameter to the module invokation, I see only the calls to pam_putenv corresponding to /etc/default/locale, which means that for some reason to be determined ~/.pam_environment is not being sourced.

Gunnar Hjalmarsson (gunnarhj) wrote :

Wonder if there is a problem with this code:

https://git.gnome.org/browse/gdm/tree/daemon/gdm-session-worker.c#n993

@Steve: gdm3 seems to not read ~/.pam_environment. Do you possibly have an idea off the top of your head?

Olivier Tilloy (osomon) wrote :

/etc/pam.d/gdm-launch-environment is run as user gdm, so it's not what we're interested in.

/etc/pam.d/gdm-password appears to be what sets the environment upon user login.

When adding some logging to that module, I'm seeing the following:

pam_env(gdm-password:session): username=ubuntu
pam_env(gdm-password:session): user env path: /home/ubuntu/.pam_environment
pam_env(gdm-password:session): parsing config file
pam_env(gdm-password:session): remove variable "LANGUAGE=fr_FR:en_GB:en"
pam_env(gdm-password:session): remove variable "LANG=fr_FR.UTF-8"

It turns out, "VARIABLE=value" is not the correct syntax for ~/.pam_environment. The expected syntax is "VARIABLE [DEFAULT=[value]] [OVERRIDE=[value]]" (man pam_env.conf).
And indeed if I modify ~/.pam_environment to conform to that syntax, I'm seeing this instead:

pam_env(gdm-password:session): pam_putenv("LANGUAGE=fr_FR:en_GB:en")
pam_env(gdm-password:session): pam_putenv("LANG=fr_FR.UTF-8")

That doesn't seem to fix the overall issue though, as the values of LANGUAGE and LANG are still those from /etc/default/locale after logging in.

Olivier Tilloy (osomon) wrote :

/usr/share/language-tools/save-to-pam-env is the script that writes to ~/.pam_environment with an incorrect syntax.

Olivier Tilloy (osomon) wrote :

I added a FOOBAR variable to both ~/.pam_environment and /etc/default/locale, with different values in each file, and after logging in the value is the one from ~/.pam_environment. So I don't think gdm sources /etc/default/locale after ~/.pam_environment. However variables LANG, LANGUAGE and LC_* appear to be overridden by the values in /etc/default/locale, and set_up_session_language() in daemon/gdm-session.c (https://git.gnome.org/browse/gdm/tree/daemon/gdm-session.c#n2488) looks suspicious in that regard.

Gunnar Hjalmarsson (gunnarhj) wrote :

Yep, suspicious indeed. I built gdm3 with that function disabled:

https://launchpad.net/~gunnarhj/+archive/ubuntu/gdm3

And yes, that's it. You nailed it Olivier; thanks a lot!

Why didn't I see it when looking at that file many months ago... :( Anyway, I have submitted a MP.

Changed in gdm3 (Ubuntu Artful):
status: Confirmed → In Progress
no longer affects: gnome-control-center (Ubuntu Artful)
no longer affects: gnome-control-center (Ubuntu)
no longer affects: accountsservice (Ubuntu Artful)
no longer affects: accountsservice (Ubuntu)
Olivier Tilloy (osomon) wrote :

And I can confirm that the packages in Gunnar's PPA appear to fix the issue here, without any visible regression, from my limited testing.

Sebastien Bacher (seb128) wrote :

the function has been added to fix https://bugzilla.gnome.org/show_bug.cgi?id=709105

Olivier Tilloy (osomon) wrote :

I filed https://bugzilla.gnome.org/show_bug.cgi?id=788762 to continue the conversation upstream.

Changed in gdm3 (Ubuntu Artful):
assignee: Sebastien Bacher (seb128) → Olivier Tilloy (osomon)
Olivier Tilloy (osomon) wrote :

See conversation on the upstream bug report. It turns out calling set_up_session_language() earlier (e.g. in on_setup_complete_cb) doesn't fix the problem: gdm_session_start_session() calls send_environment(), which overrides the environment set up by pam with the values from /etc/default/locale again.

I guess not calling set_up_session_language() at all is the correct fix in our case.

Launchpad Janitor (janitor) wrote :

This bug was fixed in the package gdm3 - 3.26.1-3ubuntu2

---------------
gdm3 (3.26.1-3ubuntu2) artful; urgency=medium

  * debian/patches/ubuntu_dont_set_language_env.patch:
    - Don't run the set_up_session_language() function, since it
      overrides variable values set by ~/.pam_environment
      (LP: #1662031). Thanks to Olivier Tilloy for debugging!

 -- Gunnar Hjalmarsson <email address hidden> Wed, 11 Oct 2017 13:20:09 +0200

Changed in gdm3 (Ubuntu Artful):
status: In Progress → Fix Released
Changed in gdm:
importance: Unknown → Medium
status: Unknown → Expired
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.