`cockpit-ws` has never protected hostnames from being interpreted as cli
options when passing them to the auth commands (`cockpit-session`,
`cockpit-ssh`, `cockpit.beiboot`). There have been a couple of relevant
changes over the years:
- our move to using cockpit-session via unix socket has removed
exposure to this problem for `cockpit-session`
- our move from `cockpit-ssh` (glib argument parser) to
`cockpit.beiboot` (Python argparse) has unfortunately exposed us to
https://github.com/python/cpython/issues/66623 which means (due to a
strange heuristic) that arguments starting with '-' can be
interpreted as positionals if they also have spaces in them
This gives a way to get a hostname starting with a `-` to ssh (where it
*will* be interpreted as an option) and the following argument (the
python invocation on the remote) will be interpreted as the hostname.
Fortunately, new versions of ssh will reject this hostname. In any
case, we should firm up the code here and add `--` to ensure that it's
definitely interpreted as a hostname by ssh.
For a similar reason add a `--` to the ssh command in `cockpit-ws`.
CVE-2026-4631
All of the talk of sudo-rs, sudo, run0 and the like led to an
interesting conclusion: we've had the ability to start transient
root-owned units with polkit authentication with fd passing as a core
systemd feature since about a decade.
Since we use systemd for everything else, why not this?
Add a new "method" field to the superuser bridge which can be
"StartTransientUnit" or "spawn" and defaults to "spawn". If this is set
to "StartTransientUnit" then we'll use that method to start the given
command as root via the StartTransientUnit D-Bus call on pid1.
Add also a new "polkit" boolean field for if we should start a polkit
agent or not. We used to do that automatically if "pkexec" appeared in
the argument vector so use that as a default value for backwards
compatibility.
Add StartTransientUnit to the default methods defined by the shell (and
beoboot) in the order below sudo but above pkexec. This means that on
systems without a working sudo (such as Ubuntu 25.10) we will choose
StartTransientUnit.
The eventual goal will be to make it the default method but let's try
this as a first step.
This will help us in our beautiful post-setuid future.
Closes#21723Closes#22669https://github.com/cockpit-project/cockpit/pull/22373
We didn't sync this in a while and there have been a lot of changes.
We also have a critical bug fix included: we recently introduced a test
case (in 0bb7438820) which triggers a
segfault in the binding layer of systemd_ctypes due to FFI call
trampolines being garbage collected while they're still running.
This is currently blocking downstream packaging on several non-x86_64
architectures.
This has some breaking API changes, so make adjustments as necessary.
One slightly non-obvious change comes from the removal of
InteractionAgent.add_handlers(), which had the potential to be racy in
case a message arrived before its handler was registered. We now have
to specify all handlers up-front, which means that the block for doing
that needs to move up to before the transport is connected. Of course,
we can only write the stage1 bootloader after the transport is online,
so we need to keep that in its current location.