1 |
commit: bf2164613a3bca292fcbba17b9dfd935fd79da72 |
2 |
Author: David Gibson <david <AT> gibson <DOT> dropbear <DOT> id <DOT> au> |
3 |
AuthorDate: Mon Sep 10 02:30:56 2012 +0000 |
4 |
Commit: Doug Goldstein <cardoe <AT> gentoo <DOT> org> |
5 |
CommitDate: Wed Oct 24 07:03:04 2012 +0000 |
6 |
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/qemu-kvm.git;a=commit;h=bf216461 |
7 |
|
8 |
qemu-char: BUGFIX, don't call FD_ISSET with negative fd |
9 |
|
10 |
tcp_chr_connect(), unlike for example udp_chr_update_read_handler() does |
11 |
not check if the fd it is using is valid (>= 0) before passing it to |
12 |
qemu_set_fd_handler2(). If using e.g. a TCP serial port, which is not |
13 |
initially connected, this can result in -1 being passed to FD_ISSET, which |
14 |
has undefined behaviour. On x86 it seems to harmlessly return 0, but on |
15 |
PowerPC, it causes a fortify buffer overflow error to be thrown. |
16 |
|
17 |
This patch fixes this by putting an extra test in tcp_chr_connect(), and |
18 |
also adds an assert qemu_set_fd_handler2() to catch other such errors on |
19 |
all platforms, rather than just some. |
20 |
|
21 |
Signed-off-by: David Gibson <david <AT> gibson.dropbear.id.au> |
22 |
Signed-off-by: Anthony Liguori <aliguori <AT> us.ibm.com> |
23 |
(cherry picked from commit bbdd2ad0814ea0911076419ea21b7957505cf1cc) |
24 |
|
25 |
--- |
26 |
iohandler.c | 2 ++ |
27 |
qemu-char.c | 6 ++++-- |
28 |
2 files changed, 6 insertions(+), 2 deletions(-) |
29 |
|
30 |
diff --git a/iohandler.c b/iohandler.c |
31 |
index dea4355..a2d871b 100644 |
32 |
--- a/iohandler.c |
33 |
+++ b/iohandler.c |
34 |
@@ -56,6 +56,8 @@ int qemu_set_fd_handler2(int fd, |
35 |
{ |
36 |
IOHandlerRecord *ioh; |
37 |
|
38 |
+ assert(fd >= 0); |
39 |
+ |
40 |
if (!fd_read && !fd_write) { |
41 |
QLIST_FOREACH(ioh, &io_handlers, next) { |
42 |
if (ioh->fd == fd) { |
43 |
|
44 |
diff --git a/qemu-char.c b/qemu-char.c |
45 |
index fe1126f..3a68430 100644 |
46 |
--- a/qemu-char.c |
47 |
+++ b/qemu-char.c |
48 |
@@ -2321,8 +2321,10 @@ static void tcp_chr_connect(void *opaque) |
49 |
TCPCharDriver *s = chr->opaque; |
50 |
|
51 |
s->connected = 1; |
52 |
- qemu_set_fd_handler2(s->fd, tcp_chr_read_poll, |
53 |
- tcp_chr_read, NULL, chr); |
54 |
+ if (s->fd >= 0) { |
55 |
+ qemu_set_fd_handler2(s->fd, tcp_chr_read_poll, |
56 |
+ tcp_chr_read, NULL, chr); |
57 |
+ } |
58 |
qemu_chr_generic_open(chr); |
59 |
} |