]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 14 Jan 2015 01:50:53 +0000 (17:50 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 14 Jan 2015 01:50:53 +0000 (17:50 -0800)
added patches:
cdc-acm-memory-leak-in-error-case.patch
genhd-check-for-int-overflow-in-disk_expand_part_tbl.patch
serial-samsung-wait-for-transfer-completion-before-clock-disable.patch
writeback-fix-a-subtle-race-condition-in-i_dirty-clearing.patch

queue-3.10/cdc-acm-memory-leak-in-error-case.patch [new file with mode: 0644]
queue-3.10/genhd-check-for-int-overflow-in-disk_expand_part_tbl.patch [new file with mode: 0644]
queue-3.10/serial-samsung-wait-for-transfer-completion-before-clock-disable.patch [new file with mode: 0644]
queue-3.10/series
queue-3.10/writeback-fix-a-subtle-race-condition-in-i_dirty-clearing.patch [new file with mode: 0644]

diff --git a/queue-3.10/cdc-acm-memory-leak-in-error-case.patch b/queue-3.10/cdc-acm-memory-leak-in-error-case.patch
new file mode 100644 (file)
index 0000000..41a1508
--- /dev/null
@@ -0,0 +1,30 @@
+From d908f8478a8d18e66c80a12adb27764920c1f1ca Mon Sep 17 00:00:00 2001
+From: Oliver Neukum <oneukum@suse.de>
+Date: Thu, 20 Nov 2014 14:54:35 +0100
+Subject: cdc-acm: memory leak in error case
+
+From: Oliver Neukum <oneukum@suse.de>
+
+commit d908f8478a8d18e66c80a12adb27764920c1f1ca upstream.
+
+If probe() fails not only the attributes need to be removed
+but also the memory freed.
+
+Reported-by: Ahmed Tamrawi <ahmedtamrawi@gmail.com>
+Signed-off-by: Oliver Neukum <oneukum@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/class/cdc-acm.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/usb/class/cdc-acm.c
++++ b/drivers/usb/class/cdc-acm.c
+@@ -1366,6 +1366,7 @@ alloc_fail8:
+                               &dev_attr_wCountryCodes);
+               device_remove_file(&acm->control->dev,
+                               &dev_attr_iCountryCodeRelDate);
++              kfree(acm->country_codes);
+       }
+       device_remove_file(&acm->control->dev, &dev_attr_bmCapabilities);
+ alloc_fail7:
diff --git a/queue-3.10/genhd-check-for-int-overflow-in-disk_expand_part_tbl.patch b/queue-3.10/genhd-check-for-int-overflow-in-disk_expand_part_tbl.patch
new file mode 100644 (file)
index 0000000..474041c
--- /dev/null
@@ -0,0 +1,44 @@
+From 5fabcb4c33fe11c7e3afdf805fde26c1a54d0953 Mon Sep 17 00:00:00 2001
+From: Jens Axboe <axboe@fb.com>
+Date: Wed, 19 Nov 2014 13:06:22 -0700
+Subject: genhd: check for int overflow in disk_expand_part_tbl()
+
+From: Jens Axboe <axboe@fb.com>
+
+commit 5fabcb4c33fe11c7e3afdf805fde26c1a54d0953 upstream.
+
+We can get here from blkdev_ioctl() -> blkpg_ioctl() -> add_partition()
+with a user passed in partno value. If we pass in 0x7fffffff, the
+new target in disk_expand_part_tbl() overflows the 'int' and we
+access beyond the end of ptbl->part[] and even write to it when we
+do the rcu_assign_pointer() to assign the new partition.
+
+Reported-by: David Ramos <daramos@stanford.edu>
+Signed-off-by: Jens Axboe <axboe@fb.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ block/genhd.c |   11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+--- a/block/genhd.c
++++ b/block/genhd.c
+@@ -1070,9 +1070,16 @@ int disk_expand_part_tbl(struct gendisk
+       struct disk_part_tbl *old_ptbl = disk->part_tbl;
+       struct disk_part_tbl *new_ptbl;
+       int len = old_ptbl ? old_ptbl->len : 0;
+-      int target = partno + 1;
++      int i, target;
+       size_t size;
+-      int i;
++
++      /*
++       * check for int overflow, since we can get here from blkpg_ioctl()
++       * with a user passed 'partno'.
++       */
++      target = partno + 1;
++      if (target < 0)
++              return -EINVAL;
+       /* disk_max_parts() is zero during initialization, ignore if so */
+       if (disk_max_parts(disk) && target > disk_max_parts(disk))
diff --git a/queue-3.10/serial-samsung-wait-for-transfer-completion-before-clock-disable.patch b/queue-3.10/serial-samsung-wait-for-transfer-completion-before-clock-disable.patch
new file mode 100644 (file)
index 0000000..96fbb7f
--- /dev/null
@@ -0,0 +1,41 @@
+From 1ff383a4c3eda8893ec61b02831826e1b1f46b41 Mon Sep 17 00:00:00 2001
+From: Robert Baldyga <r.baldyga@samsung.com>
+Date: Mon, 24 Nov 2014 07:56:21 +0100
+Subject: serial: samsung: wait for transfer completion before clock disable
+
+From: Robert Baldyga <r.baldyga@samsung.com>
+
+commit 1ff383a4c3eda8893ec61b02831826e1b1f46b41 upstream.
+
+This patch adds waiting until transmit buffer and shifter will be empty
+before clock disabling.
+
+Without this fix it's possible to have clock disabled while data was
+not transmited yet, which causes unproper state of TX line and problems
+in following data transfers.
+
+Signed-off-by: Robert Baldyga <r.baldyga@samsung.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/serial/samsung.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/tty/serial/samsung.c
++++ b/drivers/tty/serial/samsung.c
+@@ -534,11 +534,15 @@ static void s3c24xx_serial_pm(struct uar
+                             unsigned int old)
+ {
+       struct s3c24xx_uart_port *ourport = to_ourport(port);
++      int timeout = 10000;
+       ourport->pm_level = level;
+       switch (level) {
+       case 3:
++              while (--timeout && !s3c24xx_serial_txempty_nofifo(port))
++                      udelay(100);
++
+               if (!IS_ERR(ourport->baudclk))
+                       clk_disable_unprepare(ourport->baudclk);
index 17870af0a4986aa2fe0bfb3e97f7a8116582f6f1..dd2df189dc3dc8f44c94547126a1e10e5a7e2e10 100644 (file)
@@ -26,3 +26,7 @@ alsa-usb-audio-extend-kef-x300a-fu-10-tweak-to-arcam-rpac.patch
 alsa-hda-using-uninitialized-data.patch
 alsa-hda-fix-wrong-gpio_dir-gpio_mask-hint-setups-for-idt-stac-codecs.patch
 usb-cdc-acm-check-for-valid-interfaces.patch
+genhd-check-for-int-overflow-in-disk_expand_part_tbl.patch
+cdc-acm-memory-leak-in-error-case.patch
+writeback-fix-a-subtle-race-condition-in-i_dirty-clearing.patch
+serial-samsung-wait-for-transfer-completion-before-clock-disable.patch
diff --git a/queue-3.10/writeback-fix-a-subtle-race-condition-in-i_dirty-clearing.patch b/queue-3.10/writeback-fix-a-subtle-race-condition-in-i_dirty-clearing.patch
new file mode 100644 (file)
index 0000000..fb0e48f
--- /dev/null
@@ -0,0 +1,126 @@
+From 9c6ac78eb3521c5937b2dd8a7d1b300f41092f45 Mon Sep 17 00:00:00 2001
+From: Tejun Heo <tj@kernel.org>
+Date: Fri, 24 Oct 2014 15:38:21 -0400
+Subject: writeback: fix a subtle race condition in I_DIRTY clearing
+
+From: Tejun Heo <tj@kernel.org>
+
+commit 9c6ac78eb3521c5937b2dd8a7d1b300f41092f45 upstream.
+
+After invoking ->dirty_inode(), __mark_inode_dirty() does smp_mb() and
+tests inode->i_state locklessly to see whether it already has all the
+necessary I_DIRTY bits set.  The comment above the barrier doesn't
+contain any useful information - memory barriers can't ensure "changes
+are seen by all cpus" by itself.
+
+And it sure enough was broken.  Please consider the following
+scenario.
+
+ CPU 0                                 CPU 1
+ -------------------------------------------------------------------------------
+
+                                       enters __writeback_single_inode()
+                                       grabs inode->i_lock
+                                       tests PAGECACHE_TAG_DIRTY which is clear
+ enters __set_page_dirty()
+ grabs mapping->tree_lock
+ sets PAGECACHE_TAG_DIRTY
+ releases mapping->tree_lock
+ leaves __set_page_dirty()
+
+ enters __mark_inode_dirty()
+ smp_mb()
+ sees I_DIRTY_PAGES set
+ leaves __mark_inode_dirty()
+                                       clears I_DIRTY_PAGES
+                                       releases inode->i_lock
+
+Now @inode has dirty pages w/ I_DIRTY_PAGES clear.  This doesn't seem
+to lead to an immediately critical problem because requeue_inode()
+later checks PAGECACHE_TAG_DIRTY instead of I_DIRTY_PAGES when
+deciding whether the inode needs to be requeued for IO and there are
+enough unintentional memory barriers inbetween, so while the inode
+ends up with inconsistent I_DIRTY_PAGES flag, it doesn't fall off the
+IO list.
+
+The lack of explicit barrier may also theoretically affect the other
+I_DIRTY bits which deal with metadata dirtiness.  There is no
+guarantee that a strong enough barrier exists between
+I_DIRTY_[DATA]SYNC clearing and write_inode() writing out the dirtied
+inode.  Filesystem inode writeout path likely has enough stuff which
+can behave as full barrier but it's theoretically possible that the
+writeout may not see all the updates from ->dirty_inode().
+
+Fix it by adding an explicit smp_mb() after I_DIRTY clearing.  Note
+that I_DIRTY_PAGES needs a special treatment as it always needs to be
+cleared to be interlocked with the lockless test on
+__mark_inode_dirty() side.  It's cleared unconditionally and
+reinstated after smp_mb() if the mapping still has dirty pages.
+
+Also add comments explaining how and why the barriers are paired.
+
+Lightly tested.
+
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Cc: Jan Kara <jack@suse.cz>
+Cc: Mikulas Patocka <mpatocka@redhat.com>
+Cc: Jens Axboe <axboe@kernel.dk>
+Cc: Al Viro <viro@zeniv.linux.org.uk>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Jens Axboe <axboe@fb.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/fs-writeback.c |   29 ++++++++++++++++++++++-------
+ 1 file changed, 22 insertions(+), 7 deletions(-)
+
+--- a/fs/fs-writeback.c
++++ b/fs/fs-writeback.c
+@@ -470,12 +470,28 @@ __writeback_single_inode(struct inode *i
+        * write_inode()
+        */
+       spin_lock(&inode->i_lock);
+-      /* Clear I_DIRTY_PAGES if we've written out all dirty pages */
+-      if (!mapping_tagged(mapping, PAGECACHE_TAG_DIRTY))
+-              inode->i_state &= ~I_DIRTY_PAGES;
++
+       dirty = inode->i_state & I_DIRTY;
+-      inode->i_state &= ~(I_DIRTY_SYNC | I_DIRTY_DATASYNC);
++      inode->i_state &= ~I_DIRTY;
++
++      /*
++       * Paired with smp_mb() in __mark_inode_dirty().  This allows
++       * __mark_inode_dirty() to test i_state without grabbing i_lock -
++       * either they see the I_DIRTY bits cleared or we see the dirtied
++       * inode.
++       *
++       * I_DIRTY_PAGES is always cleared together above even if @mapping
++       * still has dirty pages.  The flag is reinstated after smp_mb() if
++       * necessary.  This guarantees that either __mark_inode_dirty()
++       * sees clear I_DIRTY_PAGES or we see PAGECACHE_TAG_DIRTY.
++       */
++      smp_mb();
++
++      if (mapping_tagged(mapping, PAGECACHE_TAG_DIRTY))
++              inode->i_state |= I_DIRTY_PAGES;
++
+       spin_unlock(&inode->i_lock);
++
+       /* Don't write the inode if only I_DIRTY_PAGES was set */
+       if (dirty & (I_DIRTY_SYNC | I_DIRTY_DATASYNC)) {
+               int err = write_inode(inode, wbc);
+@@ -1146,12 +1162,11 @@ void __mark_inode_dirty(struct inode *in
+       }
+       /*
+-       * make sure that changes are seen by all cpus before we test i_state
+-       * -- mikulas
++       * Paired with smp_mb() in __writeback_single_inode() for the
++       * following lockless i_state test.  See there for details.
+        */
+       smp_mb();
+-      /* avoid the locking if we can */
+       if ((inode->i_state & flags) == flags)
+               return;