[kernel] r16137 - dists/lenny-security/linux-2.6/debian/patches/bugfix/all
Dann Frazier
dannf at alioth.debian.org
Sat Aug 14 00:49:26 UTC 2010
Author: dannf
Date: Sat Aug 14 00:49:23 2010
New Revision: 16137
Log:
add missing first changeset for hvc_console fix
Modified:
dists/lenny-security/linux-2.6/debian/patches/bugfix/all/hvc_console-fix-race-between-hvc_close-and-hvc_remove.patch
Modified: dists/lenny-security/linux-2.6/debian/patches/bugfix/all/hvc_console-fix-race-between-hvc_close-and-hvc_remove.patch
==============================================================================
--- dists/lenny-security/linux-2.6/debian/patches/bugfix/all/hvc_console-fix-race-between-hvc_close-and-hvc_remove.patch Sat Aug 14 00:49:14 2010 (r16136)
+++ dists/lenny-security/linux-2.6/debian/patches/bugfix/all/hvc_console-fix-race-between-hvc_close-and-hvc_remove.patch Sat Aug 14 00:49:23 2010 (r16137)
@@ -1,4 +1,50 @@
-commit d3da819481b648303db11a3f90dc00f156d36ad5
+[2 changesets backported to Debian's 2.6.26 by dann frazier <dannf at debian.org>]
+
+commit 3852796343ee752d0ea3e3278a1cb57106e850d9
+Author: Amit Shah <amit.shah at redhat.com>
+Date: Fri Mar 12 11:53:15 2010 +0530
+
+ hvc_console: Fix race between hvc_close and hvc_remove
+
+ Alan pointed out a race in the code where hvc_remove is invoked. The
+ recent virtio_console work is the first user of hvc_remove().
+
+ Alan describes it thus:
+
+ The hvc_console assumes that a close and remove call can't occur at the
+ same time.
+
+ In addition tty_hangup(tty) is problematic as tty_hangup is asynchronous
+ itself....
+
+ So this can happen
+
+ hvc_close hvc_remove
+ hung up ? - no
+ lock
+ tty = hp->tty
+ unlock
+ lock
+ hp->tty = NULL
+ unlock
+ notify del
+ kref_put the hvc struct
+ close completes
+ tty is destroyed
+ tty_hangup dead tty
+ tty->ops will be NULL
+ NULL->...
+
+ This patch adds some tty krefs and also converts to using tty_vhangup().
+
+ Reported-by: Alan Cox <alan at lxorguk.ukuu.org.uk>
+ Signed-off-by: Amit Shah <amit.shah at redhat.com>
+ CC: Alan Cox <alan at lxorguk.ukuu.org.uk>
+ CC: linuxppc-dev at ozlabs.org
+ CC: Rusty Russell <rusty at rustcorp.com.au>
+ Signed-off-by: Greg Kroah-Hartman <gregkh at suse.de>
+
+commit 320718ee074acce5ffced6506cb51af1388942aa
Author: Anton Blanchard <anton at samba.org>
Date: Tue Apr 6 21:42:38 2010 +1000
@@ -42,27 +88,109 @@
Signed-off-by: Anton Blanchard <anton at samba.org>
Acked-by: Amit Shah <amit.shah at redhat.com>
Signed-off-by: Rusty Russell <rusty at rustcorp.com.au>
- Debian-backport-by: dann frazier <dannf at debian.org>
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c
-index ea04857..beb5a47 100644
+index 44160d5..beb5a47 100644
--- a/drivers/char/hvc_console.c
+++ b/drivers/char/hvc_console.c
-@@ -405,7 +405,6 @@ static void hvc_close(struct tty_struct *tty, struct file * filp)
- hp = tty->driver_data;
+@@ -343,6 +343,7 @@ static int hvc_open(struct tty_struct *tty, struct file * filp)
+ spin_lock_irqsave(&hp->lock, flags);
+ /* Check and then increment for fast path open. */
+ if (hp->count++ > 0) {
++ tty_kref_get(tty);
+ spin_unlock_irqrestore(&hp->lock, flags);
+ hvc_kick();
+ return 0;
+@@ -351,7 +352,7 @@ static int hvc_open(struct tty_struct *tty, struct file * filp)
+ tty->driver_data = hp;
+ tty->low_latency = 1; /* Makes flushes to ldisc synchronous. */
+
+- hp->tty = tty;
++ hp->tty = tty_kref_get(tty);
+ /* Save for request_irq outside of spin_lock. */
+ irq = hp->irq;
+ if (irq)
+@@ -373,6 +374,7 @@ static int hvc_open(struct tty_struct *tty, struct file * filp)
+ hp->tty = NULL;
+ hp->irq_requested = 0;
+ spin_unlock_irqrestore(&hp->lock, flags);
++ tty_kref_put(tty);
+ tty->driver_data = NULL;
+ kref_put(&hp->kref, destroy_hvc_struct);
+ printk(KERN_ERR "hvc_open: request_irq failed with rc %d.\n", rc);
+@@ -401,6 +403,7 @@ static void hvc_close(struct tty_struct *tty, struct file * filp)
+ return;
+ hp = tty->driver_data;
++
spin_lock_irqsave(&hp->lock, flags);
-- tty_kref_get(tty);
if (--hp->count == 0) {
- if (hp->irq_requested)
-@@ -416,9 +415,6 @@ static void hvc_close(struct tty_struct *tty, struct file * filp)
- hp->tty = NULL;
+@@ -429,6 +432,7 @@ static void hvc_close(struct tty_struct *tty, struct file * filp)
spin_unlock_irqrestore(&hp->lock, flags);
+ }
+
++ tty_kref_put(tty);
+ kref_put(&hp->kref, destroy_hvc_struct);
+ }
+
+@@ -467,6 +471,7 @@ static void hvc_hangup(struct tty_struct *tty)
+ free_irq(irq, hp);
+ while(temp_open_count) {
+ --temp_open_count;
++ tty_kref_put(tty);
+ kref_put(&hp->kref, destroy_hvc_struct);
+ }
+ }
+@@ -594,7 +599,7 @@ static int hvc_poll(struct hvc_struct *hp)
+ poll_mask |= HVC_POLL_WRITE;
+
+ /* No tty attached, just skip */
+- tty = hp->tty;
++ tty = tty_kref_get(hp->tty);
+ if (tty == NULL)
+ goto bail;
+
+@@ -671,6 +676,8 @@ static int hvc_poll(struct hvc_struct *hp)
+
+ tty_flip_buffer_push(tty);
+ }
++ if (tty)
++ tty_kref_put(tty);
+
+ return poll_mask;
+ }
+@@ -797,7 +804,7 @@ int __devexit hvc_remove(struct hvc_struct *hp)
+ struct tty_struct *tty;
+
+ spin_lock_irqsave(&hp->lock, flags);
+- tty = hp->tty;
++ tty = tty_kref_get(hp->tty);
+
+ if (hp->index < MAX_NR_HVC_CONSOLES)
+ vtermnos[hp->index] = -1;
+@@ -809,18 +816,18 @@ int __devexit hvc_remove(struct hvc_struct *hp)
+ /*
+ * We 'put' the instance that was grabbed when the kref instance
+ * was initialized using kref_init(). Let the last holder of this
+- * kref cause it to be removed, which will probably be the tty_hangup
++ * kref cause it to be removed, which will probably be the tty_vhangup
+ * below.
+ */
+ kref_put(&hp->kref, destroy_hvc_struct);
+
+ /*
+- * This function call will auto chain call hvc_hangup. The tty should
+- * always be valid at this time unless a simultaneous tty close already
+- * cleaned up the hvc_struct.
++ * This function call will auto chain call hvc_hangup.
+ */
+- if (tty)
+- tty_hangup(tty);
++ if (tty) {
++ tty_vhangup(tty);
++ tty_kref_put(tty);
++ }
+ return 0;
+ }
-- /* Put the ref obtained in hvc_open() */
-- tty_kref_put(tty);
--
- /*
- * Chain calls chars_in_buffer() and returns immediately if
- * there is no buffered data otherwise sleeps on a wait queue
More information about the Kernel-svn-changes
mailing list