[PATCH] char-device: spice_char_device_write_to_device: protect against recursion

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This fixes Spice's smart card support and is related to
commit 697f3214fd16adcd524456003619f7f44ddd031b.

Reported-by: Swapna Krishnan <skrishna@xxxxxxxxxx>

Recursion is now possible starting with spice_char_device_wakeup calling
 spice_char_device_write_to_device that later (after going through qemu)
calls spice_char_device_wakeup.

The protecting code is the same to the one in the read path.

This function call loop makes the program to abort with the following messages:

  usb-ccid: chardev: unexpected message of type 3000000
  qemu: qemu_mutex_lock: Resource deadlock avoided
---

Should I attach the backtrace in the commit message ?

---
 server/char_device.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/server/char_device.c b/server/char_device.c
index c6dc45b..54357f0 100644
--- a/server/char_device.c
+++ b/server/char_device.c
@@ -64,6 +64,7 @@ struct SpiceCharDeviceState {
     SpiceCharDeviceInstance *sin;
 
     int during_read_from_device;
+    int during_write_to_device;
 
     SpiceCharDeviceCallbacks cbs;
     void *opaque;
@@ -437,6 +438,11 @@ static int spice_char_device_write_to_device(SpiceCharDeviceState *dev)
         return 0;
     }
 
+    /* protect against recursion with spice_char_device_wakeup */
+    if (dev->during_write_to_device++ > 0) {
+        return 0;
+    }
+
     spice_char_device_state_ref(dev);
 
     if (dev->write_to_dev_timer) {
@@ -461,6 +467,11 @@ static int spice_char_device_write_to_device(SpiceCharDeviceState *dev)
                     dev->cur_write_buf_pos;
         n = sif->write(dev->sin, dev->cur_write_buf_pos, write_len);
         if (n <= 0) {
+            if (dev->during_write_to_device > 1) {
+                dev->during_write_to_device = 1;
+                continue; /* a wakeup might have been called during the write -
+                             make sure it doesn't get lost */
+            }
             break;
         }
         total += n;
@@ -485,6 +496,7 @@ static int spice_char_device_write_to_device(SpiceCharDeviceState *dev)
         }
         dev->active = dev->active || total;
     }
+    dev->during_write_to_device = 0;
     spice_char_device_state_unref(dev);
     return total;
 }
-- 
2.1.0

_______________________________________________
Spice-devel mailing list
Spice-devel@xxxxxxxxxxxxxxxxxxxxx
http://lists.freedesktop.org/mailman/listinfo/spice-devel





[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]     [Monitors]