]> git.proxmox.com Git - pve-kernel-3.10.0.git/blob - n_tty-Fix-n_tty_write-crash-when-echoing-in-raw-mode.patch
add fix for CVE-2014-0196
[pve-kernel-3.10.0.git] / n_tty-Fix-n_tty_write-crash-when-echoing-in-raw-mode.patch
1 From: Peter Hurley <peter@hurleysoftware.com>
2
3 commit 4291086b1f081b869c6d79e5b7441633dc3ace00 upstream.
4
5 The tty atomic_write_lock does not provide an exclusion guarantee for
6 the tty driver if the termios settings are LECHO & !OPOST. And since
7 it is unexpected and not allowed to call TTY buffer helpers like
8 tty_insert_flip_string concurrently, this may lead to crashes when
9 concurrect writers call pty_write. In that case the following two
10 writers:
11 * the ECHOing from a workqueue and
12 * pty_write from the process
13 race and can overflow the corresponding TTY buffer like follows.
14
15 If we look into tty_insert_flip_string_fixed_flag, there is:
16 int space = __tty_buffer_request_room(port, goal, flags);
17 struct tty_buffer *tb = port->buf.tail;
18 ...
19 memcpy(char_buf_ptr(tb, tb->used), chars, space);
20 ...
21 tb->used += space;
22
23 so the race of the two can result in something like this:
24 A B
25 __tty_buffer_request_room
26 __tty_buffer_request_room
27 memcpy(buf(tb->used), ...)
28 tb->used += space;
29 memcpy(buf(tb->used), ...) ->BOOM
30
31 B's memcpy is past the tty_buffer due to the previous A's tb->used
32 increment.
33
34 Since the N_TTY line discipline input processing can output
35 concurrently with a tty write, obtain the N_TTY ldisc output_lock to
36 serialize echo output with normal tty writes. This ensures the tty
37 buffer helper tty_insert_flip_string is not called concurrently and
38 everything is fine.
39
40 Note that this is nicely reproducible by an ordinary user using
41 forkpty and some setup around that (raw termios + ECHO). And it is
42 present in kernels at least after commit
43 d945cb9cce20ac7143c2de8d88b187f62db99bdc (pty: Rework the pty layer to
44 use the normal buffering logic) in 2.6.31-rc3.
45
46 js: add more info to the commit log
47 js: switch to bool
48 js: lock unconditionally
49 js: lock only the tty->ops->write call
50
51 References: CVE-2014-0196
52 Reported-and-tested-by: Jiri Slaby <jslaby@suse.cz>
53 Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
54 Signed-off-by: Jiri Slaby <jslaby@suse.cz>
55 Cc: Linus Torvalds <torvalds@linux-foundation.org>
56 Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
57 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
58
59 ---
60 drivers/tty/n_tty.c | 4 ++++
61 1 file changed, 4 insertions(+)
62
63 --- a/drivers/tty/n_tty.c
64 +++ b/drivers/tty/n_tty.c
65 @@ -2066,8 +2066,12 @@ static ssize_t n_tty_write(struct tty_st
66 if (tty->ops->flush_chars)
67 tty->ops->flush_chars(tty);
68 } else {
69 + struct n_tty_data *ldata = tty->disc_data;
70 +
71 while (nr > 0) {
72 + mutex_lock(&ldata->output_lock);
73 c = tty->ops->write(tty, b, nr);
74 + mutex_unlock(&ldata->output_lock);
75 if (c < 0) {
76 retval = c;
77 goto break_out;
78