Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WSLg's runtime-dir has always owner 1000 resulting in inaccessable runtime dir for default user #9689

Closed
martin-rueegg opened this issue Feb 24, 2023 · 4 comments

Comments

@martin-rueegg
Copy link

martin-rueegg commented Feb 24, 2023

Versions

Windows Version

10.0.19045.2604

WSL Version

  • WSL 2

Kernel Version

5.15.90.1

Distro Version

Ubuntu 22.04 (with systemd enabled)

Other Software

WSL version: 1.1.3.0
Kernel version: 5.15.90.1
WSLg version: 1.0.49
MSRDC version: 1.2.3770
Direct3D version: 1.608.2-61064218
DXCore version: 10.0.25131.1002-220531-1700.rs-onecore-base2-hyp
Windows version: 10.0.19045.2604

Repro Steps

  • make sure you run WSL version 1.1.3.0
  • make sure your default distribution is Ubuntu, version 22.04, with systemd enabled
    C:\>wsl.exe --status
    Default Distribution: Ubuntu
    Default Version: 2
    
  • in your default distribution, create a user with UID other than 1000 1
  • make that user the default user in /etc/wsl.conf 2
  • optionally, make the same user the default user for this distribution in the windows registry3
  • shut down WSL wsl.exe --shutdown or at least the distro in question (wsl.exe --terminate Ubuntu)
  • login (with the new default user) using wsl.exe without parameters (as it's the default user of the default distro) and check that you have read access to your runtime dir:
    ls -la "$XDG_RUNTIME_DIR"

Expected Behavior

The user's run directory ("$XDG_RUNTIME_DIR", i.e. /run/user/$UID) is read-writable and has the required sockets set up, e.g.:

$ ls -la "$XDG_RUNTIME_DIR"
total 0
drwx------ 9 new_user  new_user  280 Feb 24 15:36 .
drwxr-xr-x 3 root root  60 Feb 24 15:36 ..
srw-rw-rw- 1 new_user  new_user    0 Feb 24 15:36 bus
drwx------ 3 new_user  new_user   60 Feb 24 15:36 dbus-1
drwx------ 2 new_user  new_user   60 Feb 24 15:36 dconf
drwx------ 2 new_user  new_user  140 Feb 24 15:36 gnupg
dr-x------ 2 new_user  new_user    0 Feb 24 15:36 gvfs
drwx------ 2 new_user  new_user   40 Feb 24 15:36 gvfsd
srw-rw-rw- 1 new_user  new_user    0 Feb 24 15:36 pipewire-0
-rw-rw---- 1 new_user  new_user    0 Feb 24 15:36 pipewire-0.lock
srw-rw-rw- 1 new_user  new_user    0 Feb 24 15:36 pk-debconf-socket
drwx------ 2 new_user  new_user   80 Feb 24 15:36 pulse
srw-rw-rw- 1 new_user  new_user    0 Feb 24 15:36 snapd-session-agent.socket
drwxr-xr-x 5 new_user  new_user  140 Feb 24 15:36 systemd

It can be either

  • a bind mount to /mnt/wslg/runtime-dir (if, and only if the owner of that dir corresponds with the current user), usually shown as none /run/user/$UID type tmpfs (rw,relatime) in mount's output
  • a tmpfs mount with the options rw,nosuid,nodev,relatime,size=6565592k,nr_inodes=1641398,mode=700,uid=$UID,gid=$UID

It can easily be tested with the following command, which should only return 1 entry:

findmnt "$XDG_RUNTIME_DIR"

Actual Behavior

The directory /mnt/wslg/runtime-dir is always owned UID 1000, whether or not this UID is assigned to a user in /etc/passwd.

The runtime directory is not accessible:

$ ls -la "$XDG_RUNTIME_DIR"
ls: cannot open directory '/run/user/1234/': Permission denied

In fact, runtime directory ("$XDG_RUNTIME_DIR", /run/user/$UID seems to be mounted twice4, at least when logging in as a user with an UID other than 1000:

user@host:~$ findmnt "$XDG_RUNTIME_DIR"
TARGET         SOURCE             FSTYPE OPTIONS
/run/user/1234 tmpfs              tmpfs  rw,nosuid,nodev,relatime,size=6565592k,nr_inodes=1641398,mode=700,uid=1234,gid=1234
/run/user/1234 none[/runtime-dir] tmpfs  rw,relatime

The first would be the regular mount for that user. However, it's "shadowed" by the bind mount to /mnt/wslg/runtime-dir, despite the later being owned by another user. As such, the current user's run directory becomes inaccessible:

$ ls -ldn /mnt/wslg/runtime-dir "$XDG_RUNTIME_DIR"
drwx------ 4 1000 1000 120 Feb 24 01:03 /mnt/wslg/runtime-dir
drwx------ 4 1000 1000 120 Feb 24 01:03 /run/user/1234

If, however, the later mount is removed with sudo umount "$XDG_RUNTIME_DIR", then the "real" directory becomes "visible" and accessible and apps that require access to e.g. d-bus other sockets can now succeed:

$ ls -ldn /mnt/wslg/runtime-dir "$XDG_RUNTIME_DIR"
drwx------ 4 1000 1000 120 Feb 24 01:03 /mnt/wslg/runtime-dir
drwx------ 9 1234 1234 280 Feb 24 01:03 /run/user/1234

Further observations/remarks

  • While the runtime-dir is not accessible graphical apps don't work, or not fully.
  • It might make sense that the directory /mnt/wslg/runtime-dir should be owned by the default user (as set in /etc/wsl.conf).

Workaround

I've been able do make things work by adding the following snippet to the login script:

# make sure, XDG_RUNTIME_DIR is set
declare -i MyUID=$(id -u)
XDG_RUNTIME_DIR=${XDG_RUNTIME_DIR:-/run/user/$MyUID}
export XDG_RUNTIME_DIR

while findmnt --shadow -n -o SOURCE "$XDG_RUNTIME_DIR" >/dev/null; do
	echo "Unmounting '$XDG_RUNTIME_DIR'" >&2
	sudo umount "$XDG_RUNTIME_DIR"
done

Diagnostic Logs

WslLogs-2023-02-24_16-35-04.zip

Footnotes

  1. Login as root: wsl.exe -u root and then run:

    NEW_USER=new_user
    NEW_UID=1234
    sudo addgroup --gid $NEW_UID $NEW_USER
    sudo adduser --uid $NEW_UID --gid $NEW_UID --disabled-password $NEW_USER
    
  2. Still as root, run editor /etc/wsl.conf and add or adjust the following section, making sure that the default property under user section is set to new_user:

    [user]
    default=new_user
    
  3. In the same root session, run the following command:

    $(wslupath 'C:\')Windows/System32/WindowsPowerShell/v1.0/powershell.exe \
     "Get-ItemProperty 'Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Lxss\\{*}\' DistributionName" \
     "| Where-Object -Property DistributionName -eq $WSL_DISTRO_NAME" \
     "| Set-ItemProperty -Name DefaultUid -Value $(id -u $NEW_USER)"
    
  4. I had one occasion, where there was actually only the bind mount, but not the tempfs mount. However, I was not able to reproduce that case. Might be related to the following issue: UAC elevated / basic level of wslhost.exe cause different mount "namespaces" #9690.

@martin-rueegg
Copy link
Author

If this issue should actually be filed against microsoft/wslg, happy to create it there again.

@cerebrate
Copy link

This and related runtime dir issues have, unfortunately, been something of a long-running issue (see #8918 and #9025, primarily).

I think the best (most functionality-preserving) current solution is the one I espouse here, in which overlayfs is used to give every user/uid access to their own user runtime directory as in native Linux, but in which the WSLg sockets are effectively made to appear in all of them.

@cforce
Copy link

cforce commented Apr 21, 2023

Same here ..really annoying

Copy link
Contributor

This issue has been automatically closed since it has not had any activity for the past year. If you're still experiencing this issue please re-file this as a new issue or feature request.

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants