Bug 497501

Summary: startplasma reads "LANG" at the wrong moment in time, leading to a wrong value for "LANG" on a multi-locale system
Product: [Plasma] plasmashell Reporter: Matthias Nagel <matthias.nagel>
Component: Startup processAssignee: Plasma Bugs List <plasma-bugs>
Status: REPORTED ---    
Severity: normal CC: kde
Priority: NOR    
Version: 6.2.4   
Target Milestone: 1.0   
Platform: Gentoo Packages   
OS: Linux   
Latest Commit: Version Fixed In:
Sentry Crash Report:

Description Matthias Nagel 2024-12-15 12:41:25 UTC
SUMMARY

On a multi-locale system, which uses a different locale for system daemons and user sessions, Plasma/KDE uses the wrong locale upon initial login if `plasma-localerc` has not yet been created. The function `runStartupConfig` reads the environment variable `LANG` at a wrong moment in time which leads to a faulty value for a system with a multi-locale setup, i.e. a system which uses a different locale for system processes and user processes (i.e. those started by `systemd --user`).

This bug can either be solved within Plasma/KDE or by SDDM or even both. The bug is the result of an unlucky interaction between Plasma/KDE and SDDM and bad timing.

STEPS TO REPRODUCE

**Prerequisites**

This bug only becomes apparent if one uses different locales as the system's default and for user processes. The system's default locale is set as `LANG=C.UTF-8` in `/etc/locale.conf`. This ensures to get unlocalized messages in the system log.

The file `/etc/locale-users.conf` sets `LANG=de_DE.UTF-8` as the default for ordinary user accounts. This file is used used in various places. The file `/etc/environment.d/20-locale.conf` is a symbolic link to `/etc/locale-users.conf`. The PAM module `pam_env.so` and the user's systemd process `systemd --user` parses the directory `/etc/environment.d/` upon session creation. Moreover, certain user-facing system services uses the file `/etc/locale-users.conf` to setup a localized environment via systemd service drop-ins. For `user@.service` and `sddm.service`, there is `/etc/systemd/system/{user@.service.d,sddm.service.d}/override.conf` with

```
[Service]
EnvironmentFile=-/etc/locale-users.conf
```

This way, SDDM greets user with a localized UI.

**The actual bug**

For the Plasma/KDE part the relevant code snippet is in "startkde/startplasma.cpp:Backend::openSession() (lines 177-217). At the end of that method, the LANG variable gets a special treatment: If the variable LANG is not set in formatsConfig (aka plasma-localerc), but set as an environment variable, then the **current** value of that environment variable is written to plasma-localerc and synced. I stress the word “current”, because timing is crucial.

For SDDM, the relevant part is somewhere in the sddm-helper application. sddm-helper clears the environment variables and then re-constructs a “cleansed” environment.

Here is what happens. A typical pstree looks like

systemd,1 --switched-root --system --deserialize=50 splash
  ├─sddm,711
  │   └─sddm-helper,886 --socket /tmp/sddm-auth-65c418cf-f7c6-4130-8213-9d60d6c82829 --id 1 --start /usr/libexec/plasma-dbus-run-session-if-needed /usr/bin/startplasma-wayland --user matthias
  │       └─startplasma-wayland,935
  └─systemd,908 --user
      └─plasmashell,1221 --no-respawn

sddm (PID 711) creates the initial login screen. Although this process runs as a child of the system's systemd (PID 1), the environment is fine:

```
/proc # cat 711/environ | tr '\0' '\n' | egrep LANG
LANG=de_DE.UTF-8
GDM_LANG=de_DE.UTF-8
LANGUAGE=de_DE:en_US
```

(Because of that service drop-in for sddm.service.) When the user attempts to authenticate, sddm spawns sddm-helper. This sddm-helper clears the environment and creates a “cleansed” one:

/proc # cat 886/environ | tr '\0' '\n'
LANG="C.UTF-8"

(Note: I did not even use egrep here to filter for LANG. That is everything which is set.) sddm-helper spawns startplasma-wayland. Now, this is the unlucky moment in time, when startplasma-wayland picks up the wrong initial value for LANG due to the code in void runStartupConfig().

The environment for the user’s systemd (PID 908) is fine again:

/proc # cat 908/environ | tr '\0' '\n' | egrep LANG
LANG=de_DE.UTF-8
GDM_LANG=de_DE.UTF-8
LANGUAGE=de_DE:en_US

Unfortunately, this is too late, because Plasma has already read and written the wrong value for LANG.

This is a bug in either SDDM or Plasma or both. I do not know, why SDDM clears the environment. Maybe as a safety measure to clear any potentially harmful environment variables a user might have been set. But in doing so, SDDM goes a little over the edge. Or it is a bug in Plasma, because Plasma tries to read LANG at the wrong moment in time.

I see to possible solutions for that bug:

1. Maybe Plasma should postpone reading the `LANG` variable until Plasma runs within the user’s SystemD session after everything is “proper” again.
2. Maybe sddm-helper should not clear all environment variables, but stash away the values of harmless environment variables (such as `LANG`) and restore them to their original value. 

Obviously, both fixes can also be combined.

OBSERVED RESULT

On a multi-locale system, which uses a different locale for system daemons and user sessions, Plasma/KDE uses the wrong locale upon initial login if `plasma-localerc` has not yet been created.

EXPECTED RESULT

Plasma/KDE should use the correct value for LANG from the user's environment upon initial login.

SOFTWARE/OS VERSIONS
Linux: Gentoo Linux 2.17
KDE Plasma Version: 6.2.4
KDE Frameworks Version: 6.7.0
Qt Version: 6.7.3
Kernel: 6.12.4-gentoo
Graphics Platform: Wayland
Comment 1 Matthias Nagel 2024-12-15 13:09:36 UTC
I posted the bug at SDDM, too: https://github.com/sddm/sddm/issues/2021