The code in main_loop_wait() which handles dispatching of IOHandlers only
checks the 'deleted' flag once per iteration. If a handler was registered
for both read & write events initially, and the read callback removes the
handler, then the write callback will be set to NULL. If select() reported
that there was a write event pending as well, then this will lead to  QEMU
crashing when trying to invoke the NULL write callback. A similar problem
occurs if the handler was registered for read+write, and the read handler
updates it to only select for read in the future - the write callback will
be set to NULL. The attached patch adds neccessary checks to protect against
this problem.

   Signed-off-by: Daniel P. Berrange <[EMAIL PROTECTED]>

Regards,
Dan.
-- 
|=- Red Hat, Engineering, Emerging Technologies, Boston.  +1 978 392 2496 -=|
|=-           Perl modules: http://search.cpan.org/~danberr/              -=|
|=-               Projects: http://freshmeat.net/~danielpb/               -=|
|=-  GnuPG: 7D3B9505   F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505  -=| 
diff -r 25b9628b6900 vl.c
--- a/vl.c      Wed Aug 08 15:02:59 2007 -0400
+++ b/vl.c      Mon Aug 13 15:02:22 2007 -0400
@@ -6453,12 +6453,10 @@ void main_loop_wait(int timeout)
         IOHandlerRecord **pioh;
 
         for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
-            if (ioh->deleted)
-                continue;
-            if (FD_ISSET(ioh->fd, &rfds)) {
+            if (!ioh->deleted && ioh->fd_read && FD_ISSET(ioh->fd, &rfds)) {
                 ioh->fd_read(ioh->opaque);
             }
-            if (FD_ISSET(ioh->fd, &wfds)) {
+            if (!ioh->deleted && ioh->fd_write && FD_ISSET(ioh->fd, &wfds)) {
                 ioh->fd_write(ioh->opaque);
             }
         }

Reply via email to