Skip to content

Avoid falling prey to tiocsti#1660

Open
hallyn wants to merge 1 commit into
shadow-maint:masterfrom
hallyn:shadow.tiocsti
Open

Avoid falling prey to tiocsti#1660
hallyn wants to merge 1 commit into
shadow-maint:masterfrom
hallyn:shadow.tiocsti

Conversation

@hallyn

@hallyn hallyn commented Jun 24, 2026

Copy link
Copy Markdown
Member

We've long known (see
https://www.halfdog.net/Security/2012/TtyPushbackPrivilegeEscalation/ and https://jdebp.uk/FGA/dont-abuse-su-for-dropping-privileges.html) that su should be used to gain but not drop privilege. Much more recently, linux added the ability to prevent TIOCSTI through a configurable /proc/sys/dev/tty/legacy_tiocsti setting.

If /proc/sys/dev/tty/legacy_tiocsti is set to 0, then we are protected from the callee injecting commands on caller's tty through TIOCSTI. If it's 1, or doesn't exist, then we are not. That can be dangerous if caller is root. We currently give up the controlling terminal for non-interactive uses of su (-c). Let's do that for interactive calls as well, only in the dangerous case.

@hallyn hallyn requested a review from alejandro-colomar June 24, 2026 14:31
Comment thread src/su.c Outdated
Comment thread src/su.c Outdated
Comment thread src/su.c Outdated
We've long known (see
https://www.halfdog.net/Security/2012/TtyPushbackPrivilegeEscalation/
and https://jdebp.uk/FGA/dont-abuse-su-for-dropping-privileges.html)
that su should be used to gain but not drop privilege.  Much more
recently, linux added the ability to prevent TIOCSTI through a
configurable /proc/sys/dev/tty/legacy_tiocsti setting.

If /proc/sys/dev/tty/legacy_tiocsti is set to 0, then we are protected
from the callee injecting commands on caller's tty through TIOCSTI.
If it's 1, or doesn't exist, then we are not.  That can be dangerous
if caller is root.  We currently give up the controlling terminal
for non-interactive uses of su (-c).  Let's do that for interactive
calls as well, only in the dangerous case.
Comment thread src/su.c
Comment on lines +1000 to +1006
/*
* See the following kernel commit:
* commit 83efeeeb3d04b22aaed1df99bc70a48fe9d22c4d
* Author: Kees Cook <kees@kernel.org>
* Date: Sat Oct 22 11:29:49 2022 -0700
* Subject: tty: Allow TIOCSTI to be disabled
*/

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

How about compacting that?:

// See kernel.git 83efeeeb3d04 (2022-10-22; "tty: Allow TIOCSTI to be disabled")

Comment thread src/su.c
* Date: Sat Oct 22 11:29:49 2022 -0700
* Subject: tty: Allow TIOCSTI to be disabled
*/
static bool legacy_tiocsti_is_disabled(void) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Please move the brace to a new line (and optionally the type, but at least the brace).

Comment thread src/su.c
if (ret == NULL)
return false;

return buf[0] == '0';

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I'd like to avoid all direct operations on bytes of strings. The good thing about str*() functions is that you can fortify them with _FORTIFY_SOURCE, and other niceties. They're also easier to grep(1).

I suggest using one of the following alternatives:

return streq(buf, "0\n");

return !!strspn(buf, "0");

@alejandro-colomar alejandro-colomar Jun 28, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I prefer the former, because it also implicitly validates the rest of the string.

Maybe it would be interesting to validate and remove the newline explicitly separately:

if (stpspn(buf, "\n") == NULL)
	return false;

return streq(buf, "0");

This makes the streq() call more readable.

Comment thread src/su.c
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants