Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

libct/cg/sd: simplify DetectUserDbusSessionBusAddress #3356

Merged
merged 2 commits into from
Mar 9, 2022

Conversation

kolyshkin
Copy link
Contributor

@kolyshkin kolyshkin commented Jan 28, 2022

  1. Properly escape the value of dbus address spec.

  2. Remove using systemctl --user --no-pager show-environment because:

    • is does the same thing we do (get address from DBUS_SESSION_BUS_ADDRESS or try to construct it from XDG_RUNTIME_DIR);
    • it fails when both those variables are unset:

    $ 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 [email protected] --user to connect to bus of other user)

  3. Since it does not make sense to suggest systemctl --user start dbus
    if the proper environment is not set, remove that suggestion from the error
    message text. Since DBUS_SESSION_BUS_ADDRESS environment variable
    is set 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.

Copy link
Member

@AkihiroSuda AkihiroSuda left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

systemctl --user show-environment is for covering $XDG_RUNTIME_DIR is set but $XDG_RUNTIME_DIR/bus does not exist case, not for covering $XDG_RUNTIME_DIR is unset case

@kolyshkin
Copy link
Contributor Author

systemctl --user show-environment is for covering $XDG_RUNTIME_DIR is set but $XDG_RUNTIME_DIR/bus does not exist case, not for covering $XDG_RUNTIME_DIR is unset case

Right, I missed that path.

However, current version of systemd does the same thing as we do -- it tries "unix:path=%s/bus", where %s is the value of XDG_RUNTIME_DIR.

Here's the logic:
https://github.com/systemd/systemd/blob/be7148ebed5d73c4a76bc6089ebe2e82d8fa33e0/src/libsystemd/sd-bus/sd-bus.c#L1332-L1347

The only caveat is it uses bus_address_escape function:
https://github.com/systemd/systemd/blob/5efbd0bf897a990ebe43d7dc69141d87c404ac9a/src/libsystemd/sd-bus/bus-internal.c#L294-L318

Will take a look into it.

@kolyshkin
Copy link
Contributor Author

kolyshkin commented Feb 1, 2022

The only caveat is it uses bus_address_escape function:
https://github.com/systemd/systemd/blob/5efbd0bf897a990ebe43d7dc69141d87c404ac9a/src/libsystemd/sd-bus/bus-internal.c#L294-L318

Will take a look into it.

It seems that if we are re-creating DBUS_SESSION_BUS_ADDRESS from XDG_RUNTIME_DIR (which we do), we need to escape some characters, same as what bus_address_escape function in systemd does:
https://github.com/systemd/systemd/blob/5efbd0bf897a990ebe43d7dc69141d87c404ac9a/src/libsystemd/sd-bus/bus-internal.c#L294-L318.

Escaping rules are described at https://dbus.freedesktop.org/doc/dbus-specification.html#addresses, "Value-escaping ..."). It looks like godbus/dbus should do that.

Changing to draft for now.

@kolyshkin kolyshkin marked this pull request as draft February 1, 2022 02:55
kolyshkin added a commit to kolyshkin/dbus that referenced this pull request Feb 1, 2022
D-Bus specification 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).

More to say, if dbus sees a character that should have been escaped, it
returns an error [3].

Add EscapeBusAddressValue function (with some tests and a benchmark),
and use it from tryDiscoverDbusSessionBusAddress().

The function is exported as it might be of use to other packages (in
particular, runc [4]).

NOTE that the function does not escape '*' symbol, because de-facto it
is the list of optionally-escaped characters since 2007, but that is not
yet documented in D-Bus spec (see [5] for more details).

[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://gitlab.freedesktop.org/dbus/dbus/-/blob/37b76d13738e782fe2eb12abdd0179745c0b3f81/dbus/dbus-address.c#L330
[4] opencontainers/runc#3356
[5] https://gitlab.freedesktop.org/dbus/dbus/-/merge_requests/248

Signed-off-by: Kir Kolyshkin <[email protected]>
kolyshkin added a commit to kolyshkin/dbus that referenced this pull request Feb 1, 2022
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).

More to say, if dbus sees a character that should have been escaped, it
returns an error [3].

Add EscapeBusAddressValue function (with some tests and a benchmark),
and use it from tryDiscoverDbusSessionBusAddress().

The function is exported as it might be of use to other packages (in
particular, runc [4]).

NOTE that the function does not escape '*' symbol, because de-facto it
is the list of optionally-escaped characters since 2007, but that is not
yet documented in D-Bus spec (see [5] for more details).

[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://gitlab.freedesktop.org/dbus/dbus/-/blob/37b76d13738e782fe2eb12abdd0179745c0b3f81/dbus/dbus-address.c#L330
[4] opencontainers/runc#3356
[5] https://gitlab.freedesktop.org/dbus/dbus/-/merge_requests/248

Signed-off-by: Kir Kolyshkin <[email protected]>
@kolyshkin
Copy link
Contributor Author

OK, I have added proper address value escaping, so now our fallback is the same as systemd's (see previous comments).

@AkihiroSuda PTAL

@kolyshkin kolyshkin marked this pull request as ready for review February 1, 2022 22:00
@kolyshkin
Copy link
Contributor Author

systemctl --user show-environment is for covering $XDG_RUNTIME_DIR is set but $XDG_RUNTIME_DIR/bus does not exist case, not for covering $XDG_RUNTIME_DIR is unset case

Right, I missed that path.

However, current version of systemd does the same thing as we do -- it tries "unix:path=%s/bus", where %s is the value of XDG_RUNTIME_DIR.

In other words,

  • if XDG_RUNTIME_DIR is set, and $XDG_RUNTIME_DIR/bus exists, our code will use it and won't fall back to calling systemctl;
  • if XDG_RUNTIME_DIR is not set, or $XDG_RUNTIME_DIR/bus does not exist (ot can't be connected to), systemctl --user can not be used at all, as it needs a dbus connection.

Therefore,

  • a fallback of using systemctl is useless, as it will fail anyway.
  • suggesting to try systemctl --user start dbus in error message is useless, too, as it will fail anyway.

@kolyshkin kolyshkin requested a review from AkihiroSuda February 1, 2022 22:09
kolyshkin added a commit to kolyshkin/dbus that referenced this pull request Feb 2, 2022
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).

More to say, if dbus sees a character that should have been escaped, it
returns an error [3].

Add EscapeBusAddressValue function (with some tests and a benchmark),
and use it from tryDiscoverDbusSessionBusAddress().

The function is exported as it might be of use to other packages (in
particular, runc [4]).

NOTE that the function does not escape '*' symbol, because de-facto it
is the list of optionally-escaped characters since 2007, but that is not
yet documented in D-Bus spec (see [5] for more details).

[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://gitlab.freedesktop.org/dbus/dbus/-/blob/37b76d13738e782fe2eb12abdd0179745c0b3f81/dbus/dbus-address.c#L330
[4] opencontainers/runc#3356
[5] https://gitlab.freedesktop.org/dbus/dbus/-/merge_requests/248

Signed-off-by: Kir Kolyshkin <[email protected]>
kolyshkin added a commit to kolyshkin/dbus that referenced this pull request Feb 3, 2022
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).

More to say, if dbus sees a character that should have been escaped, it
returns an error [3].

Add EscapeBusAddressValue function (with some tests and a benchmark),
and use it from tryDiscoverDbusSessionBusAddress().

The function is exported as it might be of use to other packages (in
particular, runc [4]).

NOTE that the function does not escape '*' symbol, because de-facto it
is the list of optionally-escaped characters since 2007, but that is not
yet documented in D-Bus spec (see [5] for more details).

[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://gitlab.freedesktop.org/dbus/dbus/-/blob/37b76d13738e782fe2eb12abdd0179745c0b3f81/dbus/dbus-address.c#L330
[4] opencontainers/runc#3356
[5] https://gitlab.freedesktop.org/dbus/dbus/-/merge_requests/248

Signed-off-by: Kir Kolyshkin <[email protected]>
kolyshkin added a commit to kolyshkin/dbus that referenced this pull request Feb 8, 2022
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).

More to say, if dbus sees a character that should have been escaped, it
returns an error [3].

Add EscapeBusAddressValue function (with some tests and a benchmark),
and use it from tryDiscoverDbusSessionBusAddress().

Add UnescapeBusAddressValue, and use it from getKey().

The functions are exported as they might be of use to other packages
(in particular, runc [4]).

NOTE that the Escape... function does not escape '*' symbol, because
de-facto it is the list of optionally-escaped characters since 2007, but
that is not yet documented in D-Bus spec (see [5] for more details).

[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://gitlab.freedesktop.org/dbus/dbus/-/blob/37b76d13738e782fe2eb12abdd0179745c0b3f81/dbus/dbus-address.c#L330
[4] opencontainers/runc#3356
[5] https://gitlab.freedesktop.org/dbus/dbus/-/merge_requests/248

Signed-off-by: Kir Kolyshkin <[email protected]>
@kolyshkin kolyshkin force-pushed the user-dbus branch 2 times, most recently from 37a05b1 to d58070b Compare February 16, 2022 01:11
@kolyshkin
Copy link
Contributor Author

I have rebased this to benefit from godbus/dbus#302, so the patch is now much smaller. See #3356 (comment) as for why calling systemd --user show-environment does not make sense.

PTAL @AkihiroSuda 🙏🏻

AkihiroSuda
AkihiroSuda previously approved these changes Feb 16, 2022
@kolyshkin kolyshkin requested a review from thaJeztah February 16, 2022 22:43
liaohanqin pushed a commit to liaohanqin/dbus that referenced this pull request Feb 22, 2022
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).

More to say, if dbus sees a character that should have been escaped, it
returns an error [3].

Add EscapeBusAddressValue function (with some tests and a benchmark),
and use it from tryDiscoverDbusSessionBusAddress().

Add UnescapeBusAddressValue, and use it from getKey().

The functions are exported as they might be of use to other packages
(in particular, runc [4]).

NOTE that the Escape... function does not escape '*' symbol, because
de-facto it is the list of optionally-escaped characters since 2007, but
that is not yet documented in D-Bus spec (see [5] for more details).

[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://gitlab.freedesktop.org/dbus/dbus/-/blob/37b76d13738e782fe2eb12abdd0179745c0b3f81/dbus/dbus-address.c#L330
[4] opencontainers/runc#3356
[5] https://gitlab.freedesktop.org/dbus/dbus/-/merge_requests/248

Signed-off-by: Kir Kolyshkin <[email protected]>
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] godbus/dbus#302
[4] https://gitlab.freedesktop.org/dbus/dbus/-/blob/37b76d13738e782fe2eb12abdd0179745c0b3f81/dbus/dbus-address.c#L330

Signed-off-by: Kir Kolyshkin <[email protected]>
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=<user>@.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 <[email protected]>
@kolyshkin
Copy link
Contributor Author

Removed the dbus bump commit as it is now obsoleted by #3398.

@AkihiroSuda @thaJeztah PTAL

@kolyshkin kolyshkin requested a review from AkihiroSuda March 1, 2022 19:40
@kolyshkin
Copy link
Contributor Author

@thaJeztah @cyphar @mrunalp PTAL

Copy link
Member

@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@thaJeztah thaJeztah merged commit 51e607f into opencontainers:main Mar 9, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants