Skip to content

tons of fixes for terminal/password handling, with the goal of fixing #3853#8184

Merged
keszybz merged 23 commits intosystemd:masterfrom
poettering:color-ask-pw
Feb 15, 2018
Merged

tons of fixes for terminal/password handling, with the goal of fixing #3853#8184
keszybz merged 23 commits intosystemd:masterfrom
poettering:color-ask-pw

Conversation

@poettering
Copy link
Member

No description provided.

This modernizes acquire_terminal() in a couple of ways:

1. The three boolean arguments are replaced by a flags parameter, that
   should be more descriptive in what it does.

2. We now properly handle inotify queue overruns

3. We use _cleanup_ for closing the fds now, to shorten the code quite a
   bit.

Behaviour should not be altered by this.
…hed terminal features

Let's forget all relevant terminal features we learnt when we make a
console or /dev/null stdin/stdout/stderr.

Also, while we are at it, let's drop the various _unlikely_ and
_likely_ annotiations around the terminal feature caches. In many cases
we call the relevant functions only once in which cases the annotations
are likely to do just harm and no good. After all we can't know if the
specific code will call us just once or many times...
… not an int

We should be careful with these types, and if we do convert between
"int" and "ssize_t" we should do so explicitly rather than implicitly.
Otherwise this just looks like a bug.
We should rather sleep to much than too little. This otherwise might
result in a busy loop, because we slept too little and then recheck
again coming to the conclusion we need to go to sleep again, and so on.
We already have the terminal open, hence pass the fd we got to
ask_password_tty(), so that it doesn't have to reopen it a second time.

This is mostly an optimization, but it has the nice benefit of making us
independent from RLIMIT_NOFILE issues and so on, as we don't need to
allocate another fd needlessly.
The password prompt used to be highlighted, and that was a good thing.
Let's fix things to make the prompt highlighted again.

Fixes: systemd#3853
Also, make sure when we run in a container, we don't use the data from
/sys at all, but immediately fall back to /dev/console itself.
Let's normalize the behaviour: return a negative errno style error code,
and return the resolved string directly as argument.
A couple of fixes:

1. always bzero_explicit() away what we remove from the passphrase
   buffer. The UTF-8 code assumes the string remains NUL-terminated, and
   we hence should enforce that. memzero() would do too here, but let's
   be paranoid after all this is key material.

2. when clearing '*' characters from string, do so counting UTF-8
   codepoints properly. We already have code in place to count UTF-8
   codepoints when generating '*' characters, hence we should take the
   same care when clearing them again.

3. Treat NUL on input as an alternative terminator to newline or EOF.

4. When removing characters from the password always also reset the
   "codepoint" index properly.
Copy link
Member

@keszybz keszybz left a comment

Choose a reason for hiding this comment

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

I won't pretend to fully grok all the terminal handling stuff. Pfff. Looks okey from reading the code, but who knows.

I found some minor typos / wording issues. I think we can merge this as is, and fix those minor issues in a follow up commit.

* Note: strictly speaking this actually watches for the device being closed, it does *not* really watch
* whether a tty loses its controlling process. However, unless some rogue process uses TIOCNOTTY on /dev/tty
* *after* closing its tty otherwise this will not become a problem. As long as the administrator makes sure
* not configure any service on the same tty as an untrusted user this should not be a problem. (Which he
Copy link
Member

Choose a reason for hiding this comment

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

missing "to"

* whether a tty loses its controlling process. However, unless some rogue process uses TIOCNOTTY on /dev/tty
* *after* closing its tty otherwise this will not become a problem. As long as the administrator makes sure
* not configure any service on the same tty as an untrusted user this should not be a problem. (Which he
* probably should not do anyway.) */
Copy link
Member

Choose a reason for hiding this comment

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

s/he/they/ ?

if (ioctl(fd, TIOCSCTTY, force) < 0)
r = -errno;
r = ioctl(fd, TIOCSCTTY,
(flags & ~ACQUIRE_TERMINAL_PERMISSIVE) == ACQUIRE_TERMINAL_FORCE) < 0 ? -errno : 0;
Copy link
Member

Choose a reason for hiding this comment

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

This formatting is bad. Actually using a temporary variable for this would be nicer.

r = reset_terminal_fd(tty_fd, true);
if (r < 0)
log_warning_errno(r, "Failed to reset terminal, ignoring: %m");

Copy link
Member

Choose a reason for hiding this comment

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

Spurious newline.

bool colors_enabled(void) {

/* Returns true if colors are considered supported on our stdout. For that we check $SYSTEMD_COLORS first
* (which is the explicit way to turn off/on colors). If that didn't work we turn off colors unless we are on a
Copy link
Member

Choose a reason for hiding this comment

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

"... turn colors on/off ..."

*
* For that we first check if we explicitly got told to use colors or not, by checking $SYSTEMD_COLORS. If that
* didn't tell us anything we check whether PID 1 has $TERM set, and if not whether $TERM is set on the kernel
* command line. If we find $TERM set we assume color if it's not set to "dumb", similar to regular
Copy link
Member

Choose a reason for hiding this comment

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

"similarly to how regular ..."

assert(consoles);
assert(ret);

/* If we /sys is mounted read-only this means we are running in some kind of container environment. In that
Copy link
Member

Choose a reason for hiding this comment

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

"we"?


k = utf8_encoded_valid_unichar(str);
if (k < 0)
return (size_t) -1;
Copy link
Member

Choose a reason for hiding this comment

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

Make it ssize_t and return a proper -EINVAL?

return ((lead - 0xd800) << 10) + (trail - 0xdc00) + 0x10000;
}

size_t utf8_n_codepoints(const char *str);
Copy link
Member

Choose a reason for hiding this comment

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

No unit test?

if (ttyfd < 0)
return;

/* Backspaces back for enough characters to entirely undo printing of the specified string. */
Copy link
Member

Choose a reason for hiding this comment

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

I think the second "back" is redundant.

@keszybz keszybz merged commit 1496cea into systemd:master Feb 15, 2018
keszybz added a commit that referenced this pull request Feb 15, 2018
Trivial merge conflict resolved locally.
keszybz added a commit to keszybz/systemd that referenced this pull request Feb 16, 2018
Follow up for review of systemd#8184.
keszybz added a commit to keszybz/systemd that referenced this pull request Feb 19, 2018
Follow up for review of systemd#8184.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

2 participants