Re: [PATCH v3 1/9] virtio: console: fix race with port unplug and open/close

2013-07-30 Thread Amit Shah
On (Mon) 29 Jul 2013 [14:18:52], Rusty Russell wrote:
 Amit Shah amit.s...@redhat.com writes:
  There's a window between find_port_by_devt() returning a port and us
  taking a kref on the port, where the port could get unplugged.  Fix it
  by taking the reference in find_port_by_devt() itself.
 
  Problem reported and analyzed by Mateusz Guzik.
 
 This fix is clearly correct, but what about the other find_port_by_*
 functions?

They don't need a kref -- the kref is only to be bumped when:

1. Initialising / Plugging in the port (add_port)
2. Opening the port (this fix)

Both these cases are now covered.  As part of the locking rework, the
other find_port_by_* functions may be reworked to set some state, like
port_in_use, instead of abusing guest_connected today.

Amit
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH v3 1/9] virtio: console: fix race with port unplug and open/close

2013-07-29 Thread Rusty Russell
Amit Shah amit.s...@redhat.com writes:
 There's a window between find_port_by_devt() returning a port and us
 taking a kref on the port, where the port could get unplugged.  Fix it
 by taking the reference in find_port_by_devt() itself.

 Problem reported and analyzed by Mateusz Guzik.

This fix is clearly correct, but what about the other find_port_by_*
functions?

Applied,
Rusty.


 CC: sta...@vger.kernel.org
 Reported-by: Mateusz Guzik mgu...@redhat.com
 Signed-off-by: Amit Shah amit.s...@redhat.com
 ---
  drivers/char/virtio_console.c | 13 ++---
  1 file changed, 6 insertions(+), 7 deletions(-)

 diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
 index 1b456fe..291f437 100644
 --- a/drivers/char/virtio_console.c
 +++ b/drivers/char/virtio_console.c
 @@ -272,9 +272,12 @@ static struct port *find_port_by_devt_in_portdev(struct 
 ports_device *portdev,
   unsigned long flags;
  
   spin_lock_irqsave(portdev-ports_lock, flags);
 - list_for_each_entry(port, portdev-ports, list)
 - if (port-cdev-dev == dev)
 + list_for_each_entry(port, portdev-ports, list) {
 + if (port-cdev-dev == dev) {
 + kref_get(port-kref);
   goto out;
 + }
 + }
   port = NULL;
  out:
   spin_unlock_irqrestore(portdev-ports_lock, flags);
 @@ -1019,14 +1022,10 @@ static int port_fops_open(struct inode *inode, struct 
 file *filp)
   struct port *port;
   int ret;
  
 + /* We get the port with a kref here */
   port = find_port_by_devt(cdev-dev);
   filp-private_data = port;
  
 - /* Prevent against a port getting hot-unplugged at the same time */
 - spin_lock_irq(port-portdev-ports_lock);
 - kref_get(port-kref);
 - spin_unlock_irq(port-portdev-ports_lock);
 -
   /*
* Don't allow opening of console port devices -- that's done
* via /dev/hvc
 -- 
 1.8.1.4
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH v3 1/9] virtio: console: fix race with port unplug and open/close

2013-07-25 Thread Amit Shah
There's a window between find_port_by_devt() returning a port and us
taking a kref on the port, where the port could get unplugged.  Fix it
by taking the reference in find_port_by_devt() itself.

Problem reported and analyzed by Mateusz Guzik.

CC: sta...@vger.kernel.org
Reported-by: Mateusz Guzik mgu...@redhat.com
Signed-off-by: Amit Shah amit.s...@redhat.com
---
 drivers/char/virtio_console.c | 13 ++---
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index 1b456fe..291f437 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -272,9 +272,12 @@ static struct port *find_port_by_devt_in_portdev(struct 
ports_device *portdev,
unsigned long flags;
 
spin_lock_irqsave(portdev-ports_lock, flags);
-   list_for_each_entry(port, portdev-ports, list)
-   if (port-cdev-dev == dev)
+   list_for_each_entry(port, portdev-ports, list) {
+   if (port-cdev-dev == dev) {
+   kref_get(port-kref);
goto out;
+   }
+   }
port = NULL;
 out:
spin_unlock_irqrestore(portdev-ports_lock, flags);
@@ -1019,14 +1022,10 @@ static int port_fops_open(struct inode *inode, struct 
file *filp)
struct port *port;
int ret;
 
+   /* We get the port with a kref here */
port = find_port_by_devt(cdev-dev);
filp-private_data = port;
 
-   /* Prevent against a port getting hot-unplugged at the same time */
-   spin_lock_irq(port-portdev-ports_lock);
-   kref_get(port-kref);
-   spin_unlock_irq(port-portdev-ports_lock);
-
/*
 * Don't allow opening of console port devices -- that's done
 * via /dev/hvc
-- 
1.8.1.4

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization