Commit Graph
375 Commits
Author SHA1 Message Date
Zbigniew Jędrzejewski-Szmek c83ff0e58d user-util: return malloc'ed strings in get_user_creds
get_user_creds would use getpwnam() and then returns strings pointing
into the static buffer. This seems very iffy. Let's duplicate the
strings properly
2026-05-21 18:02:05 +02:00
Zbigniew Jędrzejewski-Szmek 3ecd6b69cf user-util: stop mangling groupname in get_group_creds
The param was input/output, which is unexpected and confusing and
actually made most callers much more complicated than they needed to be.
The function was playing fast and loose with the return value. In some
cases it was returning a static string, which would be completely fine.
But in other case it was returning a pointer into the getgrgid static
buffer, i.e. that return value could be overwritten. AFAICT, this didn't
matter in any of the callers, but we shouldn't do that anyway.

So use a separate output param with an allocated string that the caller
is responsible for.

It turns out that all callers pass NULL (outside of tests) and zero for
flags. So the function _could_ be simplified. But get_user_creds is
called with all the params actually used, and I think having the the
functions so different wouldn't be nice. I first wrote a commit to
drop the unused params, but then I discarded it.

The error message in exec-invoke.c is fixed.
2026-05-21 18:02:05 +02:00
Diego Viola 5d17215c7e treewide: fix typos in the entire codebase
Signed-off-by: Diego Viola <diego.viola@gmail.com>
2026-05-05 17:22:26 +02:00
Zbigniew Jędrzejewski-Szmek f7434671bd shared/help-util: automatically append ":" in sections 2026-05-05 11:14:33 +02:00
Lennart Poettering 99ce7a0770 options: get rid of "on_error" parameter to FOREACH_OPTION
I am really not a fan of full code lines passed to macros as parameters.
Let's get rid of the 3rd parameter of FOREACH_OPTION() hence:

1. Let's return errors just as a regular value (though a negative one),
   that can be handled via a OPTION_ERROR case statement for the switch.
   This normalizes handling of the error, just like any other event
   returned by the option parser.

2. In order to avoid exploding the amount of boilerplate in each use
   (that just propagates the error on OPTION_ERROR), let's then
   introduce an explicit FOREACH_OPTION_OR_RETURN(), that returns from
   the calling function on its own (and makes that clear in the name).

Together this cleans up, normalizes the logic and shortens the code.
2026-04-30 11:12:33 +01:00
Daan De Meyer 9d2f5b4611 fundamental/cleanup: add CLEANUP_ELEMENTS() and DEFINE_POINTER_ARRAY_CLEAR_FUNC()
DEFINE_POINTER_ARRAY_CLEAR_FUNC() generates a helper of the form
helper_array_clear(T *array, size_t n) that drops each element but does
not free the array itself, parallel to DEFINE_POINTER_ARRAY_FREE_FUNC()
for cases where the array has automatic storage duration.

CLEANUP_ELEMENTS() pairs with these helpers to provide a _cleanup_-like
attribute for fixed-size arrays: the bound is taken from ELEMENTSOF(),
and the helper is invoked across the elements at scope exit. Compared to
CLEANUP_ARRAY(), the storage is neither freed nor zeroed.

Migrate various logic across the tree over to the new macros.

sd-device: use DEFINE_POINTER_ARRAY_CLEAR_FUNC() for sd_device_unref_array_clear()

Replace the local device_unref_many() helper with the macro-generated
equivalent.

format-table: switch help-table arrays to CLEANUP_ELEMENTS()

Generate table_unref_array_clear() via DEFINE_POINTER_ARRAY_CLEAR_FUNC()
and convert the help-table arrays in bootctl, cryptenroll, nspawn,
repart and vmspawn to CLEANUP_ELEMENTS(). The arrays no longer need a
trailing NULL slot, so the size matches ELEMENTSOF() of the groups
array.

firewall-util: switch netlink message arrays to CLEANUP_ELEMENTS()

Generate sd_netlink_message_unref_array_clear() via
DEFINE_POINTER_ARRAY_CLEAR_FUNC() in place of the NULL-terminated
sd_netlink_message_unref_many(), and convert the two stack arrays of
sd_netlink_message pointers to CLEANUP_ELEMENTS().
2026-04-30 09:15:34 +02:00
Zbigniew Jędrzejewski-Szmek fb0143f1ce shared/options: add option_parser_get_help_table_ns() helper
It'll be used in the next commit.
2026-04-29 14:00:41 +02:00
Zbigniew Jędrzejewski-Szmek 0a85be9ccf run: use a "named namespace" also for the main option parser
It seems that clang reorders the entries in the options array that
originate from different functions, but not within a function. Using
"named namespaces" exclusively should sidestep the issue.

(A bigger hammer would be to sort the array. We *can* do this, since the
options have the increasing .id field. But that'd require duplicating
the memory or making it writable. Let's avoid this until we know for
sure that it's needed.)
2026-04-28 17:13:24 +02:00
Zbigniew Jędrzejewski-Szmek 03a58fe251 run: convert run0 option parser to macros
This exercises the new option namespace code.

--help output is generally the same, except for the formatting changes
related to use of the new output helpers and the common option macros.

--same-root-dir is now documented (followup for
  475729b805).

Co-developed-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-28 17:13:24 +02:00
Zbigniew Jędrzejewski-Szmek 4c0e12b3b9 run: convert parse_argv() to OPTION macros
--system is now documented (fixup for 66b1e74605).
--capsule is now documented (fixup for 759b3c082d).

--help output is generally the same, except for the formatting changes
related to use of the new output helpers and common option macros.

Co-developed-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-28 17:13:24 +02:00
Zbigniew Jędrzejewski-Szmek ff902c7ccd run: reorder switch cases to match help() output order
Both parse_argv() and parse_argv_sudo_mode() handled options in an
order that no longer matched the help text. Reorder the case statements
so the source order mirrors what the user sees in --help.

In parse_argv_sudo_mode(), drop the case 'i' → ARG_VIA_SHELL fall-through
so the cases can be sequenced independently; 'i' now sets arg_via_shell
directly.

Co-developed-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-28 17:13:24 +02:00
Arnout Engelen 086707ba79 run: allow setting output format
This is useful when moving from `--pty` or `--pipe` to using
`--verbose`: you can use `--verbose-output=cat` to get similar output on
stdout while still having all of the advantages of `--verbose` over the
other options.
2026-04-13 13:38:04 +02:00
Zbigniew Jędrzejewski-Szmek 0ce5a8fb4e tree-wide: drop flush&check step after table printing
Almost all callers of table_print() specify stdout or NULL (equivalent
to stdout) as the output stream. Simplify things by not requiring the
the stream to be specified.

In almost all cases, the printing of the table is surrounded by normal
printfs() that don't do explicit flushing and for which we don't check
the output stream status. Let's simplify most callers and skip this
step. The reason is not so much to avoid the extra step itself, but
instead to avoid the _handling_ of the potential failure. We generally
only want to print an error message for ENOMEM and other "internal"
errors, so strictly speaking we should filter out the errors from the
stream. By skipping the flush&check step we implicitly do this.
2026-04-03 13:04:40 +02:00
Mike Yuan 577e5e9a5e parse-argument: make parse_tristate_argument() do something useful
I expressed the issue I have with parse_tristate_argument()
in #37751: it doesn't add any value to direct use of parse_tristate();
on the contrary, it doesn't support means to reset the arg to "auto"/-1 state.
The mere reason it existed is that we need a int type ret param.

Since the previous attempt to address this mess failed, let's
try to make the function more useful by making it accept "auto".
I figure this is useful on its own.

As requested in
https://github.com/systemd/systemd/pull/40652#discussion_r2831833996,
the function name is suffixed with _with_auto() to establish
that "auto" is handled internally.
2026-02-20 21:20:45 +01:00
Lennart Poettering fe1f8c1acd run: support RootMStack= on the client side for systemd-run 2026-02-19 15:05:15 +01:00
Daan De Meyer 4d388536ee tree-wide: Allow running capsules as any user
For many use cases DynamicUser= just doesn't cut it. Specifically lots
of stuff wants to run as root. Let's support this use case by relaxing
our checks for capsules a bit.
2026-02-03 15:00:32 +01:00
Mike Yuan 0f22a0918d run: remove unused enum values for getopt_long() 2026-01-24 13:18:00 +01:00
Yu Watanabe 93378148d4 tree-wide: normalize comment style 2025-12-15 08:50:13 +09:00
Yu Watanabe 7875d9a4f6 run0: two follow-ups (#39900) 2025-11-26 16:24:42 +09:00
Daan De Meyer 9a6a8f35eb tree-wide: Small fixes for various clang-tidy warnings 2025-11-26 16:22:00 +09:00
Mike Yuan 2ef2002a96 run: merge privileged_execution() into become_root()
This got split in 5cabeed80b
to accommodate --empower, and later --empower received
dedicated handling again (c36942916b).
I think the new naming makes more sense - --empower is privileged
after all, just with uid left unchanged. Hence merge
privileged_execution back into it.
2025-11-26 01:10:55 +00:00
Mike Yuan 2207b7f9a4 run0: swap the order of setting default wd and user
Follow-up for 4f6ef13f43

Special casing --area= rather than --empower makes the code
self-explanatory, as --area= is about alternative home dir
after all. On top of that this ensures when --area= and
--empower are specified in combination we honor the home dir
switch, too.
2025-11-26 01:10:55 +00:00
Daan De Meyer 2ba910ab06 run: Don't make executable absolute when --root-directory= is used
Also, unless --same-root-dir was specified, don't make the executable
absolute if we're running in a chroot. Situations like this are still iffy,
but we might as well handle them a little more gracefully.
2025-11-26 00:37:17 +01:00
Daan De Meyer c36942916b run0: Give --empower its own color, title and emoji
When in --empower mode, all created files will be owned by the current
user, which could be problematic when creating files outside of the
current user's home directory, as other processes running as the same
user would be able to edit those files.

While this is a bit of an edge case since users already have to go through
the effort of writing --empower to indicate they want a privileged session
as the current user, it's not unphatomable to think they could start an
empowered session which they later return to and continue using. Currently,
it's not easy to differentiate a regular run0 session and an empowered session
at a glance, so users might think they're using a regular run0 session when
they're actually using an empowered session.

To address this problem, let's give empowered session their own identify, by
making the background orange, using the pumpkin emoji as the shell prompt
prefix and giving them an orange circle as the PTY title.
2025-11-25 17:15:30 +01:00
Antonio Alvarez Feijoo 7599d26436 run: fix two minor memory leaks
```
==19541== 8 bytes in 1 blocks are still reachable in loss record 1 of 3
==19541==    at 0x4841744: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==19541==    by 0x50125C9: strdup (strdup.c:42)
==19541==    by 0x4C55925: getusername_malloc (user-util.c:154)
==19541==    by 0x1121D6: parse_argv_sudo_mode (run.c:1098)
==19541==    by 0x123B13: run (run.c:3032)
==19541==    by 0x124198: main (run.c:3100)
==19541==
==19541== 11 bytes in 1 blocks are still reachable in loss record 2 of 3
==19541==    at 0x4841744: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==19541==    by 0x50125C9: strdup (strdup.c:42)
==19541==    by 0x112A9C: parse_argv_sudo_mode (run.c:1182)
==19541==    by 0x123B13: run (run.c:3032)
==19541==    by 0x124198: main (run.c:3100)
```
2025-11-24 16:03:34 +00:00
Daan De Meyer 4f6ef13f43 run0: Stay in cwd if --empower is specified without a user
If we run "run0 --empower", the expectation is to stay in the
current working directory, not switch to ~.
2025-11-24 14:39:34 +01:00
Zbigniew Jędrzejewski-Szmek d92e47a093 run: improve log message for unknown user/group
Before:
$ sudo build/systemd-run --scope --uid=asdf whoami
Failed to resolve user asdf: No such process
Now:
$ sudo build/systemd-run --scope --uid=asdf whoami
Failed to resolve user 'asdf': Unknown user
2025-11-18 16:23:29 +01:00
Daan De Meyer 475729b805 run0: Make --same-root-dir available for run0
This enables running something like
"mkosi box -- run0 --empower --same-root-dir -E PATH" to get an
empowered session as the current user within the "mkosi box" environment.
2025-11-14 10:36:53 +01:00
Mike Yuan 045b8d761e run: refuse --root-directory= in --scope mode
As discussed in #39669, let's reject this for now.
2025-11-13 21:17:32 +01:00
Daan De Meyer 3150c34270 run0: Never ask --empower sessions for polkit auth
A --empower session is effectively root without being UID 0, so it
doesn't make sense to enforce polkit authentication in those. Let's
add the empower group, add --empower sessions to that group and ship
a polkit rule to skip authentication for all users in the empower
group.

(As a side-effect this will also allow users to add themselves to this
group outside of 'run0 --empower' to mimick NOPASSWD from sudo)
2025-11-12 19:55:35 +01:00
Mike Yuan 9876309cfe run: make sure we send out READY=1 when --wait
Let's skip bus_wait_for_jobs_one() when --wait as well,
as it surpasses the start job and allows for
run_context_check_started() to fire.
2025-11-09 22:39:42 +01:00
Daan De Meyer 9e26ced980 core: Add RootDirectoryFileDescriptor=
RootDirectory= but via a open_tree() file descriptor. This allows
setting up the execution environment for a service by the client in
a mount namespace and then starting a transient unit in that execution
environment using the new property.

We also add --root-directory= and --same-root-dir= to systemd-run to
have it run services within the given root directory. As systemd-run
might be invoked from a different mount namespace than what systemd is
running in, systemd-run opens the given path with open_tree() and then
sends it to systemd using the new RootDirectoryFileDescriptor= property.
2025-10-31 13:09:51 +01:00
Daan De Meyer 5cabeed80b run0: Add --empower
--empower gives full privileges to a non-root user. Currently this
includes all capabilities but we leave the option open to add more
privileges via this option in the future.

Why is this useful? When running privileged development or debugging
commands from your home directory (think bpftrace, strace and such),
you want any files written by these tools to be owned by your current
user, and not by the root user. run0 --empower will allow you to run
all privileged operations (assuming the tools check for capabilities
and not UIDs), while any files written by the tools will still be owned
by the current user.
2025-10-30 15:28:36 +01:00
Daniel Hast 101dd41cb4 tree-wide: add basic validation of --background argument
Check whether the argument of the `--background` option of
`systemd-run`, `run0`, `systemd-nspawn`, `systemd-vmspawn`, and
`systemd-pty-forward` is either empty or looks like an ANSI color code,
and reject invalid values when parsing arguments.

We consider a string to look like an ANSI color code if it consists of
one or more sequences of ASCII digits separated by semicolons. This
permits every valid ANSI color code, and should reject anything that
results in garbled output.
2025-10-25 09:56:31 +09:00
Daan De Meyer 9c3359f28a ptyfwd: Always prioritize $SYSTEMD_TINT_BACKGROUND
By giving priority to --background= we prevent users from opting
out of coloring if an explicit color is chosen by a tool wrapping
one of our own tools. Instead, let's give priority to the environment
variable, so that even if our tools are wrapped by another tool with
a different background, users can still opt out of coloring just by
setting the environment variable, which has a high chance of being
forwarded to the invocation of our own tools which makes it easy to
use to disable color tinting globally if requested by the user.
2025-10-20 12:20:35 +02:00
Yu Watanabe e66b233e83 run: include sys/stat.h again
This partially reverts 9adb4685df.

For the case that sys/stat.h is not included indirectly by other headers.
Fixes the following error:
```
../src/run/run.c: In function 'fchown_to_capsule':
../src/run/run.c:2128:21: error: storage size of 'st' isn't known
 2128 |         struct stat st;
      |                     ^~
```
2025-09-19 22:56:49 +02:00
Daan De Meyer 9adb4685df tree-wide: Remove unused includes 2025-09-19 14:46:55 +02:00
Yu Watanabe b749f77ad0 run: make PTY forwarder honor vhangup() after service finished
Like we already do in machinectl.
2025-07-30 01:15:29 +09:00
Yu Watanabe dce66b0688 ptyfwd,run: make pty_forward_drain() trigger defer event to call shovel()
drained() checks PTYForward.master_readable flag, but it may be
tentatively unset due to a tentative error like EAGAIN in the previous
IO event. Let's try to call shovel() one more time, which re-read the
master and call drained() at the end. Otherwise, we may lost some data.
2025-07-30 01:15:29 +09:00
DaanDeMeyer e4691ebb49 fork-journal: Generalize to fork-notify
Most of the logic isn't journalctl specific, let's generalize a bit
so we can reuse this for other commands as well.
2025-07-14 15:07:48 +02:00
Zbigniew Jędrzejewski-Szmek 63770fa1d3 systemd-run: add --no-pager, use pager for --help 2025-07-11 19:01:42 +09:00
Yu Watanabe 83a047fe23 tree-wide: include sys/stat.h where necessary
These source files uses symbols provided by sys/stat.h, e.g. struct stat,
S_IFREG, S_IFBLK, and so on. Let's explicitly include sys/stat.h where
necessary.

Glibc's fcntl.h includes bits/stat.h, which provides these symbols, so
these symbols can be used without explicitly including sys/stat.h. But,
based on the discussion in #37922, we should explicitly include relevant
headers, and should not rely on the indirect inclusion.

Similar to 4f18ff2e29, but for sys/stat.h.
2025-07-07 12:44:10 +09:00
Yu Watanabe 4f18ff2e29 tree-wide: include unistd.h where necessary
We use symbols provided by unistd.h without including it. E.g.
open(), close(), read(), write(), access(), symlink(), unlink(), rmdir(),
fsync(), syncfs(), lseek(), ftruncate(), fchown(), dup2(), pipe2(),
getuid(), getgid(), gettid(), getppid(), pipe2(), execv(), _exit(),
environ, STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO, F_OK, and their
friends and variants, so on.

Currently, unistd.h is indirectly included mainly in the following two paths:
- through missing_syscall.h, which is planned to covert to .c file.
- through signal.h -> bits/sigstksz.h, which is new since glibc-2.34.
  Note, signal.h is included by sd-eevent.h. So, many source files
  indirectly include unistd.h if newer glibc is used.

Currently, our baseline on glibc is 2.31. We need to support glibc older
than 2.34, but unfortunately, we do not have any CI environments with
such old glibc. CIFuzz uses glibc-2.31, but it builds only fuzzers, and
many files are even not compiled.
2025-06-30 09:19:15 +02:00
Zbigniew Jędrzejewski-Szmek 7d247d3cb8 meson: drop explicit custom_target names
[1] says:
> Since 0.60.0 the name argument is optional and defaults to the basename of
> the first output
We specify >= 0.62 as the supported version, so drop the duplicate name in all cases
where it is the same as outputs[0], i.e. almost all cases.

[1] https://mesonbuild.com/Reference-manual_functions.html#custom_target
2025-06-28 17:14:50 +02:00
Yu Watanabe 31a1e15ccb sd-bus: coding style cleanups
- replace `type *func()` -> `type* func()`,
- rename arguments for storing results,
- add several missing assertions.
2025-06-18 01:54:07 +09:00
Mike Yuan a59cc3860b tree-wide: check --machine= specification
Addresses https://github.com/systemd/systemd/pull/37741#discussion_r2128482378
2025-06-17 02:10:37 +02:00
Yu Watanabe eb09b4b546 run: ignore bus connection error in acquiring invocation ID
Similar to 2b983b43c6, but for acquiring
invocation ID.

Fixes #37675.
2025-06-07 00:01:15 +09:00
Yu Watanabe ac004f4cc9 tree-wide: introduce bus_error_is_connection() and use it where applicable 2025-06-06 21:42:25 +09:00
Lennart Poettering 994a42a096 run: chop off username from --machine= argument before calling OpenMachinePTY()
Let's be compatible with sd-bus' logic to talk to machine, and support
the usual user@host syntax. We only want the host part, hence chop if
off before passing it to OpenMachinePTY().

Fixes: #32997
2025-06-05 12:45:37 +02:00
Yu Watanabe 23f9ff4724 ptyfwd: introduce pty_forward_set_window_title() helper function 2025-06-05 19:06:02 +09:00