git: 59fc4cda1bfa - main - kern: tty: refactor TIOCSTI privilege checks slightly
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 28 May 2025 01:19:27 UTC
The branch main has been updated by kevans: URL: https://cgit.FreeBSD.org/src/commit/?id=59fc4cda1bfa712c46d407d1e83bdd5c63e6e0e3 commit 59fc4cda1bfa712c46d407d1e83bdd5c63e6e0e3 Author: Kyle Evans <kevans@FreeBSD.org> AuthorDate: 2025-05-28 01:19:17 +0000 Commit: Kyle Evans <kevans@FreeBSD.org> CommitDate: 2025-05-28 01:19:17 +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 Differential Revision: https://reviews.freebsd.org/D50506 --- 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);