|
@@ -2128,8 +2128,24 @@ retry_open:
|
|
|
if (!noctty &&
|
|
|
current->signal->leader &&
|
|
|
!current->signal->tty &&
|
|
|
- tty->session == NULL)
|
|
|
- __proc_set_tty(tty);
|
|
|
+ tty->session == NULL) {
|
|
|
+ /*
|
|
|
+ * Don't let a process that only has write access to the tty
|
|
|
+ * obtain the privileges associated with having a tty as
|
|
|
+ * controlling terminal (being able to reopen it with full
|
|
|
+ * access through /dev/tty, being able to perform pushback).
|
|
|
+ * Many distributions set the group of all ttys to "tty" and
|
|
|
+ * grant write-only access to all terminals for setgid tty
|
|
|
+ * binaries, which should not imply full privileges on all ttys.
|
|
|
+ *
|
|
|
+ * This could theoretically break old code that performs open()
|
|
|
+ * on a write-only file descriptor. In that case, it might be
|
|
|
+ * necessary to also permit this if
|
|
|
+ * inode_permission(inode, MAY_READ) == 0.
|
|
|
+ */
|
|
|
+ if (filp->f_mode & FMODE_READ)
|
|
|
+ __proc_set_tty(tty);
|
|
|
+ }
|
|
|
spin_unlock_irq(¤t->sighand->siglock);
|
|
|
read_unlock(&tasklist_lock);
|
|
|
tty_unlock(tty);
|
|
@@ -2418,7 +2434,7 @@ static int fionbio(struct file *file, int __user *p)
|
|
|
* Takes ->siglock() when updating signal->tty
|
|
|
*/
|
|
|
|
|
|
-static int tiocsctty(struct tty_struct *tty, int arg)
|
|
|
+static int tiocsctty(struct tty_struct *tty, struct file *file, int arg)
|
|
|
{
|
|
|
int ret = 0;
|
|
|
|
|
@@ -2452,6 +2468,13 @@ static int tiocsctty(struct tty_struct *tty, int arg)
|
|
|
goto unlock;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ /* See the comment in tty_open(). */
|
|
|
+ if ((file->f_mode & FMODE_READ) == 0 && !capable(CAP_SYS_ADMIN)) {
|
|
|
+ ret = -EPERM;
|
|
|
+ goto unlock;
|
|
|
+ }
|
|
|
+
|
|
|
proc_set_tty(tty);
|
|
|
unlock:
|
|
|
read_unlock(&tasklist_lock);
|
|
@@ -2844,7 +2867,7 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
|
|
no_tty();
|
|
|
return 0;
|
|
|
case TIOCSCTTY:
|
|
|
- return tiocsctty(tty, arg);
|
|
|
+ return tiocsctty(tty, file, arg);
|
|
|
case TIOCGPGRP:
|
|
|
return tiocgpgrp(tty, real_tty, p);
|
|
|
case TIOCSPGRP:
|