Created attachment 222189 [details]
Patch against the ports tree
Patch that removes the `unlink` call before binding some UNIX socket.
The problem with the existing approach is that, when Xorg is launched as `root`, it can always unlink existing sockets, which it does when no display is explicitly specified and `-displayfd` is used.
Moreover, the X server removes the UNIX socket when exiting (even in most abnormal cases).
Typically, sddm exactly triggers the problem. So when you try to open another session through it, the first session's sockets are crushed and it becomes stale.
I'm proposing the patch here since it is not practically useful on platforms that launch Xorg with an unprivileged user and because upstream seems inactive.
I am quite skeptical of pulling this in without it first being submitted and accepted upstream.
Can you explain exactly what problem you are trying to solve?
As for the high-level problem I'm fixing, I wrote this description:
> Typically, sddm exactly triggers the problem. So when you try to open
> another session through it, the first session's sockets are crushed
> and it becomes stale.
What do you find unclear in it exactly?
As for the low-level description, let me recapitulate with more context. As you most probably know, there are two ways that Xorg selects its display at startup:
- Either you supply an explicit display on the command-line (e.g., ":1").
- Or you do not, and either "-displayfd" has been specified, in which case Xorg will try to assign some automatically, or it has not, in which case :0 is used by default.
("-displayfd" has other effects, but this is a separate discussion, relevant to the other bug #253278.)
The problem is with the automatic assignment of display. It works by trying to grab the first display available (from :0 when using UNIX sockets), which it does by simply unlinking an existing socket file and then binding a new socket to the same file. When the server is run as root, this operation always succeeds, and any existing socket for :0 ("/tmp/.X11-UNIX/X0") that would exist is removed. This leaves any preexisting X session on :0 stale (e.g., launching new apps make them go to the new session).
And SDDM triggers that: It passes "-displayfd", and no display directive, relying on the server to do display assignmnent, which it doesn't do correctly.
Now, I agree that this problem is probably not FreeBSD specific (it affects platforms/distributions running Xorg as root). If you prefer, I'll report it upstream and we'll see how it goes.
Amusingly, I found this code at start of 'startx':
# Automatically determine an unused $DISPLAY
while true ; do
[ -e "/tmp/.X$d-lock" -o -S "/tmp/.X11-unix/X$d" ] || break
d=$(($d + 1))
This is exactly what the proposed change makes X (launched with '-displayfd') do.
Reported upstream here:
+1. Prevents Plasma/Wayland (debug session) destroying X11 socket used by Sway (dogfood session) at least until https://invent.kde.org/plasma/kwin/-/commit/9f0f4527029a. Both run Xwayland with different flags e.g.,
|-- login [pam] (login)
| `-- sway
|-- Xwayland :0 -rootless -terminate -core -listenfd 35 -listenfd 37 -wm 40
|-- login [pam] (login)
| `-- ck-launch-session dbus-run-session startplasma-wayland
| `-- dbus-run-session startplasma-wayland
| |-- dbus-daemon --nofork --print-address 4 --session
| `-- startplasma-wayland
| `-- kwin_wayland_wrapper --xwayland ../libexec/startplasma-waylandsession (kwin_wayland_wrappe)
| `-- kwin_wayland --wayland_fd 4 --xwayland ../libexec/startplasma-waylandsession
| `-- Xwayland -displayfd 49 -rootless -wm 52 -auth /var/run/user/1234/xauth_XOBvXm
Notice, Sway doesn't use -displayfd unlike Plasma but simply checks locks.
I would like upstream to comment on the MR that is in the patch in Phab that Jan linked here before we commit this.