public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] tty: Fix a USB serial crash/scribble
@ 2009-07-22  9:39 Alan Cox
  2009-07-22 10:16 ` Daniel Mack
  0 siblings, 1 reply; 5+ messages in thread
From: Alan Cox @ 2009-07-22  9:39 UTC (permalink / raw)
  To: daniel, linux-kernel, linux-usb, stern

See if this one looks sensible. It does leave a tiny race window but that
semes wiser than hacking up the tty kref_put path in the middle of an -rc
series.

Thanks to Daniel and Alan Stern for chasing this down and getting traces. Also
to Daniel for being persistent when I took it as a random odd "only seen by one
user" error which it wasn't.

---

From: Alan Cox <alan@linux.intel.com>

The port lock is used to protect the port state. However the port structure
is freed on a hangup, then the lock taken on a close. The right fix is to
drop the port on tty->shutdown() but we can't yet do that due to sleep v
non-sleeping rules. Instead do the next best thing and fix it up when we are
not in -rc season.

Reported-by: Daniel Mack <daniel@caiaq.de>
Signed-off-by: Alan Cox <alan@linux.intel.com>
---

 drivers/usb/serial/usb-serial.c |   19 ++++++++++++++++++-
 1 files changed, 18 insertions(+), 1 deletions(-)


diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index bd7581b..228d77c 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -340,6 +340,22 @@ static void serial_close(struct tty_struct *tty, struct file *filp)
 
 	dbg("%s - port %d", __func__, port->number);
 
+	/* FIXME:
+	   This leaves a very narrow race. Really we should do the
+	   serial_do_free() on tty->shutdown(), but tty->shutdown can
+	   be called from IRQ context and serial_do_free can sleep.
+
+	   The right fix is probably to make the tty free (which is rare)
+	   and thus tty->shutdown() occur via a work queue and simplify all
+	   the drivers that use it.
+	*/
+	if (tty_hung_up_p(filp)) {
+		/* serial_hangup already called serial_down at this point.
+		   Another user may have already reopened the port but 
+		   serial_do_free is refcounted */
+		serial_do_free(port);
+		return;
+	}
 
 	if (tty_port_close_start(&port->port, tty, filp) == 0)
 		return;
@@ -355,7 +371,8 @@ static void serial_hangup(struct tty_struct *tty)
 	struct usb_serial_port *port = tty->driver_data;
 	serial_do_down(port);
 	tty_port_hangup(&port->port);
-	serial_do_free(port);
+	/* We must not free port yet - the USB serial layer depends on it's
+	   continued existence */
 }
 
 static int serial_write(struct tty_struct *tty, const unsigned char *buf,


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH] tty: Fix a USB serial crash/scribble
  2009-07-22  9:39 [PATCH] tty: Fix a USB serial crash/scribble Alan Cox
@ 2009-07-22 10:16 ` Daniel Mack
  2009-07-25  4:48   ` Greg KH
  0 siblings, 1 reply; 5+ messages in thread
From: Daniel Mack @ 2009-07-22 10:16 UTC (permalink / raw)
  To: Alan Cox; +Cc: linux-kernel, linux-usb, stern

On Wed, Jul 22, 2009 at 10:39:51AM +0100, Alan Cox wrote:
> See if this one looks sensible. It does leave a tiny race window but that
> semes wiser than hacking up the tty kref_put path in the middle of an -rc
> series.
> 
> Thanks to Daniel and Alan Stern for chasing this down and getting traces. Also
> to Daniel for being persistent when I took it as a random odd "only seen by one
> user" error which it wasn't.

Thanks Alan for your patience. You know the tty layer well which I have
no clue of, so I missed the bits in the close callback.

I tested your patch and can confirm it fixes the problem for me.

Daniel



> The port lock is used to protect the port state. However the port structure
> is freed on a hangup, then the lock taken on a close. The right fix is to
> drop the port on tty->shutdown() but we can't yet do that due to sleep v
> non-sleeping rules. Instead do the next best thing and fix it up when we are
> not in -rc season.
> 
> Reported-by: Daniel Mack <daniel@caiaq.de>
> Signed-off-by: Alan Cox <alan@linux.intel.com>

Tested-by: Daniel Mack <daniel@caiaq.de>


> ---
> 
>  drivers/usb/serial/usb-serial.c |   19 ++++++++++++++++++-
>  1 files changed, 18 insertions(+), 1 deletions(-)
> 
> 
> diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
> index bd7581b..228d77c 100644
> --- a/drivers/usb/serial/usb-serial.c
> +++ b/drivers/usb/serial/usb-serial.c
> @@ -340,6 +340,22 @@ static void serial_close(struct tty_struct *tty, struct file *filp)
>  
>  	dbg("%s - port %d", __func__, port->number);
>  
> +	/* FIXME:
> +	   This leaves a very narrow race. Really we should do the
> +	   serial_do_free() on tty->shutdown(), but tty->shutdown can
> +	   be called from IRQ context and serial_do_free can sleep.
> +
> +	   The right fix is probably to make the tty free (which is rare)
> +	   and thus tty->shutdown() occur via a work queue and simplify all
> +	   the drivers that use it.
> +	*/
> +	if (tty_hung_up_p(filp)) {
> +		/* serial_hangup already called serial_down at this point.
> +		   Another user may have already reopened the port but 
> +		   serial_do_free is refcounted */
> +		serial_do_free(port);
> +		return;
> +	}
>  
>  	if (tty_port_close_start(&port->port, tty, filp) == 0)
>  		return;
> @@ -355,7 +371,8 @@ static void serial_hangup(struct tty_struct *tty)
>  	struct usb_serial_port *port = tty->driver_data;
>  	serial_do_down(port);
>  	tty_port_hangup(&port->port);
> -	serial_do_free(port);
> +	/* We must not free port yet - the USB serial layer depends on it's
> +	   continued existence */
>  }
>  
>  static int serial_write(struct tty_struct *tty, const unsigned char *buf,
> 

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] tty: Fix a USB serial crash/scribble
  2009-07-22 10:16 ` Daniel Mack
@ 2009-07-25  4:48   ` Greg KH
  2009-07-25 11:56     ` Alan Cox
  0 siblings, 1 reply; 5+ messages in thread
From: Greg KH @ 2009-07-25  4:48 UTC (permalink / raw)
  To: Daniel Mack; +Cc: Alan Cox, linux-kernel, linux-usb, stern

On Wed, Jul 22, 2009 at 12:16:31PM +0200, Daniel Mack wrote:
> On Wed, Jul 22, 2009 at 10:39:51AM +0100, Alan Cox wrote:
> > See if this one looks sensible. It does leave a tiny race window but that
> > semes wiser than hacking up the tty kref_put path in the middle of an -rc
> > series.
> > 
> > Thanks to Daniel and Alan Stern for chasing this down and getting traces. Also
> > to Daniel for being persistent when I took it as a random odd "only seen by one
> > user" error which it wasn't.
> 
> Thanks Alan for your patience. You know the tty layer well which I have
> no clue of, so I missed the bits in the close callback.
> 
> I tested your patch and can confirm it fixes the problem for me.
> 
> Daniel
> 
> 
> 
> > The port lock is used to protect the port state. However the port structure
> > is freed on a hangup, then the lock taken on a close. The right fix is to
> > drop the port on tty->shutdown() but we can't yet do that due to sleep v
> > non-sleeping rules. Instead do the next best thing and fix it up when we are
> > not in -rc season.
> > 
> > Reported-by: Daniel Mack <daniel@caiaq.de>
> > Signed-off-by: Alan Cox <alan@linux.intel.com>
> 
> Tested-by: Daniel Mack <daniel@caiaq.de>

Acked-by: Greg Kroah-Hartman <gregkh@suse.de>

Alan, do you want me to send this to Linus, or will you?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] tty: Fix a USB serial crash/scribble
  2009-07-25  4:48   ` Greg KH
@ 2009-07-25 11:56     ` Alan Cox
  2009-07-25 16:55       ` Greg KH
  0 siblings, 1 reply; 5+ messages in thread
From: Alan Cox @ 2009-07-25 11:56 UTC (permalink / raw)
  To: Greg KH; +Cc: Daniel Mack, linux-kernel, linux-usb, stern

> Alan, do you want me to send this to Linus, or will you?

I sent it to him on the 22nd.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] tty: Fix a USB serial crash/scribble
  2009-07-25 11:56     ` Alan Cox
@ 2009-07-25 16:55       ` Greg KH
  0 siblings, 0 replies; 5+ messages in thread
From: Greg KH @ 2009-07-25 16:55 UTC (permalink / raw)
  To: Alan Cox; +Cc: Daniel Mack, linux-kernel, linux-usb, stern

On Sat, Jul 25, 2009 at 12:56:21PM +0100, Alan Cox wrote:
> > Alan, do you want me to send this to Linus, or will you?
> 
> I sent it to him on the 22nd.

Doh, nevermind :)

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2009-07-25 16:56 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-07-22  9:39 [PATCH] tty: Fix a USB serial crash/scribble Alan Cox
2009-07-22 10:16 ` Daniel Mack
2009-07-25  4:48   ` Greg KH
2009-07-25 11:56     ` Alan Cox
2009-07-25 16:55       ` Greg KH

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox