Skip to content
This repository has been archived by the owner on Sep 9, 2021. It is now read-only.

[freebsd] basuctl status default PID of system bus is off-by-one #39

Closed
jbeich opened this issue Aug 25, 2021 · 9 comments
Closed

[freebsd] basuctl status default PID of system bus is off-by-one #39

jbeich opened this issue Aug 25, 2021 · 9 comments

Comments

@jbeich
Copy link
Contributor

jbeich commented Aug 25, 2021

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
@jbeich jbeich changed the title [freebsd] basuctl status is off-by-one with default PID of system bus [freebsd] basuctl status default PID system bus is off-by-one Aug 25, 2021
@jbeich jbeich changed the title [freebsd] basuctl status default PID system bus is off-by-one [freebsd] basuctl status default PID of system bus is off-by-one Aug 25, 2021
@kennylevinsen
Copy link
Collaborator

Does it happen on FreeBSD 13 too? Can you try to verify what this is returning in your case?

.pid = cred.cr_pid,

@jbeich
Copy link
Contributor Author

jbeich commented Aug 26, 2021

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 given wl_client_get_credentials also uses cr_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

@kennylevinsen
Copy link
Collaborator

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

@jbeich
Copy link
Contributor Author

jbeich commented Aug 26, 2021

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)".

@kennylevinsen
Copy link
Collaborator

Hmm, that's a problem and means we can't use LOCAL_PEERCRED as substitute for SO_PEERCRED at all in a client setting where a server may have forked after listen(2) as SO_PEERCRED reports on the state of the process at the time of connect(2) or socketpair(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.

@kennylevinsen
Copy link
Collaborator

(Alternatively, it may be that the behavior of the dbus server itself should be considered broken on freebsd.)

@kennylevinsen
Copy link
Collaborator

Can you check if #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.

@jbeich
Copy link
Contributor Author

jbeich commented Sep 3, 2021

Can you check if #40 is a functioning workaround?

No regressions:

  • mako still works fine, including service activation
  • LIBSEAT_BACKEND=consolekit2 ck-launch-session dbus-run-session sway still works fine
  • xdg-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             -             -                         -          -                  

@kennylevinsen
Copy link
Collaborator

Thank you for testing!

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

No branches or pull requests

2 participants