microsoft / WSL

Issues found on WSL
https://docs.microsoft.com/windows/wsl
MIT License
17.46k stars 821 forks source link

/tmp/.X11-unix is being mounted read-only #9303

Closed AndASM closed 1 year ago

AndASM commented 1 year ago

Version

WSL version: 1.0.3.0

WSL Version

Kernel Version

5.15.79.1-microsoft-standard-WSL2

Distro Version

Ubuntu 22.10

Other Software

systemd 251 (251.4-1ubuntu7)

Repro Steps

Run any kind of secondary X11 server. You get an error that /tmp/.X11-unix is a read-only filesystem.

Expected Behavior

Secondary X servers should work. /tmp/.X11-unix should not be read-only.

Actual Behavior

E bind(5, {AF=1 "/tmp/.X11-unix/X1"}, 19): Read-only file system

Diagnostic Logs

No response

AndASM commented 1 year ago

See here for a comment on how and why this was broken.

Overwriting and overriding the system is not a very good approach. A more standard approach to running guest distributions in a virtualized or containerized environment may result in much less maintenance, fewer compatibility issues, and fewer regressions.

Mischala commented 1 year ago

Can be reproduced by installing the kali-win-kex package, on Kali Linux in WSL2 and trying to run kex --win

This should produce a VNC session to the virtualized Kali distro, but it fails to create the connection, as the /tmp/.X11-unix is uneditable.

elsaco commented 1 year ago

@Mischala to get kex --win working remount /tmp/.X11-unix with rw option:

sudo mount -o remount,rw /tmp/.X11-unix

After this sockets can be added, sample output:

┌──(tux㉿eleven)-[~]
└─$ kex --win

Win-KeX server sessions:

X DISPLAY #     RFB PORT #      RFB UNIX PATH   PROCESS ID #    SERVER
1               5901                            53              Xtigervnc

You can use the Win-KeX client to connect to any of these displays.

┌──(tux㉿eleven)-[~]
└─$ ls -la /tmp/.X11-unix/
total 4
drwxrwxrwx 2 root root   80 Dec 11 09:43 .
drwxrwxrwt 5 root root 4096 Dec 11 09:43 ..
srwxrwxrwx 1 tux  tux     0 Dec 11 09:39 X0
srwxrwxrwx 1 tux  tux     0 Dec 11 09:43 X1

Notice there are two sockets in /tmp/.X11-unix with X1 being used by kex.

kex and wslg running:

kex-win_xterm_test

AndASM commented 1 year ago

Similar to @elsaco's advice above, I worked around this issue by adding:

ExecStartPre=+/usr/bin/mount -o remount,rw /tmp/.X11-unix

To the systemd service unit for the secondary X server I am launching. ExecStartPre for running commands before the main service executable. + at the start of a command, so it runs with full privileges instead of any restricted user or group set in the unit file, since you need root privileges to remount like that.

OneBlue commented 1 year ago

Thank you for reporting this @AndASM.

Unfortunately with this kind of issue it's pretty much impossible to have a 100% perfect solution. This directory is mounted read-only by default to prevent systemd-units (like gdm for instance) from deleting the 'X0' socket, which would break wslg.

Given that a secondary X server is an advanced scenario, the officially recommended way of doing this would be what you suggested: remounting /tmp/.X11-unix as rw before writing there.

esumii commented 1 year ago

Hijacking such a common directory in its entirety is not a good idea - how about a symlink?

sudo umount /tmp/.X11-unix
ln -sf /mnt/wslg/.X11-unix/X0 /tmp/.X11-unix/
AndASM commented 1 year ago

@OneBlue, this issue seems to effect a number of users and not be resolved. Would you please re-open it for discussion and evaluation?

Unfortunately with this kind of issue it's pretty much impossible to have a 100% perfect solution. This directory is mounted read-only by default to prevent systemd-units (like gdm for instance) from deleting the 'X0' socket, which would break wslg.

So, is WSL an environment or a distribution? Isn't this problem caused by the hybrid approach? The systemd units are breaking it, because WSL is overwriting system files and settings in a more malware-like way. It is monkey-patching the system. It would be easier to use the built-in extension points instead of monkey-patching system files and configuration! Plus it would be more secure. It's hard to use any kind of system file protection or validation with WSL2, when at any time a patch could be released where WSL will monkey-patch the guest system in arbitrary and non-standard ways! Since WSL2 can, to a degree, control the host system, isn't that creating a large surface area for security problems??

By changing how standard system extension points like the .X11-unix folder work, WSL is breaking compatibility with just about everything. This appears to have been done to work around a current compatibility issue with a specific set of release versions of of Ubuntu for WSL. These issues appear to have been fixed in the preview version of Ubuntu for WSL, so the changes aren't required for version 22.10 and after. While I agree there is no 100% perfect solution, I argue that breaking the standards to work around a current compatibility issue is even less ideal. If it is also being done in the hopes it also allows easier installation of arbitrary third party distributions, I would argue that installing an untested and possibly incompatible distribution IS an advanced activity. The work around will likely cause more issues and workarounds, not less! Anyone trying to integrate the system will most likely have to trip over this issue, spend time diagnosing it, then spending time fixing it. The same as they would have to if the system remounts, overwrites, or deletes the folder or socket.

Instead, would it not be better for WSL2 to provide documented interfaces, services, and/or drivers? Similar to guest tools and packages like are provided for other virualizers? It is after all a set of extensions and wrapper tools for Hyper-V. If we had services and extension points, we could create normal system packages for each distribution. These could properly configure the distributions, instead of applying arbitrary non-standard monkey-patches.

That approach would also allow non-FHS distributions (like NixOS) to more easily integrate, since the folders and mount points WSL2 is using may not exist. So arbitrarily assuming and writing to them would at best not work, and in worse cases possibly do damage.

In my own Ubuntu install, I have been having better luck writing packages that first remove and clean up all changes made by WSL's invasive init system, then re-applying them through the standard interfaces. Suddenly everything just works, the first time.. until some new monkey-patch is added that has to be undone, like making a standard read-write system folder read-only.

AndASM commented 1 year ago

Hijacking such a common directory in its entirety is not a good idea - how about a symlink?

Good idea!

You could also bind-mount a file like a socket, which might be more robust against other changes like /mnt/WSL being moved, unavailable, or unmounted.

Using one of those approaches, one could make an ugly workaround. A simple daemon could be made that monitors /tmp/.X11-unix/X0 and re-binds it or binds the next available socket (e.g. X1, X2, ...) if something unbinds it. That would at least make a service that is visible to the user instead of some invisible force rewriting the system. It would be less ugly than the current workaround of mounting a standard read-write system folder as read-only.

AndASM commented 1 year ago

Given that a secondary X server is an advanced scenario, the officially recommended way of doing this would be what you suggested: remounting /tmp/.X11-unix as rw before writing there.

Another case against this: Containerized development (also remote development as there is heavy overlap of requirements.) The X protocol can be used over network and other remote sockets. As such it is commonly used for remote desktop- or virtualisation- purposes. OpenSSH, a component of both Windows and Linux, supports forwarding X sockets.

For an example of a tool that that uses remote or containerized development, see Microsoft's Visual Studio Code. It doesn't use the X protocol. But plugins and add-on tools might use it to display graphical elements from within the development containers. See Microsoft's Development Containers open specification and Microsoft's cli reference implementation.

ladieman217 commented 1 year ago

@elsaco Thanks, it works

TonnyAndre commented 1 year ago

ExecStartPre=+/usr/bin/mount -o remount,rw /tmp/.X11-unix

i tryed that but i receive the massage " -o: command not found"

mrfoxie commented 1 year ago

@Mischala to get kex --win working remount /tmp/.X11-unix with rw option:

sudo mount -o remount,rw /tmp/.X11-unix

After this sockets can be added, sample output:

┌──(tux㉿eleven)-[~]
└─$ kex --win

Win-KeX server sessions:

X DISPLAY #     RFB PORT #      RFB UNIX PATH   PROCESS ID #    SERVER
1               5901                            53              Xtigervnc

You can use the Win-KeX client to connect to any of these displays.

┌──(tux㉿eleven)-[~]
└─$ ls -la /tmp/.X11-unix/
total 4
drwxrwxrwx 2 root root   80 Dec 11 09:43 .
drwxrwxrwt 5 root root 4096 Dec 11 09:43 ..
srwxrwxrwx 1 tux  tux     0 Dec 11 09:39 X0
srwxrwxrwx 1 tux  tux     0 Dec 11 09:43 X1

Notice there are two sockets in /tmp/.X11-unix with X1 being used by kex.

kex and wslg running:

kex-win_xterm_test

I have to write the command all the time i use kex

leofab commented 1 year ago

@Mischala to get kex --win working remount /tmp/.X11-unix with rw option:

sudo mount -o remount,rw /tmp/.X11-unix

After this sockets can be added, sample output:

┌──(tux㉿eleven)-[~]
└─$ kex --win

Win-KeX server sessions:

X DISPLAY #     RFB PORT #      RFB UNIX PATH   PROCESS ID #    SERVER
1               5901                            53              Xtigervnc

You can use the Win-KeX client to connect to any of these displays.

┌──(tux㉿eleven)-[~]
└─$ ls -la /tmp/.X11-unix/
total 4
drwxrwxrwx 2 root root   80 Dec 11 09:43 .
drwxrwxrwt 5 root root 4096 Dec 11 09:43 ..
srwxrwxrwx 1 tux  tux     0 Dec 11 09:39 X0
srwxrwxrwx 1 tux  tux     0 Dec 11 09:43 X1

Notice there are two sockets in /tmp/.X11-unix with X1 being used by kex.

kex and wslg running:

kex-win_xterm_test

@elsaco thx so much it really helped out, just ran the commands and kex --win -s worked perfectly

aki-k commented 1 year ago
# mount -o remount,rw /tmp/.X11-unix

Also helped me with the missing Xwayland X1 socket (it wasn't created anywhere) when starting Xwayland :1 for Gnome desktop.

With this setup you can run Gnome desktop 40.4 in Rocky Linux 9 instance in WSL 2:

https://akik.kapsi.fi/rocky/