1. 05 10月, 2015 1 次提交
    • P
      drivers/tty: make pty.c slightly more explicitly non-modular · 7154988f
      Paul Gortmaker 提交于
      The Kconfig currently controlling compilation of this code is:
      
      drivers/tty/Kconfig:config LEGACY_PTYS
      drivers/tty/Kconfig:    bool "Legacy (BSD) PTY support"
      
      ...and:
      
      drivers/tty/Kconfig:config UNIX98_PTYS
      drivers/tty/Kconfig:    bool "Unix98 PTY support" if EXPERT
      
      combined with this:
      
      obj-$(CONFIG_LEGACY_PTYS)       += pty.o
      obj-$(CONFIG_UNIX98_PTYS)       += pty.o
      
      ...meaning that it currently is not being built as a module by anyone.
      
      Lets remove the traces of modularity we can so that when reading the
      driver there is less doubt it is builtin-only.
      
      Since module_init translates to device_initcall in the non-modular
      case, the init ordering remains unchanged with this commit.
      
      We don't delete the module.h include since other parts of the file are
      using content from there.
      
      Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
      Cc: Jiri Slaby <jslaby@suse.com>
      Signed-off-by: NPaul Gortmaker <paul.gortmaker@windriver.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      7154988f
  2. 24 7月, 2015 1 次提交
  3. 11 5月, 2015 1 次提交
    • P
      pty: Fix input race when closing · 1a48632f
      Peter Hurley 提交于
      A read() from a pty master may mistakenly indicate EOF (errno == -EIO)
      after the pty slave has closed, even though input data remains to be read.
      For example,
      
             pty slave       |        input worker        |    pty master
                             |                            |
                             |                            |   n_tty_read()
      pty_write()            |                            |     input avail? no
        add data             |                            |     sleep
        schedule worker  --->|                            |     .
                             |---> flush_to_ldisc()       |     .
      pty_close()            |       fill read buffer     |     .
        wait for worker      |       wakeup reader    --->|     .
                             |       read buffer full?    |---> input avail ? yes
                             |<---   yes - exit worker    |     copy 4096 bytes to user
        TTY_OTHER_CLOSED <---|                            |<--- kick worker
                             |                            |
      
      		                **** New read() before worker starts ****
      
                             |                            |   n_tty_read()
                             |                            |     input avail? no
                             |                            |     TTY_OTHER_CLOSED? yes
                             |                            |     return -EIO
      
      Several conditions are required to trigger this race:
      1. the ldisc read buffer must become full so the input worker exits
      2. the read() count parameter must be >= 4096 so the ldisc read buffer
         is empty
      3. the subsequent read() occurs before the kicked worker has processed
         more input
      
      However, the underlying cause of the race is that data is pipelined, while
      tty state is not; ie., data already written by the pty slave end is not
      yet visible to the pty master end, but state changes by the pty slave end
      are visible to the pty master end immediately.
      
      Pipeline the TTY_OTHER_CLOSED state through input worker to the reader.
      1. Introduce TTY_OTHER_DONE which is set by the input worker when
         TTY_OTHER_CLOSED is set and either the input buffers are flushed or
         input processing has completed. Readers/polls are woken when
         TTY_OTHER_DONE is set.
      2. Reader/poll checks TTY_OTHER_DONE instead of TTY_OTHER_CLOSED.
      3. A new input worker is started from pty_close() after setting
         TTY_OTHER_CLOSED, which ensures the TTY_OTHER_DONE state will be
         set if the last input worker is already finished (or just about to
         exit).
      
      Remove tty_flush_to_ldisc(); no in-tree callers.
      
      Fixes: 52bce7f8 ("pty, n_tty: Simplify input processing on final close")
      Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=96311
      BugLink: http://bugs.launchpad.net/bugs/1429756
      Cc: <stable@vger.kernel.org> # 3.19+
      Reported-by: NAndy Whitcroft <apw@canonical.com>
      Reported-by: NH.J. Lu <hjl.tools@gmail.com>
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      1a48632f
  4. 03 2月, 2015 4 次提交
    • P
      n_tty: Fix signal handling flushes · d2b6f447
      Peter Hurley 提交于
      BRKINT and ISIG requires input and output flush when a signal char
      is received. However, the order of operations is significant since
      parallel i/o may be ongoing.
      
      Merge the signal handling for BRKINT with ISIG handling.
      
      Process the signal first. This ensures any ongoing i/o is aborted;
      without this, a waiting writer may continue writing after the flush
      occurs and after the signal char has been echoed.
      
      Write lock the termios_rwsem, which excludes parallel writers from
      pushing new i/o until after the output buffers are flushed; claiming
      the write lock is necessary anyway to exclude parallel readers while
      the read buffer is flushed.
      
      Subclass the termios_rwsem for ptys since the slave pty performing
      the flush may appear to reorder the termios_rwsem->tty buffer lock
      lock order; adding annotation clarifies that
        slave tty_buffer lock-> slave termios_rwsem -> master tty_buffer lock
      is a valid lock order.
      
      Flush the echo buffer. In this context, the echo buffer is 'output'.
      Otherwise, the output will appear discontinuous because the output buffer
      was cleared which contains older output than the echo buffer.
      
      Open-code the read buffer flush since the input worker does not need
      kicking (this is the input worker).
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      d2b6f447
    • P
      pty: Fix buffer flush deadlock · 1d1d14da
      Peter Hurley 提交于
      The pty driver does not clear its write buffer when commanded.
      This is to avoid an apparent deadlock between parallel flushes from
      both pty ends; specifically when handling either BRK or INTR input.
      However, parallel flushes from this source is not possible since
      the pty master can never be set to BRKINT or ISIG. Parallel flushes
      from other sources are possible but these do not threaten deadlocks.
      
      Annotate the tty buffer mutex for lockdep to represent the nested
      tty_buffer locking which occurs when the pty slave is processing input
      (its buffer mutex held) and receives INTR or BRK and acquires the
      linked tty buffer mutex via tty_buffer_flush().
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      1d1d14da
    • P
      pty: Fix overlimit memory use · c81622ac
      Peter Hurley 提交于
      The pty_space() computation is broken; the space already consumed
      in the tty buffer is not accounted for.
      
      Use tty_buffer_set_limit(), which enforces the limit automatically.
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      c81622ac
    • P
      tty: Prevent untrappable signals from malicious program · 37480a05
      Peter Hurley 提交于
      Commit 26df6d13 ("tty: Add EXTPROC support for LINEMODE")
      allows a process which has opened a pty master to send _any_ signal
      to the process group of the pty slave. Although potentially
      exploitable by a malicious program running a setuid program on
      a pty slave, it's unknown if this exploit currently exists.
      
      Limit to signals actually used.
      
      Cc: Theodore Ts'o <tytso@mit.edu>
      Cc: Howard Chu <hyc@symas.com>
      Cc: One Thousand Gnomes <gnomes@lxorguk.ukuu.org.uk>
      Cc: Jiri Slaby <jslaby@suse.cz>
      Cc: <stable@vger.kernel.org> # 2.6.36+
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      37480a05
  5. 06 11月, 2014 12 次提交
  6. 24 9月, 2014 1 次提交
  7. 13 7月, 2014 1 次提交
  8. 12 7月, 2014 1 次提交
  9. 25 7月, 2013 2 次提交
    • P
      tty: Fix lock order in tty_do_resize() · dee4a0be
      Peter Hurley 提交于
      Commits 6a1c0680 and
      9356b535, respectively
        'tty: Convert termios_mutex to termios_rwsem' and
        'n_tty: Access termios values safely'
      introduced a circular lock dependency with console_lock and
      termios_rwsem.
      
      The lockdep report [1] shows that n_tty_write() will attempt
      to claim console_lock while holding the termios_rwsem, whereas
      tty_do_resize() may already hold the console_lock while
      claiming the termios_rwsem.
      
      Since n_tty_write() and tty_do_resize() do not contend
      over the same data -- the tty->winsize structure -- correct
      the lock dependency by introducing a new lock which
      specifically serializes access to tty->winsize only.
      
      [1] Lockdep report
      
      ======================================================
      [ INFO: possible circular locking dependency detected ]
      3.10.0-0+tip-xeon+lockdep #0+tip Not tainted
      -------------------------------------------------------
      modprobe/277 is trying to acquire lock:
       (&tty->termios_rwsem){++++..}, at: [<ffffffff81452656>] tty_do_resize+0x36/0xe0
      
      but task is already holding lock:
       ((fb_notifier_list).rwsem){.+.+.+}, at: [<ffffffff8107aac6>] __blocking_notifier_call_chain+0x56/0xc0
      
      which lock already depends on the new lock.
      
      the existing dependency chain (in reverse order) is:
      
      -> #2 ((fb_notifier_list).rwsem){.+.+.+}:
             [<ffffffff810b6d62>] lock_acquire+0x92/0x1f0
             [<ffffffff8175b797>] down_read+0x47/0x5c
             [<ffffffff8107aac6>] __blocking_notifier_call_chain+0x56/0xc0
             [<ffffffff8107ab46>] blocking_notifier_call_chain+0x16/0x20
             [<ffffffff813d7c0b>] fb_notifier_call_chain+0x1b/0x20
             [<ffffffff813d95b2>] register_framebuffer+0x1e2/0x320
             [<ffffffffa01043e1>] drm_fb_helper_initial_config+0x371/0x540 [drm_kms_helper]
             [<ffffffffa01bcb05>] nouveau_fbcon_init+0x105/0x140 [nouveau]
             [<ffffffffa01ad0af>] nouveau_drm_load+0x43f/0x610 [nouveau]
             [<ffffffffa008a79e>] drm_get_pci_dev+0x17e/0x2a0 [drm]
             [<ffffffffa01ad4da>] nouveau_drm_probe+0x25a/0x2a0 [nouveau]
             [<ffffffff813b13db>] local_pci_probe+0x4b/0x80
             [<ffffffff813b1701>] pci_device_probe+0x111/0x120
             [<ffffffff814977eb>] driver_probe_device+0x8b/0x3a0
             [<ffffffff81497bab>] __driver_attach+0xab/0xb0
             [<ffffffff814956ad>] bus_for_each_dev+0x5d/0xa0
             [<ffffffff814971fe>] driver_attach+0x1e/0x20
             [<ffffffff81496cc1>] bus_add_driver+0x111/0x290
             [<ffffffff814982b7>] driver_register+0x77/0x170
             [<ffffffff813b0454>] __pci_register_driver+0x64/0x70
             [<ffffffffa008a9da>] drm_pci_init+0x11a/0x130 [drm]
             [<ffffffffa022a04d>] nouveau_drm_init+0x4d/0x1000 [nouveau]
             [<ffffffff810002ea>] do_one_initcall+0xea/0x1a0
             [<ffffffff810c54cb>] load_module+0x123b/0x1bf0
             [<ffffffff810c5f57>] SyS_init_module+0xd7/0x120
             [<ffffffff817677c2>] system_call_fastpath+0x16/0x1b
      
      -> #1 (console_lock){+.+.+.}:
             [<ffffffff810b6d62>] lock_acquire+0x92/0x1f0
             [<ffffffff810430a7>] console_lock+0x77/0x80
             [<ffffffff8146b2a1>] con_flush_chars+0x31/0x50
             [<ffffffff8145780c>] n_tty_write+0x1ec/0x4d0
             [<ffffffff814541b9>] tty_write+0x159/0x2e0
             [<ffffffff814543f5>] redirected_tty_write+0xb5/0xc0
             [<ffffffff811ab9d5>] vfs_write+0xc5/0x1f0
             [<ffffffff811abec5>] SyS_write+0x55/0xa0
             [<ffffffff817677c2>] system_call_fastpath+0x16/0x1b
      
      -> #0 (&tty->termios_rwsem){++++..}:
             [<ffffffff810b65c3>] __lock_acquire+0x1c43/0x1d30
             [<ffffffff810b6d62>] lock_acquire+0x92/0x1f0
             [<ffffffff8175b724>] down_write+0x44/0x70
             [<ffffffff81452656>] tty_do_resize+0x36/0xe0
             [<ffffffff8146c841>] vc_do_resize+0x3e1/0x4c0
             [<ffffffff8146c99f>] vc_resize+0x1f/0x30
             [<ffffffff813e4535>] fbcon_init+0x385/0x5a0
             [<ffffffff8146a4bc>] visual_init+0xbc/0x120
             [<ffffffff8146cd13>] do_bind_con_driver+0x163/0x320
             [<ffffffff8146cfa1>] do_take_over_console+0x61/0x70
             [<ffffffff813e2b93>] do_fbcon_takeover+0x63/0xc0
             [<ffffffff813e67a5>] fbcon_event_notify+0x715/0x820
             [<ffffffff81762f9d>] notifier_call_chain+0x5d/0x110
             [<ffffffff8107aadc>] __blocking_notifier_call_chain+0x6c/0xc0
             [<ffffffff8107ab46>] blocking_notifier_call_chain+0x16/0x20
             [<ffffffff813d7c0b>] fb_notifier_call_chain+0x1b/0x20
             [<ffffffff813d95b2>] register_framebuffer+0x1e2/0x320
             [<ffffffffa01043e1>] drm_fb_helper_initial_config+0x371/0x540 [drm_kms_helper]
             [<ffffffffa01bcb05>] nouveau_fbcon_init+0x105/0x140 [nouveau]
             [<ffffffffa01ad0af>] nouveau_drm_load+0x43f/0x610 [nouveau]
             [<ffffffffa008a79e>] drm_get_pci_dev+0x17e/0x2a0 [drm]
             [<ffffffffa01ad4da>] nouveau_drm_probe+0x25a/0x2a0 [nouveau]
             [<ffffffff813b13db>] local_pci_probe+0x4b/0x80
             [<ffffffff813b1701>] pci_device_probe+0x111/0x120
             [<ffffffff814977eb>] driver_probe_device+0x8b/0x3a0
             [<ffffffff81497bab>] __driver_attach+0xab/0xb0
             [<ffffffff814956ad>] bus_for_each_dev+0x5d/0xa0
             [<ffffffff814971fe>] driver_attach+0x1e/0x20
             [<ffffffff81496cc1>] bus_add_driver+0x111/0x290
             [<ffffffff814982b7>] driver_register+0x77/0x170
             [<ffffffff813b0454>] __pci_register_driver+0x64/0x70
             [<ffffffffa008a9da>] drm_pci_init+0x11a/0x130 [drm]
             [<ffffffffa022a04d>] nouveau_drm_init+0x4d/0x1000 [nouveau]
             [<ffffffff810002ea>] do_one_initcall+0xea/0x1a0
             [<ffffffff810c54cb>] load_module+0x123b/0x1bf0
             [<ffffffff810c5f57>] SyS_init_module+0xd7/0x120
             [<ffffffff817677c2>] system_call_fastpath+0x16/0x1b
      
      other info that might help us debug this:
      
      Chain exists of:
        &tty->termios_rwsem --> console_lock --> (fb_notifier_list).rwsem
      
       Possible unsafe locking scenario:
      
             CPU0                    CPU1
             ----                    ----
        lock((fb_notifier_list).rwsem);
                                     lock(console_lock);
                                     lock((fb_notifier_list).rwsem);
        lock(&tty->termios_rwsem);
      
       *** DEADLOCK ***
      
      7 locks held by modprobe/277:
       #0:  (&__lockdep_no_validate__){......}, at: [<ffffffff81497b5b>] __driver_attach+0x5b/0xb0
       #1:  (&__lockdep_no_validate__){......}, at: [<ffffffff81497b69>] __driver_attach+0x69/0xb0
       #2:  (drm_global_mutex){+.+.+.}, at: [<ffffffffa008a6dd>] drm_get_pci_dev+0xbd/0x2a0 [drm]
       #3:  (registration_lock){+.+.+.}, at: [<ffffffff813d93f5>] register_framebuffer+0x25/0x320
       #4:  (&fb_info->lock){+.+.+.}, at: [<ffffffff813d8116>] lock_fb_info+0x26/0x60
       #5:  (console_lock){+.+.+.}, at: [<ffffffff813d95a4>] register_framebuffer+0x1d4/0x320
       #6:  ((fb_notifier_list).rwsem){.+.+.+}, at: [<ffffffff8107aac6>] __blocking_notifier_call_chain+0x56/0xc0
      
      stack backtrace:
      CPU: 0 PID: 277 Comm: modprobe Not tainted 3.10.0-0+tip-xeon+lockdep #0+tip
      Hardware name: Dell Inc. Precision WorkStation T5400  /0RW203, BIOS A11 04/30/2012
       ffffffff8213e5e0 ffff8802aa2fb298 ffffffff81755f19 ffff8802aa2fb2e8
       ffffffff8174f506 ffff8802aa2fa000 ffff8802aa2fb378 ffff8802aa2ea8e8
       ffff8802aa2ea910 ffff8802aa2ea8e8 0000000000000006 0000000000000007
      Call Trace:
       [<ffffffff81755f19>] dump_stack+0x19/0x1b
       [<ffffffff8174f506>] print_circular_bug+0x1fb/0x20c
       [<ffffffff810b65c3>] __lock_acquire+0x1c43/0x1d30
       [<ffffffff810b775e>] ? mark_held_locks+0xae/0x120
       [<ffffffff810b78d5>] ? trace_hardirqs_on_caller+0x105/0x1d0
       [<ffffffff810b6d62>] lock_acquire+0x92/0x1f0
       [<ffffffff81452656>] ? tty_do_resize+0x36/0xe0
       [<ffffffff8175b724>] down_write+0x44/0x70
       [<ffffffff81452656>] ? tty_do_resize+0x36/0xe0
       [<ffffffff81452656>] tty_do_resize+0x36/0xe0
       [<ffffffff8146c841>] vc_do_resize+0x3e1/0x4c0
       [<ffffffff8146c99f>] vc_resize+0x1f/0x30
       [<ffffffff813e4535>] fbcon_init+0x385/0x5a0
       [<ffffffff8146a4bc>] visual_init+0xbc/0x120
       [<ffffffff8146cd13>] do_bind_con_driver+0x163/0x320
       [<ffffffff8146cfa1>] do_take_over_console+0x61/0x70
       [<ffffffff813e2b93>] do_fbcon_takeover+0x63/0xc0
       [<ffffffff813e67a5>] fbcon_event_notify+0x715/0x820
       [<ffffffff81762f9d>] notifier_call_chain+0x5d/0x110
       [<ffffffff8107aadc>] __blocking_notifier_call_chain+0x6c/0xc0
       [<ffffffff8107ab46>] blocking_notifier_call_chain+0x16/0x20
       [<ffffffff813d7c0b>] fb_notifier_call_chain+0x1b/0x20
       [<ffffffff813d95b2>] register_framebuffer+0x1e2/0x320
       [<ffffffffa01043e1>] drm_fb_helper_initial_config+0x371/0x540 [drm_kms_helper]
       [<ffffffff8173cbcb>] ? kmemleak_alloc+0x5b/0xc0
       [<ffffffff81198874>] ? kmem_cache_alloc_trace+0x104/0x290
       [<ffffffffa01035e1>] ? drm_fb_helper_single_add_all_connectors+0x81/0xf0 [drm_kms_helper]
       [<ffffffffa01bcb05>] nouveau_fbcon_init+0x105/0x140 [nouveau]
       [<ffffffffa01ad0af>] nouveau_drm_load+0x43f/0x610 [nouveau]
       [<ffffffffa008a79e>] drm_get_pci_dev+0x17e/0x2a0 [drm]
       [<ffffffffa01ad4da>] nouveau_drm_probe+0x25a/0x2a0 [nouveau]
       [<ffffffff8175f162>] ? _raw_spin_unlock_irqrestore+0x42/0x80
       [<ffffffff813b13db>] local_pci_probe+0x4b/0x80
       [<ffffffff813b1701>] pci_device_probe+0x111/0x120
       [<ffffffff814977eb>] driver_probe_device+0x8b/0x3a0
       [<ffffffff81497bab>] __driver_attach+0xab/0xb0
       [<ffffffff81497b00>] ? driver_probe_device+0x3a0/0x3a0
       [<ffffffff814956ad>] bus_for_each_dev+0x5d/0xa0
       [<ffffffff814971fe>] driver_attach+0x1e/0x20
       [<ffffffff81496cc1>] bus_add_driver+0x111/0x290
       [<ffffffffa022a000>] ? 0xffffffffa0229fff
       [<ffffffff814982b7>] driver_register+0x77/0x170
       [<ffffffffa022a000>] ? 0xffffffffa0229fff
       [<ffffffff813b0454>] __pci_register_driver+0x64/0x70
       [<ffffffffa008a9da>] drm_pci_init+0x11a/0x130 [drm]
       [<ffffffffa022a000>] ? 0xffffffffa0229fff
       [<ffffffffa022a000>] ? 0xffffffffa0229fff
       [<ffffffffa022a04d>] nouveau_drm_init+0x4d/0x1000 [nouveau]
       [<ffffffff810002ea>] do_one_initcall+0xea/0x1a0
       [<ffffffff810c54cb>] load_module+0x123b/0x1bf0
       [<ffffffff81399a50>] ? ddebug_proc_open+0xb0/0xb0
       [<ffffffff813855ae>] ? trace_hardirqs_on_thunk+0x3a/0x3f
       [<ffffffff810c5f57>] SyS_init_module+0xd7/0x120
       [<ffffffff817677c2>] system_call_fastpath+0x16/0x1b
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      dee4a0be
    • P
      tty: Remove extra wakeup from pty write() path · 5ede5253
      Peter Hurley 提交于
      Acquiring the write_wait queue spin lock now accounts for the largest
      slice of cpu time on the tty write path. Two factors contribute to
      this situation; a overly-pessimistic line discipline write loop which
      _always_ sets up a wait loop even if i/o will immediately succeed, and
      on ptys, a wakeup storm from reads and writes.
      
      Writer wakeup does not need to be performed by the pty driver.
      Firstly, since the actual i/o is performed within the write, the
      line discipline write loop will continue while space remains in
      the flip buffers. Secondly, when space becomes avail in the
      line discipline receive buffer (and thus also in the flip buffers),
      the pty unthrottle re-wakes the writer (non-flow-controlled line
      disciplines unconditionally unthrottle the driver when data is
      received). Thus, existing in-kernel i/o is guaranteed to advance.
      Finally, writer wakeup occurs at the conclusion of the line discipline
      write (in tty_write_unlock()). This guarantees that any user-space write
      waiters are woken to continue additional i/o.
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      5ede5253
  10. 24 7月, 2013 2 次提交
  11. 18 6月, 2013 1 次提交
  12. 01 5月, 2013 1 次提交
    • L
      tty: fix up atime/mtime mess, take three · b0b88565
      Linus Torvalds 提交于
      We first tried to avoid updating atime/mtime entirely (commit
      b0de59b5: "TTY: do not update atime/mtime on read/write"), and then
      limited it to only update it occasionally (commit 37b7f3c7: "TTY:
      fix atime/mtime regression"), but it turns out that this was both
      insufficient and overkill.
      
      It was insufficient because we let people attach to the shared ptmx node
      to see activity without even reading atime/mtime, and it was overkill
      because the "only once a minute" means that you can't really tell an
      idle person from an active one with 'w'.
      
      So this tries to fix the problem properly.  It marks the shared ptmx
      node as un-notifiable, and it lowers the "only once a minute" to a few
      seconds instead - still long enough that you can't time individual
      keystrokes, but short enough that you can tell whether somebody is
      active or not.
      Reported-by: NSimon Kirby <sim@hostway.ca>
      Acked-by: NJiri Slaby <jslaby@suse.cz>
      Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
      Cc: stable@vger.kernel.org
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      b0b88565
  13. 16 4月, 2013 1 次提交
  14. 16 3月, 2013 1 次提交
  15. 05 2月, 2013 3 次提交
    • P
      pty: Ignore slave open count for master pty open · 80cace72
      Peter Hurley 提交于
      Multiple slave pty opens may be performed in parallel with the
      master open. Of course, all the slave opens will fail because the
      master pty is still locked but during this time the slave pty
      count will be artificially greater than 1. This is should not
      cause the master pty open to fail.
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      80cace72
    • P
      pty: Ignore slave pty close() if never successfully opened · 69939035
      Peter Hurley 提交于
      If the master and slave ptys are opened in parallel, the slave open
      fails because the pty is still locked. This is as designed.
      However, pty_close() is still called for the slave pty which sets
      TTY_OTHER_CLOSED in the master pty. This can cause the master open
      to fail as well.
      
      Use a common pattern in other tty drivers by setting TTY_IO_ERROR
      until the open is successful and only closing the pty if not set.
      
      Note: the master pty always closes regardless of whether the open
      was successful, so that proper cleanup can occur.
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      69939035
    • P
      pty: Fix BUG()s when ptmx_open() errors out · 7acf6cd8
      Peter Hurley 提交于
      If pmtx_open() fails to get a slave inode or fails the pty_open(),
      the tty is released as part of the error cleanup. As evidenced by the
      first BUG stacktrace below, pty_close() assumes that the linked pty has
      a valid, initialized inode* stored in driver_data.
      
      Also, as evidenced by the second BUG stacktrace below, pty_unix98_shutdown()
      assumes that the master pty's driver_data has been initialized.
      
      1) Fix the invalid assumption in pty_close().
      2) Initialize driver_data immediately so proper devpts fs cleanup occurs.
      
      Fixes this BUG:
      
      [  815.868844] BUG: unable to handle kernel NULL pointer dereference at 0000000000000028
      [  815.869018] IP: [<ffffffff81207bcc>] devpts_pty_kill+0x1c/0xa0
      [  815.869190] PGD 7c775067 PUD 79deb067 PMD 0
      [  815.869315] Oops: 0000 [#1] PREEMPT SMP
      [  815.869443] Modules linked in: kvm_intel kvm snd_hda_intel snd_hda_codec snd_hwdep snd_pcm snd_seq_midi microcode snd_rawmidi psmouse serio_raw snd_seq_midi_event snd_seq snd_timer$
      [  815.870025] CPU 0
      [  815.870143] Pid: 27819, comm: stress_test_tty Tainted: G        W    3.8.0-next-20130125+ttypatch-2-xeon #2 Bochs Bochs
      [  815.870386] RIP: 0010:[<ffffffff81207bcc>]  [<ffffffff81207bcc>] devpts_pty_kill+0x1c/0xa0
      [  815.870540] RSP: 0018:ffff88007d3e1ac8  EFLAGS: 00010282
      [  815.870661] RAX: ffff880079c20800 RBX: 0000000000000000 RCX: 0000000000000000
      [  815.870804] RDX: ffff880079c209a8 RSI: 0000000000000286 RDI: 0000000000000000
      [  815.870933] RBP: ffff88007d3e1ae8 R08: 0000000000000000 R09: 0000000000000000
      [  815.871078] R10: 0000000000000000 R11: 0000000000000001 R12: ffff88007bfb7e00
      [  815.871209] R13: 0000000000000005 R14: ffff880079c20c00 R15: ffff880079c20c00
      [  815.871343] FS:  00007f2e86206700(0000) GS:ffff88007fc00000(0000) knlGS:0000000000000000
      [  815.871495] CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
      [  815.871617] CR2: 0000000000000028 CR3: 000000007ae56000 CR4: 00000000000006f0
      [  815.871752] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
      [  815.871902] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
      [  815.872012] Process stress_test_tty (pid: 27819, threadinfo ffff88007d3e0000, task ffff88007c874530)
      [  815.872012] Stack:
      [  815.872012]  ffff88007bfb7e00 ffff880079c20c00 ffff88007bfb7e00 0000000000000005
      [  815.872012]  ffff88007d3e1b08 ffffffff81417be7 ffff88007caa9bd8 ffff880079c20800
      [  815.872012]  ffff88007d3e1bc8 ffffffff8140e5f8 0000000000000000 0000000000000000
      [  815.872012] Call Trace:
      [  815.872012]  [<ffffffff81417be7>] pty_close+0x157/0x170
      [  815.872012]  [<ffffffff8140e5f8>] tty_release+0x138/0x580
      [  815.872012]  [<ffffffff816d29f3>] ? _raw_spin_lock+0x23/0x30
      [  815.872012]  [<ffffffff816d267a>] ? _raw_spin_unlock+0x1a/0x40
      [  815.872012]  [<ffffffff816d0178>] ? __mutex_unlock_slowpath+0x48/0x60
      [  815.872012]  [<ffffffff81417dff>] ptmx_open+0x11f/0x180
      [  815.872012]  [<ffffffff8119394b>] chrdev_open+0x9b/0x1c0
      [  815.872012]  [<ffffffff8118d643>] do_dentry_open+0x203/0x290
      [  815.872012]  [<ffffffff811938b0>] ? cdev_put+0x30/0x30
      [  815.872012]  [<ffffffff8118d705>] finish_open+0x35/0x50
      [  815.872012]  [<ffffffff8119dcce>] do_last+0x6fe/0xe90
      [  815.872012]  [<ffffffff8119a7af>] ? link_path_walk+0x7f/0x880
      [  815.872012]  [<ffffffff810909d5>] ? cpuacct_charge+0x75/0x80
      [  815.872012]  [<ffffffff8119e51c>] path_openat+0xbc/0x4e0
      [  815.872012]  [<ffffffff816d0fd0>] ? __schedule+0x400/0x7f0
      [  815.872012]  [<ffffffff8140e956>] ? tty_release+0x496/0x580
      [  815.872012]  [<ffffffff8119ec11>] do_filp_open+0x41/0xa0
      [  815.872012]  [<ffffffff816d267a>] ? _raw_spin_unlock+0x1a/0x40
      [  815.872012]  [<ffffffff811abe39>] ? __alloc_fd+0xe9/0x140
      [  815.872012]  [<ffffffff8118ea44>] do_sys_open+0xf4/0x1e0
      [  815.872012]  [<ffffffff8118eb51>] sys_open+0x21/0x30
      [  815.872012]  [<ffffffff816da499>] system_call_fastpath+0x16/0x1b
      [  815.872012] Code: 0f 1f 80 00 00 00 00 45 31 e4 eb d7 0f 0b 90 0f 1f 44 00 00 55 48 89 e5 48 83 ec 20 48 89 5d e8 48 89 fb 4c 89 65 f0 4c 89 6d f8 <48> 8b 47 28 48 81 78 58 d1 1c 0$
      [  815.872012] RIP  [<ffffffff81207bcc>] devpts_pty_kill+0x1c/0xa0
      [  815.872012]  RSP <ffff88007d3e1ac8>
      [  815.872012] CR2: 0000000000000028
      [  815.897036] ---[ end trace eadf50b7f34e47d5 ]---
      
      Fixes this BUG also:
      
      [  608.366836] BUG: unable to handle kernel NULL pointer dereference at 0000000000000028
      [  608.366948] IP: [<ffffffff812078d8>] devpts_kill_index+0x18/0x70
      [  608.367050] PGD 7c75b067 PUD 7b919067 PMD 0
      [  608.367135] Oops: 0000 [#1] PREEMPT SMP
      [  608.367201] Modules linked in: kvm_intel kvm snd_hda_intel snd_hda_codec snd_hwdep snd_pcm snd_seq_midi snd_rawmidi snd_seq_midi_event microcode snd_seq psmouse snd_timer snd_seq_device serio_raw snd mac_hid soundcore snd_page_alloc rfcomm virtio_balloon parport_pc bnep bluetooth ppdev i2c_piix4 lp parport floppy
      [  608.367617] CPU 2
      [  608.367669] Pid: 1918, comm: stress_test_tty Tainted: G        W    3.8.0-next-20130125+ttypatch-2-xeon #2 Bochs Bochs
      [  608.367796] RIP: 0010:[<ffffffff812078d8>]  [<ffffffff812078d8>] devpts_kill_index+0x18/0x70
      [  608.367885] RSP: 0018:ffff88007ae41a88  EFLAGS: 00010286
      [  608.367951] RAX: ffffffff81417e80 RBX: ffff880036472400 RCX: 0000000180400028
      [  608.368010] RDX: ffff880036470004 RSI: 0000000000000004 RDI: 0000000000000000
      [  608.368010] RBP: ffff88007ae41a98 R08: 0000000000000000 R09: 0000000000000001
      [  608.368010] R10: ffffea0001f22e40 R11: ffffffff814151d5 R12: 0000000000000004
      [  608.368010] R13: ffff880036470000 R14: 0000000000000004 R15: ffff880036472400
      [  608.368010] FS:  00007ff7a5268700(0000) GS:ffff88007fd00000(0000) knlGS:0000000000000000
      [  608.368010] CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
      [  608.368010] CR2: 0000000000000028 CR3: 000000007a0fd000 CR4: 00000000000006e0
      [  608.368010] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
      [  608.368010] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
      [  608.368010] Process stress_test_tty (pid: 1918, threadinfo ffff88007ae40000, task ffff88003688dc40)
      [  608.368010] Stack:
      [  608.368010]  ffff880036472400 0000000000000001 ffff88007ae41aa8 ffffffff81417e98
      [  608.368010]  ffff88007ae41ac8 ffffffff8140c42b ffff88007ac73100 ffff88007ac73100
      [  608.368010]  ffff88007ae41b98 ffffffff8140ead5 ffff88007ae41b38 ffff88007ca40e40
      [  608.368010] Call Trace:
      [  608.368010]  [<ffffffff81417e98>] pty_unix98_shutdown+0x18/0x20
      [  608.368010]  [<ffffffff8140c42b>] release_tty+0x3b/0xe0
      [  608.368010]  [<ffffffff8140ead5>] __tty_release+0x575/0x5d0
      [  608.368010]  [<ffffffff816d2c63>] ? _raw_spin_lock+0x23/0x30
      [  608.368010]  [<ffffffff816d28ea>] ? _raw_spin_unlock+0x1a/0x40
      [  608.368010]  [<ffffffff816d03e8>] ? __mutex_unlock_slowpath+0x48/0x60
      [  608.368010]  [<ffffffff8140ef79>] tty_open+0x449/0x5f0
      [  608.368010]  [<ffffffff8119394b>] chrdev_open+0x9b/0x1c0
      [  608.368010]  [<ffffffff8118d643>] do_dentry_open+0x203/0x290
      [  608.368010]  [<ffffffff811938b0>] ? cdev_put+0x30/0x30
      [  608.368010]  [<ffffffff8118d705>] finish_open+0x35/0x50
      [  608.368010]  [<ffffffff8119dcce>] do_last+0x6fe/0xe90
      [  608.368010]  [<ffffffff8119a7af>] ? link_path_walk+0x7f/0x880
      [  608.368010]  [<ffffffff8119e51c>] path_openat+0xbc/0x4e0
      [  608.368010]  [<ffffffff8119ec11>] do_filp_open+0x41/0xa0
      [  608.368010]  [<ffffffff816d28ea>] ? _raw_spin_unlock+0x1a/0x40
      [  608.368010]  [<ffffffff811abe39>] ? __alloc_fd+0xe9/0x140
      [  608.368010]  [<ffffffff8118ea44>] do_sys_open+0xf4/0x1e0
      [  608.368010]  [<ffffffff816d2c63>] ? _raw_spin_lock+0x23/0x30
      [  608.368010]  [<ffffffff8118eb51>] sys_open+0x21/0x30
      [  608.368010]  [<ffffffff816da719>] system_call_fastpath+0x16/0x1b
      [  608.368010] Code: ec 48 83 c4 10 5b 41 5c 5d c3 66 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 55 48 89 e5 48 83 ec 10 4c 89 65 f8 41 89 f4 48 89 5d f0 <48> 8b 47 28 48 81 78 58 d1 1c 00 00 74 0b 48 8b 05 4b 66 cf 00
      [  608.368010] RIP  [<ffffffff812078d8>] devpts_kill_index+0x18/0x70
      [  608.368010]  RSP <ffff88007ae41a88>
      [  608.368010] CR2: 0000000000000028
      [  608.394153] ---[ end trace afe83b0fb5fbda93 ]---
      Reported-by: NIlya Zykov <ilya@ilyx.ru>
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      7acf6cd8
  16. 18 1月, 2013 1 次提交
  17. 16 1月, 2013 5 次提交
    • J
      TTY: do not reset master's packet mode · b81273a1
      Jiri Slaby 提交于
      Now that login from util-linux is forced to drop all references to a
      TTY which it wants to hangup (to reach reference count 1) we are
      seeing issues with telnet. When login closes its last reference to the
      slave PTY, it also resets packet mode on the *master* side. And we
      have a race here.
      
      What telnet does is fork+exec of `login'. Then there are two
      scenarios:
      * `login' closes the slave TTY and resets thus master's packet mode,
        but even now telnet properly sets the mode, or
      * `telnetd' sets packet mode on the master, `login' closes the slave
        TTY and resets master's packet mode.
      
      The former case is OK. However the latter happens in much more cases,
      by the order of magnitude to be precise. So when one tries to login to
      such a messed telnet setup, they see the following:
      inux login:
                  ogin incorrect
      
      Note the missing first letters -- telnet thinks it is still in the
      packet mode, so when it receives "linux login" from `login', it
      considers "l" as the type of the packet and strips it.
      
      SuS does not mention how the implementation should behave. Both BSDs I
      checked (Free and Net) do not reset the flag upon the last close.
      
      By this I am resurrecting an old bug, see References. We are hitting
      it regularly now, i.e. with updated util-linux, ergo login.
      
      Here, I am changing a behavior introduced back in 2.1 times. It would
      better have a long time testing before goes upstream.
      Signed-off-by: NJiri Slaby <jslaby@suse.cz>
      Cc: Mauro Carvalho Chehab <mchehab@redhat.com>
      Cc: Bryan Mason <bmason@redhat.com>
      References: https://lkml.org/lkml/2009/11/11/223
      References: https://bugzilla.redhat.com/show_bug.cgi?id=504703
      References: https://bugzilla.novell.com/show_bug.cgi?id=797042Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      b81273a1
    • C
      tty: cleanup checkpatch warning in pty.c · b9f8033f
      Cong Ding 提交于
      spaces are used for indent in 3 places of tty/pty.c, we change it to tab.
      Signed-off-by: NCong Ding <dinggnu@gmail.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      b9f8033f
    • C
      tty: cleanup the panic message · 82f8c35f
      Cong Ding 提交于
      the "\n" in panic message is excess, so we remove it in tty/pty.c as what it
      is used in other places.
      Signed-off-by: NCong Ding <dinggnu@gmail.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      82f8c35f
    • J
      TTY: switch tty_flip_buffer_push · 2e124b4a
      Jiri Slaby 提交于
      Now, we start converting tty buffer functions to actually use
      tty_port. This will allow us to get rid of the need of tty in many
      call sites. Only tty_port will needed and hence no more
      tty_port_tty_get in those paths.
      
      Now, the one where most of tty_port_tty_get gets removed:
      tty_flip_buffer_push.
      
      IOW we also closed all the races in drivers not using tty_port_tty_get
      at all yet.
      
      Also we move tty_flip_buffer_push declaration from include/linux/tty.h
      to include/linux/tty_flip.h to all others while we are changing it
      anyway.
      Signed-off-by: NJiri Slaby <jslaby@suse.cz>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      2e124b4a
    • J
      TTY: switch tty_insert_flip_string · 05c7cd39
      Jiri Slaby 提交于
      Now, we start converting tty buffer functions to actually use
      tty_port. This will allow us to get rid of the need of tty in many
      call sites. Only tty_port will needed and hence no more
      tty_port_tty_get in those paths.
      
      tty_insert_flip_string this time.
      Signed-off-by: NJiri Slaby <jslaby@suse.cz>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      05c7cd39
  18. 22 11月, 2012 1 次提交