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  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  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: 
> Reported-by: Mateusz Guzik 
> Signed-off-by: Amit Shah 
> ---
>  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: 
Reported-by: Mateusz Guzik 
Signed-off-by: Amit Shah 
---
 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