git: f099c6b3a423 - stable/14 - kern: tty: refactor TIOCSTI privilege checks slightly
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 21 Jul 2025 02:13:45 UTC
The branch stable/14 has been updated by kevans:
URL: https://cgit.FreeBSD.org/src/commit/?id=f099c6b3a423a78c1367a11fd987457ae592924f
commit f099c6b3a423a78c1367a11fd987457ae592924f
Author: Kyle Evans <kevans@FreeBSD.org>
AuthorDate: 2025-05-28 01:19:17 +0000
Commit: Kyle Evans <kevans@FreeBSD.org>
CommitDate: 2025-07-21 02:12:25 +0000
kern: tty: refactor TIOCSTI privilege checks slightly
This removes some repetition from it and makes the flow a little more
obvious. Future work may find some way to add more constraints to the
unprivileged path, add a security sysctl to disable it, or perhaps
some combination of the two.
Reviewed by: kib, markj
(cherry picked from commit 59fc4cda1bfa712c46d407d1e83bdd5c63e6e0e3)
---
sys/kern/tty.c | 26 +++++++++++++++++++++-----
1 file changed, 21 insertions(+), 5 deletions(-)
diff --git a/sys/kern/tty.c b/sys/kern/tty.c
index b1b3b268d0e9..47f9f25cec37 100644
--- a/sys/kern/tty.c
+++ b/sys/kern/tty.c
@@ -1643,6 +1643,24 @@ tty_set_winsize(struct tty *tp, const struct winsize *wsz)
tty_signal_pgrp(tp, SIGWINCH);
}
+static int
+tty_sti_check(struct tty *tp, int fflag, struct thread *td)
+{
+ /* Root can bypass all of our constraints. */
+ if (priv_check(td, PRIV_TTY_STI) == 0)
+ return (0);
+
+ /* Unprivileged users must have it opened for read. */
+ if ((fflag & FREAD) == 0)
+ return (EPERM);
+
+ /* It must also be their controlling tty. */
+ if (!tty_is_ctty(tp, td->td_proc))
+ return (EACCES);
+
+ return (0);
+}
+
static int
tty_generic_ioctl(struct tty *tp, u_long cmd, void *data, int fflag,
struct thread *td)
@@ -1988,11 +2006,9 @@ tty_generic_ioctl(struct tty *tp, u_long cmd, void *data, int fflag,
tty_info(tp);
return (0);
case TIOCSTI:
- if ((fflag & FREAD) == 0 && priv_check(td, PRIV_TTY_STI))
- return (EPERM);
- if (!tty_is_ctty(tp, td->td_proc) &&
- priv_check(td, PRIV_TTY_STI))
- return (EACCES);
+ error = tty_sti_check(tp, fflag, td);
+ if (error != 0)
+ return (error);
ttydisc_rint(tp, *(char *)data, 0);
ttydisc_rint_done(tp);
return (0);