Merge pull request #12057 from poettering/chown-tty

chown TTY back to root:tty after a service terminates that used them
This commit is contained in:
Zbigniew Jędrzejewski-Szmek
2019-03-21 17:31:19 +01:00
committed by GitHub
4 changed files with 41 additions and 27 deletions

17
TODO
View File

@@ -78,8 +78,6 @@ Features:
* maybe implicitly attach monotonic+realtime timestamps to outgoing messages in
log.c and sd-journal-send
* chown() tty a service is attached to after the service goes down
* optionally: turn on cgroup delegation for per-session scope units
* introduce per-unit (i.e. per-slice, per-service) journal log size limits.
@@ -258,8 +256,6 @@ Features:
* support projid-based quota in machinectl for containers
* Add NetworkNamespacePath= to specify a path to a network namespace
* maybe use SOURCE_DATE_EPOCH (i.e. the env var the reproducible builds folks
introduced) as the RTC epoch, instead of the mtime of NEWS.
@@ -439,8 +435,6 @@ Features:
* optionally, also require WATCHDOG=1 notifications during service start-up and shutdown
* resolved: when routing queries, make sure only look for the *longest* suffix...
* delay activation of logind until somebody logs in, or when /dev/tty0 pulls it
in or lingering is on (so that containers don't bother with it until PAM is used). also exit-on-idle
@@ -585,12 +579,6 @@ Features:
service instances processing the listening socket, and open this up
for ReusePort=
* socket units: support creating sockets in different namespace,
opening it up for JoinsNamespaceOf=. This would require to fork off
a tiny process that joins the namespace and creates/binds the socket
and passes this back to PID1 via SCM_RIGHTS. This also could be used
to allow Chown/chgrp on sockets without requiring NSS in PID 1.
* introduce bus call FreezeUnit(s, b), as well as "systemctl freeze
$UNIT" and "systemctl thaw $UNIT" as wrappers around this. The calls
should SIGSTOP all unit processes in a loop until all processes of
@@ -631,9 +619,6 @@ Features:
* load .d/*.conf dropins for device units
* allow implementation of InaccessibleDirectories=/ plus
ReadOnlyDirectories=... for whitelisting files for a service.
* sd-bus:
- EBADSLT handling
- GetAllProperties() on a non-existing object does not result in a failure currently
@@ -736,8 +721,6 @@ Features:
- follow PropertiesChanged state more closely, to deal with quick logouts and
relogins
* exec: when deinitializating a tty device fix the perms and group, too, not only when initializing. Set access mode/gid to 0620/tty.
* journal:
- consider introducing implicit _TTY= + _PPID= + _EUID= + _EGID= + _FSUID= + _FSGID= fields
- import and delete pstore filesystem content at startup

View File

@@ -4157,17 +4157,23 @@ static bool tty_may_match_dev_console(const char *tty) {
return true; /* if we could not resolve, assume it may */
/* "tty0" means the active VC, so it may be the same sometimes */
return streq(resolved, tty) || (streq(resolved, "tty0") && tty_is_vc(tty));
return path_equal(resolved, tty) || (streq(resolved, "tty0") && tty_is_vc(tty));
}
bool exec_context_may_touch_console(const ExecContext *ec) {
static bool exec_context_may_touch_tty(const ExecContext *ec) {
assert(ec);
return (ec->tty_reset ||
return ec->tty_reset ||
ec->tty_vhangup ||
ec->tty_vt_disallocate ||
is_terminal_input(ec->std_input) ||
is_terminal_output(ec->std_output) ||
is_terminal_output(ec->std_error)) &&
is_terminal_output(ec->std_error);
}
bool exec_context_may_touch_console(const ExecContext *ec) {
return exec_context_may_touch_tty(ec) &&
tty_may_match_dev_console(exec_context_tty_path(ec));
}
@@ -4634,6 +4640,30 @@ void exec_context_free_log_extra_fields(ExecContext *c) {
c->n_log_extra_fields = 0;
}
void exec_context_revert_tty(ExecContext *c) {
int r;
assert(c);
/* First, reset the TTY (possibly kicking everybody else from the TTY) */
exec_context_tty_reset(c, NULL);
/* And then undo what chown_terminal() did earlier. Note that we only do this if we have a path
* configured. If the TTY was passed to us as file descriptor we assume the TTY is opened and managed
* by whoever passed it to us and thus knows better when and how to chmod()/chown() it back. */
if (exec_context_may_touch_tty(c)) {
const char *path;
path = exec_context_tty_path(c);
if (path) {
r = chmod_and_chown(path, TTY_MODE, 0, TTY_GID);
if (r < 0 && r != -ENOENT)
log_warning_errno(r, "Failed to reset TTY ownership/access mode of %s, ignoring: %m", path);
}
}
}
void exec_status_start(ExecStatus *s, pid_t pid) {
assert(s);
@@ -4658,12 +4688,8 @@ void exec_status_exit(ExecStatus *s, const ExecContext *context, pid_t pid, int
s->code = code;
s->status = status;
if (context) {
if (context->utmp_id)
(void) utmp_put_dead_process(context->utmp_id, pid, code, status);
exec_context_tty_reset(context, NULL);
}
if (context && context->utmp_id)
(void) utmp_put_dead_process(context->utmp_id, pid, code, status);
}
void exec_status_reset(ExecStatus *s) {

View File

@@ -374,6 +374,8 @@ int exec_context_get_effective_ioprio(const ExecContext *c);
void exec_context_free_log_extra_fields(ExecContext *c);
void exec_context_revert_tty(ExecContext *c);
void exec_status_start(ExecStatus *s, pid_t pid);
void exec_status_exit(ExecStatus *s, const ExecContext *context, pid_t pid, int code, int status);
void exec_status_dump(const ExecStatus *s, FILE *f, const char *prefix);

View File

@@ -1754,6 +1754,9 @@ static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart)
if (s->pid_file)
(void) unlink(s->pid_file);
/* Reset TTY ownership if necessary */
exec_context_revert_tty(&s->exec_context);
return;
fail: