On FreeBSD >= 12.3 basu uses cr_pid
which returns PID that appears to be off-by-one.
$ pkg install basu dbus
$ service dbus onestart
$ mount -t linprocfs nil /proc
$ basuctl status
BusAddress=unix:path=/var/run/dbus/system_bus_socket
BusScope=system
BusID=0123456789abcdef0123456789abcdef
<27>(../src/busctl/busctl.c:1282) Failed to get credentials: No such process
$ truss basuctl status 2>&1 | grep open.\*proc
open("/proc/1233/status",O_RDONLY|O_CLOEXEC,0666) ERR#2 'No such file or directory'
$ ps lp $(pgrep -f dbus.\*system)
UID PID PPID C PRI NI VSZ RSS MWCHAN STAT TT TIME COMMAND
556 1234 1 2 20 0 14324 3812 select Is - 0:00,02 /usr/local/bin/dbus-daemon --system
$ sockstat -nlu | awk 'FNR == 1 || /system_bus/'
USER COMMAND PID FD PROTO LOCAL ADDRESS FOREIGN ADDRESS
556 dbus-daemo 1234 3 stream /var/run/dbus/system_bus_socket
$ dbus-send --system --print-reply --dest=org.freedesktop.DBus / org.freedesktop.DBus.GetConnectionUnixProcessID string:org.freedesktop.DBus
method return time=1234567890.123456 sender=org.freedesktop.DBus -> destination=:1.57 serial=3 reply_serial=2
uint32 1234
Does it happen on FreeBSD 13 too? Can you try to verify what this is returning in your case? https://github.com/emersion/basu/blob/928a746f7ebd83812ddb152a5c0fb11a0a294c93/src/basic/socket-util.c#L45
Does it happen on FreeBSD 13 too?
Yep, confirmed inside 13.0 amd64 jail on -CURRENT kernel. I only dogfood -CURRENT and can't easily test older kernels.
Can you try to verify what this is returning in your case?
1233 aka invalid PID that's 1 digit smaller than system dbus daemon uses:
(lldb) p cred (xucred) $1 = { cr_version = 0 cr_uid = 0 cr_ngroups = 1 cr_groups = { [0] = 0 [1] = 0 [2] = 0 [3] = 0 [4] = 0 [5] = 0 [6] = 0 [7] = 0 [8] = 0 [9] = 0 [10] = 0 [11] = 0 [12] = 0 [13] = 0 [14] = 0 [15] = 0 } = (_cr_unused1 = 0x00000000000005b6, cr_pid = 1233) }Buggy
LOCAL_PEERCRED
is unlikely givenwl_client_get_credentials
also usescr_pid
and works fine (as used by Sway) e.g.,$ swaymsg -t get_tree | jq -r '.. | select(.shell? == "xdg_shell") | .pid' | xargs ps lp UID PID PPID C PRI NI VSZ RSS MWCHAN STAT TT TIME COMMAND 1111 59937 1 1 20 0 1052380 492464 select Ss - 0:51,10 emacs --daemon (emacs-28.0.50) 1111 60064 1 0 20 0 432144 29312 kqread S - 0:30,91 alacritty
Buggy LOCAL_PEERCRED is unlikely given wl_client_get_credentials also uses cr_pid and works fine (as used by Sway)
Hmm, if that's immediately after the call to LOCAL_PEERCRED, it would have to be either a buggy result or a wrong fd we're querying (not sure why that would be). I can try to poke at it a bit later.
The freshports libwayland-server doesn't use cr_pid on freebsd 12 btw - https://cgit.freebsd.org/ports/tree/graphics/wayland/files/patch-src_wayland-server.c#n88
a buggy result or a wrong fd we're querying
fd looks correct but PID maybe stale if dbus-daemon forked after listen call.
(lldb) p fd (int) $0 = 3 $ procstat -f $(pgrep basuctl) | awk 'FNR == 1 || $3 == 3' PID COMM FD T V FLAGS REF OFFSET PRO NAME 77791 basuctl 3 s - rw---n-- 1 0 UDS 0 0 /var/run/dbus/system_bus_socket
unix(4) says "the credentials presented to the client (the connect(2) caller) are those of the server when it called listen(2)".
Hmm, that's a problem and means we can't use
LOCAL_PEERCRED
as substitute forSO_PEERCRED
at all in a client setting where a server may have forked afterlisten(2)
asSO_PEERCRED
reports on the state of the process at the time ofconnect(2)
orsocketpair(2)
.I would also argue that the behavior of LOCAL_PEERCRED here may be semi-broken, as I can't the value in reporting the pid of a process that may no longer exist if daemonization has occurred after
listen(2)
.If things worked on older FreeBSD, it may mean that we can just ignore cr_pid and report an invalid pid.
(Alternatively, it may be that the behavior of the dbus server itself should be considered broken on freebsd.)
Can you check if https://github.com/emersion/basu/pull/40 is a functioning workaround?
To be able to retrieve the PID on FreeBSD, we'd need something that returns the PID of the peer at the time of
connect(2)
, but if it works better to not read the PID, that should be fine for now.
Can you check if #40 is a functioning workaround?
No regressions:
mako
still works fine, including service activationLIBSEAT_BACKEND=consolekit2 ck-launch-session dbus-run-session sway
still works finexdg-desktop-portal-wlr
still works fine with Firefox$ basuctl status BusAddress=unix:path=/var/run/dbus/system_bus_socket BusScope=system BusID=0123456789abcdef0123456789abcdef -<27>(../src/busctl/busctl.c:1282) Failed to get credentials: No such process +EUID=0 +EGID=0 +Unit=n/a +Slice=n/a +UserUnit=n/a +UserSlice=n/a +Session=n/a$ basuctl list before NAME PID PROCESS USER CONNECTION UNIT SESSION DESCRIPTION -org.freedesktop.DBus - - - - - - - +org.freedesktop.DBus - - root - - - -
Thank you for testing!