From 11895cd087b64e47f69fb01828c5206427e3049a Mon Sep 17 00:00:00 2001 From: Kir Kolyshkin Date: Tue, 1 Feb 2022 13:45:58 -0800 Subject: [PATCH 1/2] libct/cg/sd: escape dbus address value D-Bus specification [1] requires that the values in server address need to be escaped in a special way, and other clients perform the needed escaping (e.g. systemd [2] does that, as well as recent godbus [3]). More to say, it is important to perform such escaping, since if dbus sees a character that should have been escaped but it's not, it returns an error [4]. Fix tryDiscoverDbusSessionBusAddress to use dbus.EscapeBusAddressValue function, recently added to godbus [3]. [1] https://dbus.freedesktop.org/doc/dbus-specification.html#addresses [2] https://github.com/systemd/systemd/blob/5efbd0bf897a990ebe43d7dc69141d87c404ac9a/src/libsystemd/sd-bus/bus-internal.c#L294-L318 [3] https://github.com/godbus/dbus/pull/302 [4] https://gitlab.freedesktop.org/dbus/dbus/-/blob/37b76d13738e782fe2eb12abdd0179745c0b3f81/dbus/dbus-address.c#L330 Signed-off-by: Kir Kolyshkin --- libcontainer/cgroups/systemd/user.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcontainer/cgroups/systemd/user.go b/libcontainer/cgroups/systemd/user.go index 0f50f76eee4..cdcec06a07b 100644 --- a/libcontainer/cgroups/systemd/user.go +++ b/libcontainer/cgroups/systemd/user.go @@ -87,7 +87,7 @@ func DetectUserDbusSessionBusAddress() (string, error) { if xdr := os.Getenv("XDG_RUNTIME_DIR"); xdr != "" { busPath := filepath.Join(xdr, "bus") if _, err := os.Stat(busPath); err == nil { - busAddress := "unix:path=" + busPath + busAddress := "unix:path=" + dbus.EscapeBusAddressValue(busPath) return busAddress, nil } } From 1a935208410a353be149df7100b26c8490b14556 Mon Sep 17 00:00:00 2001 From: Kir Kolyshkin Date: Thu, 27 Jan 2022 18:16:34 -0800 Subject: [PATCH 2/2] libct/cg/sd: simplify DetectUserDbusSessionBusAddress Apparently, "systemctl --user --no-pager show-environment" is useless without DBUS_SESSION_BUS_ADDRESS or XDG_RUNTIME_DIR set: $ echo $DBUS_SESSION_BUS_ADDRESS, $XDG_RUNTIME_DIR unix:path=/run/user/1000/bus, /run/user/1000 $ systemctl --user --no-pager show-environment | grep DBUS_SESS DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus $ unset DBUS_SESSION_BUS_ADDRESS $ systemctl --user --no-pager show-environment | grep DBUS_SESS DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus $ unset XDG_RUNTIME_DIR $ systemctl --user --no-pager show-environment | grep DBUS_SESS Failed to connect to bus: $DBUS_SESSION_BUS_ADDRESS and $XDG_RUNTIME_DIR not defined (consider using --machine=@.host --user to connect to bus of other user) So, it does not make sense to try it to get the address. Also, it does not make sense to suggest "systemctl --user start dbus" either, for the same reason, so remove that suggestion from the error message text. Since DBUS_SESSION_BUS_ADDRESS environment variable, on which the code relies, is et by dbus-run-session (or dbus-launch, or something similar that is supposed to be run during the login process), add a suggestion to re-login. Finally, fix the following linter warning: > error-strings: error strings should not be capitalized or end with punctuation or a newline (revive) Signed-off-by: Kir Kolyshkin --- libcontainer/cgroups/systemd/user.go | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/libcontainer/cgroups/systemd/user.go b/libcontainer/cgroups/systemd/user.go index cdcec06a07b..6fa1cc77639 100644 --- a/libcontainer/cgroups/systemd/user.go +++ b/libcontainer/cgroups/systemd/user.go @@ -77,9 +77,8 @@ func DetectUID() (int, error) { return -1, errors.New("could not detect the OwnerUID") } -// DetectUserDbusSessionBusAddress returns $DBUS_SESSION_BUS_ADDRESS if set. -// Otherwise returns "unix:path=$XDG_RUNTIME_DIR/bus" if $XDG_RUNTIME_DIR/bus exists. -// Otherwise parses the value from `systemctl --user show-environment` . +// DetectUserDbusSessionBusAddress returns $DBUS_SESSION_BUS_ADDRESS, if set. +// Otherwise it returns "unix:path=$XDG_RUNTIME_DIR/bus", if $XDG_RUNTIME_DIR/bus exists. func DetectUserDbusSessionBusAddress() (string, error) { if env := os.Getenv("DBUS_SESSION_BUS_ADDRESS"); env != "" { return env, nil @@ -91,16 +90,5 @@ func DetectUserDbusSessionBusAddress() (string, error) { return busAddress, nil } } - b, err := exec.Command("systemctl", "--user", "--no-pager", "show-environment").CombinedOutput() - if err != nil { - return "", fmt.Errorf("could not execute `systemctl --user --no-pager show-environment` (output=%q): %w", string(b), err) - } - scanner := bufio.NewScanner(bytes.NewReader(b)) - for scanner.Scan() { - s := strings.TrimSpace(scanner.Text()) - if strings.HasPrefix(s, "DBUS_SESSION_BUS_ADDRESS=") { - return strings.TrimPrefix(s, "DBUS_SESSION_BUS_ADDRESS="), nil - } - } - return "", errors.New("could not detect DBUS_SESSION_BUS_ADDRESS from `systemctl --user --no-pager show-environment`. Make sure you have installed the dbus-user-session or dbus-daemon package and then run: `systemctl --user start dbus`") + return "", errors.New("could not detect DBUS_SESSION_BUS_ADDRESS from the environment; make sure you have installed the dbus-user-session or dbus-daemon package; note you may need to re-login") }