[kernel] r18317 - in dists/sid/linux-2.6/debian: . patches/bugfix/all patches/series
Ben Hutchings
benh at alioth.debian.org
Fri Nov 25 00:46:04 UTC 2011
Author: benh
Date: Fri Nov 25 00:46:02 2011
New Revision: 18317
Log:
lirc_serial: Fix various bugs that may result in a crash, deadlock or other failure (Closes: #645811)
Added:
dists/sid/linux-2.6/debian/patches/bugfix/all/0001-media-staging-lirc_serial-Fix-init-exit-order.patch
dists/sid/linux-2.6/debian/patches/bugfix/all/0002-media-staging-lirc_serial-Free-resources-on-failure-.patch
dists/sid/linux-2.6/debian/patches/bugfix/all/0003-media-staging-lirc_serial-Fix-deadlock-on-resume-fai.patch
dists/sid/linux-2.6/debian/patches/bugfix/all/0004-media-staging-lirc_serial-Fix-bogus-error-codes.patch
dists/sid/linux-2.6/debian/patches/bugfix/all/0005-media-staging-lirc_serial-Do-not-assume-error-codes-.patch
Modified:
dists/sid/linux-2.6/debian/changelog
dists/sid/linux-2.6/debian/patches/series/base
Modified: dists/sid/linux-2.6/debian/changelog
==============================================================================
--- dists/sid/linux-2.6/debian/changelog Thu Nov 24 08:33:38 2011 (r18316)
+++ dists/sid/linux-2.6/debian/changelog Fri Nov 25 00:46:02 2011 (r18317)
@@ -12,6 +12,8 @@
but limit these to devices not supported by brcmsmac
* brcmsmac: Enable as module for all architectures
* Include module taint flags in bug reports
+ * lirc_serial: Fix various bugs that may result in a crash, deadlock or
+ other failure (Closes: #645811)
-- Ben Hutchings <ben at decadent.org.uk> Tue, 22 Nov 2011 05:26:25 +0000
Added: dists/sid/linux-2.6/debian/patches/bugfix/all/0001-media-staging-lirc_serial-Fix-init-exit-order.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/all/0001-media-staging-lirc_serial-Fix-init-exit-order.patch Fri Nov 25 00:46:02 2011 (r18317)
@@ -0,0 +1,141 @@
+From: Ben Hutchings <ben at decadent.org.uk>
+Date: Wed, 16 Nov 2011 01:49:41 -0300
+Subject: [PATCH 1/5] [media] staging: lirc_serial: Fix init/exit order
+
+commit 9105b8b200410383d0854bbe237ee385d7d33ba6 upstream.
+
+Currently the module init function registers a platform_device and
+only then allocates its IRQ and I/O region. This allows allocation to
+race with the device's suspend() function. Instead, allocate
+resources in the platform driver's probe() function and free them in
+the remove() function.
+
+The module exit function removes the platform device before the
+character device that provides access to it. Change it to reverse the
+order of initialisation.
+
+Signed-off-by: Ben Hutchings <ben at decadent.org.uk>
+Signed-off-by: Mauro Carvalho Chehab <mchehab at redhat.com>
+[bwh: Adjust filename for 3.1]
+---
+ drivers/staging/lirc/lirc_serial.c | 56 +++++++++++------------------
+ 1 files changed, 21 insertions(+), 35 deletions(-)
+
+diff --git a/drivers/staging/lirc/lirc_serial.c b/drivers/staging/media/lirc/lirc_serial.c
+index 8a060a8..8637631 100644
+--- a/drivers/staging/lirc/lirc_serial.c
++++ b/drivers/staging/lirc/lirc_serial.c
+@@ -836,7 +836,7 @@ static int hardware_init_port(void)
+ return 0;
+ }
+
+-static int init_port(void)
++static int __devinit lirc_serial_probe(struct platform_device *dev)
+ {
+ int i, nlow, nhigh, result;
+
+@@ -913,6 +913,18 @@ static int init_port(void)
+ return 0;
+ }
+
++static int __devexit lirc_serial_remove(struct platform_device *dev)
++{
++ free_irq(irq, (void *)&hardware);
++
++ if (iommap != 0)
++ release_mem_region(iommap, 8 << ioshift);
++ else
++ release_region(io, 8);
++
++ return 0;
++}
++
+ static int set_use_inc(void *data)
+ {
+ unsigned long flags;
+@@ -1076,16 +1088,6 @@ static struct lirc_driver driver = {
+
+ static struct platform_device *lirc_serial_dev;
+
+-static int __devinit lirc_serial_probe(struct platform_device *dev)
+-{
+- return 0;
+-}
+-
+-static int __devexit lirc_serial_remove(struct platform_device *dev)
+-{
+- return 0;
+-}
+-
+ static int lirc_serial_suspend(struct platform_device *dev,
+ pm_message_t state)
+ {
+@@ -1188,10 +1190,6 @@ static int __init lirc_serial_init_module(void)
+ {
+ int result;
+
+- result = lirc_serial_init();
+- if (result)
+- return result;
+-
+ switch (type) {
+ case LIRC_HOMEBREW:
+ case LIRC_IRDEO:
+@@ -1211,8 +1209,7 @@ static int __init lirc_serial_init_module(void)
+ break;
+ #endif
+ default:
+- result = -EINVAL;
+- goto exit_serial_exit;
++ return -EINVAL;
+ }
+ if (!softcarrier) {
+ switch (type) {
+@@ -1228,37 +1225,26 @@ static int __init lirc_serial_init_module(void)
+ }
+ }
+
+- result = init_port();
+- if (result < 0)
+- goto exit_serial_exit;
++ result = lirc_serial_init();
++ if (result)
++ return result;
++
+ driver.features = hardware[type].features;
+ driver.dev = &lirc_serial_dev->dev;
+ driver.minor = lirc_register_driver(&driver);
+ if (driver.minor < 0) {
+ printk(KERN_ERR LIRC_DRIVER_NAME
+ ": register_chrdev failed!\n");
+- result = -EIO;
+- goto exit_release;
++ lirc_serial_exit();
++ return -EIO;
+ }
+ return 0;
+-exit_release:
+- release_region(io, 8);
+-exit_serial_exit:
+- lirc_serial_exit();
+- return result;
+ }
+
+ static void __exit lirc_serial_exit_module(void)
+ {
+- lirc_serial_exit();
+-
+- free_irq(irq, (void *)&hardware);
+-
+- if (iommap != 0)
+- release_mem_region(iommap, 8 << ioshift);
+- else
+- release_region(io, 8);
+ lirc_unregister_driver(driver.minor);
++ lirc_serial_exit();
+ dprintk("cleaned up module\n");
+ }
+
+--
+1.7.7.3
+
Added: dists/sid/linux-2.6/debian/patches/bugfix/all/0002-media-staging-lirc_serial-Free-resources-on-failure-.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/all/0002-media-staging-lirc_serial-Free-resources-on-failure-.patch Fri Nov 25 00:46:02 2011 (r18317)
@@ -0,0 +1,60 @@
+From: Ben Hutchings <ben at decadent.org.uk>
+Date: Wed, 16 Nov 2011 01:52:11 -0300
+Subject: [PATCH 2/5] [media] staging: lirc_serial: Free resources on failure
+ paths of lirc_serial_probe()
+
+commit c8e57e1b766c2321aa76ee5e6878c69bd2313d62 upstream.
+
+Failure to allocate the I/O region leaves the IRQ allocated.
+A later failure leaves them both allocated.
+
+Reported-by: Torsten Crass <torsten.crass at eBiology.de>
+Signed-off-by: Ben Hutchings <ben at decadent.org.uk>
+Signed-off-by: Mauro Carvalho Chehab <mchehab at redhat.com>
+[bwh: Adjust filename for 3.1]
+---
+ drivers/staging/lirc/lirc_serial.c | 19 ++++++++++++++++---
+ 1 files changed, 16 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/staging/lirc/lirc_serial.c b/drivers/staging/media/lirc/lirc_serial.c
+index 8637631..d833772 100644
+--- a/drivers/staging/lirc/lirc_serial.c
++++ b/drivers/staging/lirc/lirc_serial.c
+@@ -875,11 +875,14 @@ static int __devinit lirc_serial_probe(struct platform_device *dev)
+ ": or compile the serial port driver as module and\n");
+ printk(KERN_WARNING LIRC_DRIVER_NAME
+ ": make sure this module is loaded first\n");
+- return -EBUSY;
++ result = -EBUSY;
++ goto exit_free_irq;
+ }
+
+- if (hardware_init_port() < 0)
+- return -EINVAL;
++ if (hardware_init_port() < 0) {
++ result = -EINVAL;
++ goto exit_release_region;
++ }
+
+ /* Initialize pulse/space widths */
+ init_timing_params(duty_cycle, freq);
+@@ -911,6 +914,16 @@ static int __devinit lirc_serial_probe(struct platform_device *dev)
+
+ dprintk("Interrupt %d, port %04x obtained\n", irq, io);
+ return 0;
++
++exit_release_region:
++ if (iommap != 0)
++ release_mem_region(iommap, 8 << ioshift);
++ else
++ release_region(io, 8);
++exit_free_irq:
++ free_irq(irq, (void *)&hardware);
++
++ return result;
+ }
+
+ static int __devexit lirc_serial_remove(struct platform_device *dev)
+--
+1.7.7.3
+
Added: dists/sid/linux-2.6/debian/patches/bugfix/all/0003-media-staging-lirc_serial-Fix-deadlock-on-resume-fai.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/all/0003-media-staging-lirc_serial-Fix-deadlock-on-resume-fai.patch Fri Nov 25 00:46:02 2011 (r18317)
@@ -0,0 +1,35 @@
+From: Ben Hutchings <ben at decadent.org.uk>
+Date: Wed, 16 Nov 2011 01:53:25 -0300
+Subject: [PATCH 3/5] [media] staging: lirc_serial: Fix deadlock on resume
+ failure
+
+commit 1ff1d88e862948ae5bfe490248c023ff8ac2855d upstream.
+
+A resume function cannot remove the device it is resuming!
+
+Signed-off-by: Ben Hutchings <ben at decadent.org.uk>
+Signed-off-by: Mauro Carvalho Chehab <mchehab at redhat.com>
+[bwh: Adjust filename for 3.1]
+---
+ drivers/staging/lirc/lirc_serial.c | 4 +---
+ 1 files changed, 1 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/staging/lirc/lirc_serial.c b/drivers/staging/media/lirc/lirc_serial.c
+index d833772..befe626 100644
+--- a/drivers/staging/lirc/lirc_serial.c
++++ b/drivers/staging/lirc/lirc_serial.c
+@@ -1127,10 +1127,8 @@ static int lirc_serial_resume(struct platform_device *dev)
+ {
+ unsigned long flags;
+
+- if (hardware_init_port() < 0) {
+- lirc_serial_exit();
++ if (hardware_init_port() < 0)
+ return -EINVAL;
+- }
+
+ spin_lock_irqsave(&hardware[type].lock, flags);
+ /* Enable Interrupt */
+--
+1.7.7.3
+
Added: dists/sid/linux-2.6/debian/patches/bugfix/all/0004-media-staging-lirc_serial-Fix-bogus-error-codes.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/all/0004-media-staging-lirc_serial-Fix-bogus-error-codes.patch Fri Nov 25 00:46:02 2011 (r18317)
@@ -0,0 +1,103 @@
+From: Ben Hutchings <ben at decadent.org.uk>
+Date: Wed, 16 Nov 2011 01:53:35 -0300
+Subject: [PATCH 4/5] [media] staging: lirc_serial: Fix bogus error codes
+
+commit 9b98d60679711753e548be15c6bef5239db6ed64 upstream.
+
+Device not found? ENODEV, not EINVAL.
+Write to read-only device? EPERM, not EBADF.
+Invalid argument? EINVAL, not ENOSYS.
+Unsupported ioctl? ENOIOCTLCMD, not ENOSYS.
+Another function returned an error code? Use that, don't replace it.
+
+Signed-off-by: Ben Hutchings <ben at decadent.org.uk>
+Signed-off-by: Mauro Carvalho Chehab <mchehab at redhat.com>
+[bwh: Adjust filename for 3.1]
+---
+ drivers/staging/lirc/lirc_serial.c | 23 ++++++++++++-----------
+ 1 files changed, 12 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/staging/lirc/lirc_serial.c b/drivers/staging/media/lirc/lirc_serial.c
+index befe626..6f5257e 100644
+--- a/drivers/staging/lirc/lirc_serial.c
++++ b/drivers/staging/lirc/lirc_serial.c
+@@ -773,7 +773,7 @@ static int hardware_init_port(void)
+ /* we fail, there's nothing here */
+ printk(KERN_ERR LIRC_DRIVER_NAME ": port existence test "
+ "failed, cannot continue\n");
+- return -EINVAL;
++ return -ENODEV;
+ }
+
+
+@@ -879,10 +879,9 @@ static int __devinit lirc_serial_probe(struct platform_device *dev)
+ goto exit_free_irq;
+ }
+
+- if (hardware_init_port() < 0) {
+- result = -EINVAL;
++ result = hardware_init_port();
++ if (result < 0)
+ goto exit_release_region;
+- }
+
+ /* Initialize pulse/space widths */
+ init_timing_params(duty_cycle, freq);
+@@ -980,7 +979,7 @@ static ssize_t lirc_write(struct file *file, const char *buf,
+ int *wbuf;
+
+ if (!(hardware[type].features & LIRC_CAN_SEND_PULSE))
+- return -EBADF;
++ return -EPERM;
+
+ count = n / sizeof(int);
+ if (n % sizeof(int) || count % 2 == 0)
+@@ -1031,11 +1030,11 @@ static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
+ return result;
+ /* only LIRC_MODE_PULSE supported */
+ if (value != LIRC_MODE_PULSE)
+- return -ENOSYS;
++ return -EINVAL;
+ break;
+
+ case LIRC_GET_LENGTH:
+- return -ENOSYS;
++ return -ENOIOCTLCMD;
+ break;
+
+ case LIRC_SET_SEND_DUTY_CYCLE:
+@@ -1126,9 +1125,11 @@ static void lirc_serial_exit(void);
+ static int lirc_serial_resume(struct platform_device *dev)
+ {
+ unsigned long flags;
++ int result;
+
+- if (hardware_init_port() < 0)
+- return -EINVAL;
++ result = hardware_init_port();
++ if (result < 0)
++ return result;
+
+ spin_lock_irqsave(&hardware[type].lock, flags);
+ /* Enable Interrupt */
+@@ -1161,7 +1162,7 @@ static int __init lirc_serial_init(void)
+ /* Init read buffer. */
+ result = lirc_buffer_init(&rbuf, sizeof(int), RBUF_LEN);
+ if (result < 0)
+- return -ENOMEM;
++ return result;
+
+ result = platform_driver_register(&lirc_serial_driver);
+ if (result) {
+@@ -1247,7 +1248,7 @@ static int __init lirc_serial_init_module(void)
+ printk(KERN_ERR LIRC_DRIVER_NAME
+ ": register_chrdev failed!\n");
+ lirc_serial_exit();
+- return -EIO;
++ return driver.minor;
+ }
+ return 0;
+ }
+--
+1.7.7.3
+
Added: dists/sid/linux-2.6/debian/patches/bugfix/all/0005-media-staging-lirc_serial-Do-not-assume-error-codes-.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/all/0005-media-staging-lirc_serial-Do-not-assume-error-codes-.patch Fri Nov 25 00:46:02 2011 (r18317)
@@ -0,0 +1,52 @@
+From: Ben Hutchings <ben at decadent.org.uk>
+Date: Wed, 16 Nov 2011 01:54:04 -0300
+Subject: [PATCH 5/5] [media] staging: lirc_serial: Do not assume error codes
+ returned by request_irq()
+
+commit affc9a0d59ac49bd304e2137bd5e4ffdd6fdfa52 upstream.
+
+lirc_serial_probe() must fail if request_irq() returns an error, even if
+it isn't EBUSY or EINVAL,
+
+Signed-off-by: Ben Hutchings <ben at decadent.org.uk>
+Signed-off-by: Mauro Carvalho Chehab <mchehab at redhat.com>
+[bwh: Adjust filename for 3.1]
+---
+ drivers/staging/lirc/lirc_serial.c | 21 +++++++++------------
+ 1 files changed, 9 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/staging/lirc/lirc_serial.c b/drivers/staging/media/lirc/lirc_serial.c
+index 6f5257e..0ca308a 100644
+--- a/drivers/staging/lirc/lirc_serial.c
++++ b/drivers/staging/lirc/lirc_serial.c
+@@ -843,18 +843,15 @@ static int __devinit lirc_serial_probe(struct platform_device *dev)
+ result = request_irq(irq, irq_handler,
+ IRQF_DISABLED | (share_irq ? IRQF_SHARED : 0),
+ LIRC_DRIVER_NAME, (void *)&hardware);
+-
+- switch (result) {
+- case -EBUSY:
+- printk(KERN_ERR LIRC_DRIVER_NAME ": IRQ %d busy\n", irq);
+- return -EBUSY;
+- case -EINVAL:
+- printk(KERN_ERR LIRC_DRIVER_NAME
+- ": Bad irq number or handler\n");
+- return -EINVAL;
+- default:
+- break;
+- };
++ if (result < 0) {
++ if (result == -EBUSY)
++ printk(KERN_ERR LIRC_DRIVER_NAME ": IRQ %d busy\n",
++ irq);
++ else if (result == -EINVAL)
++ printk(KERN_ERR LIRC_DRIVER_NAME
++ ": Bad irq number or handler\n");
++ return result;
++ }
+
+ /* Reserve io region. */
+ /*
+--
+1.7.7.3
+
Modified: dists/sid/linux-2.6/debian/patches/series/base
==============================================================================
--- dists/sid/linux-2.6/debian/patches/series/base Thu Nov 24 08:33:38 2011 (r18316)
+++ dists/sid/linux-2.6/debian/patches/series/base Fri Nov 25 00:46:02 2011 (r18317)
@@ -73,3 +73,9 @@
+ features/arm/imx53_ahci5.patch
+ debian/bcma-Do-not-claim-PCI-device-IDs-also-claimed-by-brc.patch
+
++ bugfix/all/0001-media-staging-lirc_serial-Fix-init-exit-order.patch
++ bugfix/all/0002-media-staging-lirc_serial-Free-resources-on-failure-.patch
++ bugfix/all/0003-media-staging-lirc_serial-Fix-deadlock-on-resume-fai.patch
++ bugfix/all/0004-media-staging-lirc_serial-Fix-bogus-error-codes.patch
++ bugfix/all/0005-media-staging-lirc_serial-Do-not-assume-error-codes-.patch
More information about the Kernel-svn-changes
mailing list