Add background checks to tty ioctls that modify tty settings
@@ -412,6 +412,8 @@ static void tty_wakeup(tty_t *tty) {
/*
* Check whether we're allowed to continue with an operation.
+ * This function is used before reading or writing to the tty, as well as
+ * modifying tty settings.
* Heavily based on FreeBSD's tty_wait_background().
*/
static int tty_check_background(tty_t *tty, int sig) {
@@ -881,15 +883,18 @@ static int tty_get_termios(tty_t *tty, struct termios *t) {
}
static int tty_set_termios(tty_t *tty, u_long cmd, struct termios *t) {
- int error;
+ int err;
SCOPED_MTX_LOCK(&tty->t_lock);
if (tty_detached(tty))
return ENXIO;
+ if ((err = tty_check_background(tty, SIGTTOU)))
+ return err;
+
if (cmd == TIOCSETAW || cmd == TIOCSETAF)
- if ((error = tty_drain_out(tty)))
- return error;
+ if ((err = tty_drain_out(tty)))
+ return err;
if (cmd == TIOCSETAF)
tty_discard_input(tty);
@@ -945,10 +950,13 @@ static int tty_get_fg_pgrp(tty_t *tty, int *pgid_p) {
}
static int tty_set_fg_pgrp(tty_t *tty, pgid_t pgid) {
+ int err;
WITH_MTX_LOCK (&all_proc_mtx) {
proc_t *p = proc_self();
pgrp_t *pg = pgrp_lookup(pgid);
WITH_MTX_LOCK (&tty->t_lock) {
+ if ((err = tty_check_background(tty, SIGTTOU)))
+ return err;
if (tty_detached(tty))
return ENXIO;
/* The target process group must be in the same session
@@ -965,7 +973,10 @@ static int tty_set_fg_pgrp(tty_t *tty, pgid_t pgid) {
}
static int tty_set_winsize(tty_t *tty, struct winsize *sz) {
+ int err;
SCOPED_MTX_LOCK(&tty->t_lock);
+ if ((err = tty_check_background(tty, SIGTTOU)))
+ return err;
if (memcmp(&tty->t_winsize, sz, sizeof(struct winsize)) == 0)
return 0;
tty->t_winsize = *sz;
