core: do not chown fd-passed TTYs
When stdio is passed as file descriptors, the provider of those descriptors remains responsible for their ownership and access mode. This keeps run0 in a pipeline from changing the caller's TTY ownership to the target user, which can otherwise break later terminal access from the original user. Fixes #43336
This commit is contained in:
committed by
Yu Watanabe
parent
e8454eb14c
commit
e98c68104b
@@ -5722,7 +5722,12 @@ int exec_invoke(
|
||||
}
|
||||
#endif
|
||||
|
||||
if (uid_is_valid(uid)) {
|
||||
/* Only adjust ownership for TTYs we acquired via StandardInput=tty*. If stdin is passed
|
||||
* as an fd, its ownership is managed by the provider of the fd, see exec_context_revert_tty(). */
|
||||
if (uid_is_valid(uid) &&
|
||||
params->stdin_fd < 0 &&
|
||||
exec_input_is_terminal(context->std_input) &&
|
||||
exec_context_tty_path(context)) {
|
||||
r = chown_terminal(STDIN_FILENO, uid);
|
||||
if (r < 0) {
|
||||
*exit_status = EXIT_STDIN;
|
||||
|
||||
@@ -339,6 +339,26 @@ if [[ -e /usr/lib/pam.d/systemd-run0 ]] || [[ -e /etc/pam.d/systemd-run0 ]]; the
|
||||
assert_eq "$(run0 --pipe echo -n foo)" "foo"
|
||||
assert_eq "$(run0 --pipe --pty echo -n foo)" "foo"
|
||||
|
||||
# When run0 is used in a pipeline, the caller's TTY is passed through as an fd. Its
|
||||
# ownership/access mode must not be changed to the target user.
|
||||
script -qec 'bash -euxc '"'"'
|
||||
set -o pipefail
|
||||
tty_path="$(tty)"
|
||||
tty_stat="$(stat -Lc "%u:%g:%a" "$tty_path")"
|
||||
run0 --user=testuser echo -n foo | cat >/dev/null
|
||||
[[ "$(stat -Lc "%u:%g:%a" "$tty_path")" == "$tty_stat" ]]
|
||||
'"'" /dev/null
|
||||
|
||||
# --pty also passes a service PTY as an fd. It must still provide a usable TTY to
|
||||
# the target user without changing the caller's TTY ownership/access mode.
|
||||
script -qec 'bash -euxc '"'"'
|
||||
tty_path="$(tty)"
|
||||
tty_stat="$(stat -Lc "%u:%g:%a" "$tty_path")"
|
||||
run0 --pty --user=testuser bash -xec \
|
||||
"test \"\$(id -un)\" = testuser; test -t 0; test -t 1; test -t 2; tty >/dev/null"
|
||||
[[ "$(stat -Lc "%u:%g:%a" "$tty_path")" == "$tty_stat" ]]
|
||||
'"'" /dev/null
|
||||
|
||||
# Validate when we invoke run0 without a tty, that depending on --pty it either allocates a tty or not
|
||||
assert_neq "$(run0 --pty tty < /dev/null)" "not a tty"
|
||||
assert_eq "$(run0 --pipe tty < /dev/null)" "not a tty"
|
||||
|
||||
Reference in New Issue
Block a user