The branch main has been updated by kevans:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=59fc4cda1bfa712c46d407d1e83bdd5c63e6e0e3

commit 59fc4cda1bfa712c46d407d1e83bdd5c63e6e0e3
Author:     Kyle Evans <kev...@freebsd.org>
AuthorDate: 2025-05-28 01:19:17 +0000
Commit:     Kyle Evans <kev...@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);

Reply via email to