]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.0-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 5 Jun 2013 05:14:55 +0000 (22:14 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 5 Jun 2013 05:14:55 +0000 (22:14 -0700)
added patches:
alsa-usb-audio-avoid-integer-overflow-in-create_fixed_stream_quirk.patch
alsa-usb-audio-fix-possible-hang-and-overflow-in-parse_uac2_sample_rate_range.patch
jfs-fix-a-couple-races.patch

queue-3.0/alsa-usb-audio-avoid-integer-overflow-in-create_fixed_stream_quirk.patch [new file with mode: 0644]
queue-3.0/alsa-usb-audio-fix-possible-hang-and-overflow-in-parse_uac2_sample_rate_range.patch [new file with mode: 0644]
queue-3.0/jfs-fix-a-couple-races.patch [new file with mode: 0644]
queue-3.0/series

diff --git a/queue-3.0/alsa-usb-audio-avoid-integer-overflow-in-create_fixed_stream_quirk.patch b/queue-3.0/alsa-usb-audio-avoid-integer-overflow-in-create_fixed_stream_quirk.patch
new file mode 100644 (file)
index 0000000..191daf9
--- /dev/null
@@ -0,0 +1,76 @@
+From 8866f405efd4171f9d9c91901d2dd02f01bacb60 Mon Sep 17 00:00:00 2001
+From: Xi Wang <xi.wang@gmail.com>
+Date: Tue, 14 Feb 2012 05:18:48 -0500
+Subject: ALSA: usb-audio: avoid integer overflow in create_fixed_stream_quirk()
+
+From: Xi Wang <xi.wang@gmail.com>
+
+commit 8866f405efd4171f9d9c91901d2dd02f01bacb60 upstream.
+
+A malicious USB device could feed in a large nr_rates value.  This would
+cause the subsequent call to kmemdup() to allocate a smaller buffer than
+expected, leading to out-of-bounds access.
+
+This patch validates the nr_rates value and reuses the limit introduced
+in commit 4fa0e81b ("ALSA: usb-audio: fix possible hang and overflow
+in parse_uac2_sample_rate_range()").
+
+Signed-off-by: Xi Wang <xi.wang@gmail.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Cc: Ben Hutchings <ben@decadent.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/usb/card.h   |    1 +
+ sound/usb/format.c |    4 +---
+ sound/usb/quirks.c |    6 +++++-
+ 3 files changed, 7 insertions(+), 4 deletions(-)
+
+--- a/sound/usb/card.h
++++ b/sound/usb/card.h
+@@ -1,6 +1,7 @@
+ #ifndef __USBAUDIO_CARD_H
+ #define __USBAUDIO_CARD_H
++#define MAX_NR_RATES  1024
+ #define MAX_PACKS     20
+ #define MAX_PACKS_HS  (MAX_PACKS * 8) /* in high speed mode */
+ #define MAX_URBS      8
+--- a/sound/usb/format.c
++++ b/sound/usb/format.c
+@@ -209,8 +209,6 @@ static int parse_audio_format_rates_v1(s
+       return 0;
+ }
+-#define MAX_UAC2_NR_RATES 1024
+-
+ /*
+  * Helper function to walk the array of sample rate triplets reported by
+  * the device. The problem is that we need to parse whole array first to
+@@ -255,7 +253,7 @@ static int parse_uac2_sample_rate_range(
+                       fp->rates |= snd_pcm_rate_to_rate_bit(rate);
+                       nr_rates++;
+-                      if (nr_rates >= MAX_UAC2_NR_RATES) {
++                      if (nr_rates >= MAX_NR_RATES) {
+                               snd_printk(KERN_ERR "invalid uac2 rates\n");
+                               break;
+                       }
+--- a/sound/usb/quirks.c
++++ b/sound/usb/quirks.c
+@@ -131,10 +131,14 @@ static int create_fixed_stream_quirk(str
+       unsigned *rate_table = NULL;
+       fp = kmemdup(quirk->data, sizeof(*fp), GFP_KERNEL);
+-      if (! fp) {
++      if (!fp) {
+               snd_printk(KERN_ERR "cannot memdup\n");
+               return -ENOMEM;
+       }
++      if (fp->nr_rates > MAX_NR_RATES) {
++              kfree(fp);
++              return -EINVAL;
++      }
+       if (fp->nr_rates > 0) {
+               rate_table = kmalloc(sizeof(int) * fp->nr_rates, GFP_KERNEL);
+               if (!rate_table) {
diff --git a/queue-3.0/alsa-usb-audio-fix-possible-hang-and-overflow-in-parse_uac2_sample_rate_range.patch b/queue-3.0/alsa-usb-audio-fix-possible-hang-and-overflow-in-parse_uac2_sample_rate_range.patch
new file mode 100644 (file)
index 0000000..3cbc7d8
--- /dev/null
@@ -0,0 +1,69 @@
+From 4fa0e81b83503900be277e6273a79651b375e288 Mon Sep 17 00:00:00 2001
+From: Xi Wang <xi.wang@gmail.com>
+Date: Sun, 8 Jan 2012 09:02:52 -0500
+Subject: ALSA: usb-audio: fix possible hang and overflow in parse_uac2_sample_rate_range()
+
+From: Xi Wang <xi.wang@gmail.com>
+
+commit 4fa0e81b83503900be277e6273a79651b375e288 upstream.
+
+A malicious USB device may feed in carefully crafted min/max/res values,
+so that the inner loop in parse_uac2_sample_rate_range() could run for
+a long time or even never terminate, e.g., given max = INT_MAX.
+
+Also nr_rates could be a large integer, which causes an integer overflow
+in the subsequent call to kmalloc() in parse_audio_format_rates_v2().
+Thus, kmalloc() would allocate a smaller buffer than expected, leading
+to a memory corruption.
+
+To exploit the two vulnerabilities, an attacker needs physical access
+to the machine to plug in a malicious USB device.
+
+This patch makes two changes.
+
+1) The type of "rate" is changed to unsigned int, so that the loop could
+   stop once "rate" is larger than INT_MAX.
+
+2) Limit nr_rates to 1024.
+
+Suggested-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Xi Wang <xi.wang@gmail.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Cc: Ben Hutchings <ben@decadent.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/usb/format.c |    8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+--- a/sound/usb/format.c
++++ b/sound/usb/format.c
+@@ -209,6 +209,8 @@ static int parse_audio_format_rates_v1(s
+       return 0;
+ }
++#define MAX_UAC2_NR_RATES 1024
++
+ /*
+  * Helper function to walk the array of sample rate triplets reported by
+  * the device. The problem is that we need to parse whole array first to
+@@ -226,7 +228,7 @@ static int parse_uac2_sample_rate_range(
+               int min = combine_quad(&data[2 + 12 * i]);
+               int max = combine_quad(&data[6 + 12 * i]);
+               int res = combine_quad(&data[10 + 12 * i]);
+-              int rate;
++              unsigned int rate;
+               if ((max < 0) || (min < 0) || (res < 0) || (max < min))
+                       continue;
+@@ -253,6 +255,10 @@ static int parse_uac2_sample_rate_range(
+                       fp->rates |= snd_pcm_rate_to_rate_bit(rate);
+                       nr_rates++;
++                      if (nr_rates >= MAX_UAC2_NR_RATES) {
++                              snd_printk(KERN_ERR "invalid uac2 rates\n");
++                              break;
++                      }
+                       /* avoid endless loop */
+                       if (res == 0)
diff --git a/queue-3.0/jfs-fix-a-couple-races.patch b/queue-3.0/jfs-fix-a-couple-races.patch
new file mode 100644 (file)
index 0000000..ce297d5
--- /dev/null
@@ -0,0 +1,54 @@
+From 73aaa22d5ffb2630456bac2f9a4ed9b81d0d7271 Mon Sep 17 00:00:00 2001
+From: Dave Kleikamp <dave.kleikamp@oracle.com>
+Date: Wed, 1 May 2013 11:08:38 -0500
+Subject: jfs: fix a couple races
+
+From: Dave Kleikamp <dave.kleikamp@oracle.com>
+
+commit 73aaa22d5ffb2630456bac2f9a4ed9b81d0d7271 upstream.
+
+This patch fixes races uncovered by xfstests testcase 068.
+
+One race is the result of jfs_sync() trying to write a sync point to the
+journal after it has been frozen (or possibly in the process). Since
+freezing sync's the journal, there is no need to write a sync point so
+we simply want to return.
+
+The second involves jfs_write_inode() being called on a deleted inode.
+It calls jfs_flush_journal which is held up by the jfs_commit thread
+doing the final iput on the same deleted inode, which itself is
+waiting for the I_SYNC flag to be cleared. jfs_write_inode need not
+do anything when i_nlink is zero, which is the easy fix.
+
+Reported-by: Michael L. Semon <mlsemon35@gmail.com>
+Signed-off-by: Dave Kleikamp <dave.kleikamp@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/jfs/inode.c      |    2 +-
+ fs/jfs/jfs_logmgr.c |    3 ++-
+ 2 files changed, 3 insertions(+), 2 deletions(-)
+
+--- a/fs/jfs/inode.c
++++ b/fs/jfs/inode.c
+@@ -125,7 +125,7 @@ int jfs_write_inode(struct inode *inode,
+ {
+       int wait = wbc->sync_mode == WB_SYNC_ALL;
+-      if (test_cflag(COMMIT_Nolink, inode))
++      if (inode->i_nlink == 0)
+               return 0;
+       /*
+        * If COMMIT_DIRTY is not set, the inode isn't really dirty.
+--- a/fs/jfs/jfs_logmgr.c
++++ b/fs/jfs/jfs_logmgr.c
+@@ -1057,7 +1057,8 @@ static int lmLogSync(struct jfs_log * lo
+  */
+ void jfs_syncpt(struct jfs_log *log, int hard_sync)
+ {     LOG_LOCK(log);
+-      lmLogSync(log, hard_sync);
++      if (!test_bit(log_QUIESCE, &log->flag))
++              lmLogSync(log, hard_sync);
+       LOG_UNLOCK(log);
+ }
index 35f2002576ab008875fac616069fce58796b7963..f9054fb83748b7f5ee71fce29f60ac68b1235262 100644 (file)
@@ -26,3 +26,6 @@ cifs-fix-potential-buffer-overrun-when-composing-a-new-options-string.patch
 usb-io_ti-fix-null-dereference-in-chase_port.patch
 libata-make-ata_exec_internal_sg-honor-dmadir.patch
 xen-events-handle-virq_timer-before-any-other-hardirq-in-event-loop.patch
+jfs-fix-a-couple-races.patch
+alsa-usb-audio-fix-possible-hang-and-overflow-in-parse_uac2_sample_rate_range.patch
+alsa-usb-audio-avoid-integer-overflow-in-create_fixed_stream_quirk.patch