aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Slaby <jslaby@suse.cz>2011-11-11 04:47:23 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2011-11-15 18:52:47 -0500
commit955787ca94a17bdfd00e369a21ceb97aa21792fc (patch)
tree16bd8e8a7c154be15dcb0c7375c4c8c2c7c019c9
parent2cd0050cf3ec4da847c3a2f7d95cffd548aef39d (diff)
TTY: move debug checking out of tty_release
There is no need to taint the tty_release code with paranoia checking. So move it out of line to a separate function. Making thus tty_release more readable. [v2] don't introduce a hard to reproduce use after free (scheduled work would need to preempt the current thread) Signed-off-by: Jiri Slaby <jslaby@suse.cz> Cc: Alan Cox <alan@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/tty/tty_io.c101
1 files changed, 57 insertions, 44 deletions
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index 76e66ff5e65..b874b6d1b0b 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -1557,6 +1557,62 @@ static void release_tty(struct tty_struct *tty, int idx)
1557} 1557}
1558 1558
1559/** 1559/**
1560 * tty_release_checks - check a tty before real release
1561 * @tty: tty to check
1562 * @o_tty: link of @tty (if any)
1563 * @idx: index of the tty
1564 *
1565 * Performs some paranoid checking before true release of the @tty.
1566 * This is a no-op unless TTY_PARANOIA_CHECK is defined.
1567 */
1568static int tty_release_checks(struct tty_struct *tty, struct tty_struct *o_tty,
1569 int idx)
1570{
1571#ifdef TTY_PARANOIA_CHECK
1572 if (idx < 0 || idx >= tty->driver->num) {
1573 printk(KERN_DEBUG "tty_release_dev: bad idx when trying to "
1574 "free (%s)\n", tty->name);
1575 return -1;
1576 }
1577
1578 /* not much to check for devpts */
1579 if (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM)
1580 return 0;
1581
1582 if (tty != tty->driver->ttys[idx]) {
1583 printk(KERN_DEBUG "tty_release_dev: driver.table[%d] not tty "
1584 "for (%s)\n", idx, tty->name);
1585 return -1;
1586 }
1587 if (tty->termios != tty->driver->termios[idx]) {
1588 printk(KERN_DEBUG "tty_release_dev: driver.termios[%d] not termios "
1589 "for (%s)\n",
1590 idx, tty->name);
1591 return -1;
1592 }
1593 if (tty->driver->other) {
1594 if (o_tty != tty->driver->other->ttys[idx]) {
1595 printk(KERN_DEBUG "tty_release_dev: other->table[%d] "
1596 "not o_tty for (%s)\n",
1597 idx, tty->name);
1598 return -1;
1599 }
1600 if (o_tty->termios != tty->driver->other->termios[idx]) {
1601 printk(KERN_DEBUG "tty_release_dev: other->termios[%d] "
1602 "not o_termios for (%s)\n",
1603 idx, tty->name);
1604 return -1;
1605 }
1606 if (o_tty->link != tty) {
1607 printk(KERN_DEBUG "tty_release_dev: bad pty pointers\n");
1608 return -1;
1609 }
1610 }
1611#endif
1612 return 0;
1613}
1614
1615/**
1560 * tty_release - vfs callback for close 1616 * tty_release - vfs callback for close
1561 * @inode: inode of tty 1617 * @inode: inode of tty
1562 * @filp: file pointer for handle to tty 1618 * @filp: file pointer for handle to tty
@@ -1598,59 +1654,16 @@ int tty_release(struct inode *inode, struct file *filp)
1598 devpts = (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM) != 0; 1654 devpts = (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM) != 0;
1599 o_tty = tty->link; 1655 o_tty = tty->link;
1600 1656
1601#ifdef TTY_PARANOIA_CHECK 1657 if (tty_release_checks(tty, o_tty, idx)) {
1602 if (idx < 0 || idx >= tty->driver->num) {
1603 printk(KERN_DEBUG "tty_release_dev: bad idx when trying to "
1604 "free (%s)\n", tty->name);
1605 tty_unlock(); 1658 tty_unlock();
1606 return 0; 1659 return 0;
1607 } 1660 }
1608 if (!devpts) {
1609 if (tty != tty->driver->ttys[idx]) {
1610 tty_unlock();
1611 printk(KERN_DEBUG "tty_release_dev: driver.table[%d] not tty "
1612 "for (%s)\n", idx, tty->name);
1613 return 0;
1614 }
1615 if (tty->termios != tty->driver->termios[idx]) {
1616 tty_unlock();
1617 printk(KERN_DEBUG "tty_release_dev: driver.termios[%d] not termios "
1618 "for (%s)\n",
1619 idx, tty->name);
1620 return 0;
1621 }
1622 }
1623#endif
1624 1661
1625#ifdef TTY_DEBUG_HANGUP 1662#ifdef TTY_DEBUG_HANGUP
1626 printk(KERN_DEBUG "tty_release_dev of %s (tty count=%d)...", 1663 printk(KERN_DEBUG "tty_release_dev of %s (tty count=%d)...",
1627 tty_name(tty, buf), tty->count); 1664 tty_name(tty, buf), tty->count);
1628#endif 1665#endif
1629 1666
1630#ifdef TTY_PARANOIA_CHECK
1631 if (tty->driver->other &&
1632 !(tty->driver->flags & TTY_DRIVER_DEVPTS_MEM)) {
1633 if (o_tty != tty->driver->other->ttys[idx]) {
1634 tty_unlock();
1635 printk(KERN_DEBUG "tty_release_dev: other->table[%d] "
1636 "not o_tty for (%s)\n",
1637 idx, tty->name);
1638 return 0 ;
1639 }
1640 if (o_tty->termios != tty->driver->other->termios[idx]) {
1641 tty_unlock();
1642 printk(KERN_DEBUG "tty_release_dev: other->termios[%d] "
1643 "not o_termios for (%s)\n",
1644 idx, tty->name);
1645 return 0;
1646 }
1647 if (o_tty->link != tty) {
1648 tty_unlock();
1649 printk(KERN_DEBUG "tty_release_dev: bad pty pointers\n");
1650 return 0;
1651 }
1652 }
1653#endif
1654 if (tty->ops->close) 1667 if (tty->ops->close)
1655 tty->ops->close(tty, filp); 1668 tty->ops->close(tty, filp);
1656 1669