]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
another .32 patch
authorGreg Kroah-Hartman <gregkh@suse.de>
Fri, 29 Jan 2010 21:19:32 +0000 (13:19 -0800)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 29 Jan 2010 21:19:32 +0000 (13:19 -0800)
queue-2.6.32/firewire-core-add_descriptor-size-check.patch [new file with mode: 0644]
queue-2.6.32/series

diff --git a/queue-2.6.32/firewire-core-add_descriptor-size-check.patch b/queue-2.6.32/firewire-core-add_descriptor-size-check.patch
new file mode 100644 (file)
index 0000000..c7430e1
--- /dev/null
@@ -0,0 +1,149 @@
+From stefanr@s5r6.in-berlin.de  Fri Jan 29 13:16:03 2010
+From: Stefan Richter <stefanr@s5r6.in-berlin.de>
+Date: Fri, 29 Jan 2010 21:25:46 +0100 (CET)
+Subject: firewire: core: add_descriptor size check
+To: stable@kernel.org
+Cc: Greg KH <greg@kroah.com>
+Message-ID: <tkrat.2b9cc2097f5274fe@s5r6.in-berlin.de>
+
+
+Backport of commit e300839da40e99581581c5d053a95a172651fec8 upstream.
+
+Presently, firewire-core only checks whether descriptors that are to be
+added by userspace drivers to the local node's config ROM do not exceed
+a size of 256 quadlets.  However, the sum of the bare minimum ROM plus
+all descriptors (from firewire-core, from firewire-net, from userspace)
+must not exceed 256 quadlets.
+
+Otherwise, the bounds of a statically allocated buffer will be
+overwritten.  If the kernel survives that, firewire-core will
+subsequently be unable to parse the local node's config ROM.
+
+(Note, userspace drivers can add descriptors only through device files
+of local nodes.  These are usually only accessible by root, unlike
+device files of remote nodes which may be accessible to lesser
+privileged users.)
+
+Therefore add a test which takes the actual present and required ROM
+size into account for all descriptors of kernelspace and userspace
+drivers.
+
+Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/firewire/core-card.c |   42 +++++++++++++++++++++++++++++-------------
+ 1 file changed, 29 insertions(+), 13 deletions(-)
+
+--- a/drivers/firewire/core-card.c
++++ b/drivers/firewire/core-card.c
+@@ -57,6 +57,9 @@ static LIST_HEAD(card_list);
+ static LIST_HEAD(descriptor_list);
+ static int descriptor_count;
++/* ROM header, bus info block, root dir header, capabilities = 7 quadlets */
++static size_t config_rom_length = 1 + 4 + 1 + 1;
++
+ #define BIB_CRC(v)            ((v) <<  0)
+ #define BIB_CRC_LENGTH(v)     ((v) << 16)
+ #define BIB_INFO_LENGTH(v)    ((v) << 24)
+@@ -72,7 +75,7 @@ static int descriptor_count;
+ #define BIB_CMC                       ((1) << 30)
+ #define BIB_IMC                       ((1) << 31)
+-static u32 *generate_config_rom(struct fw_card *card, size_t *config_rom_length)
++static u32 *generate_config_rom(struct fw_card *card)
+ {
+       struct fw_descriptor *desc;
+       static u32 config_rom[256];
+@@ -131,7 +134,7 @@ static u32 *generate_config_rom(struct f
+       for (i = 0; i < j; i += length + 1)
+               length = fw_compute_block_crc(config_rom + i);
+-      *config_rom_length = j;
++      WARN_ON(j != config_rom_length);
+       return config_rom;
+ }
+@@ -140,17 +143,24 @@ static void update_config_roms(void)
+ {
+       struct fw_card *card;
+       u32 *config_rom;
+-      size_t length;
+       list_for_each_entry (card, &card_list, link) {
+-              config_rom = generate_config_rom(card, &length);
+-              card->driver->set_config_rom(card, config_rom, length);
++              config_rom = generate_config_rom(card);
++              card->driver->set_config_rom(card, config_rom,
++                                           config_rom_length);
+       }
+ }
++static size_t required_space(struct fw_descriptor *desc)
++{
++      /* descriptor + entry into root dir + optional immediate entry */
++      return desc->length + 1 + (desc->immediate > 0 ? 1 : 0);
++}
++
+ int fw_core_add_descriptor(struct fw_descriptor *desc)
+ {
+       size_t i;
++      int ret;
+       /*
+        * Check descriptor is valid; the length of all blocks in the
+@@ -166,15 +176,21 @@ int fw_core_add_descriptor(struct fw_des
+       mutex_lock(&card_mutex);
+-      list_add_tail(&desc->link, &descriptor_list);
+-      descriptor_count++;
+-      if (desc->immediate > 0)
++      if (config_rom_length + required_space(desc) > 256) {
++              ret = -EBUSY;
++      } else {
++              list_add_tail(&desc->link, &descriptor_list);
++              config_rom_length += required_space(desc);
+               descriptor_count++;
+-      update_config_roms();
++              if (desc->immediate > 0)
++                      descriptor_count++;
++              update_config_roms();
++              ret = 0;
++      }
+       mutex_unlock(&card_mutex);
+-      return 0;
++      return ret;
+ }
+ EXPORT_SYMBOL(fw_core_add_descriptor);
+@@ -183,6 +199,7 @@ void fw_core_remove_descriptor(struct fw
+       mutex_lock(&card_mutex);
+       list_del(&desc->link);
++      config_rom_length -= required_space(desc);
+       descriptor_count--;
+       if (desc->immediate > 0)
+               descriptor_count--;
+@@ -436,7 +453,6 @@ int fw_card_add(struct fw_card *card,
+               u32 max_receive, u32 link_speed, u64 guid)
+ {
+       u32 *config_rom;
+-      size_t length;
+       int ret;
+       card->max_receive = max_receive;
+@@ -445,8 +461,8 @@ int fw_card_add(struct fw_card *card,
+       mutex_lock(&card_mutex);
+-      config_rom = generate_config_rom(card, &length);
+-      ret = card->driver->enable(card, config_rom, length);
++      config_rom = generate_config_rom(card);
++      ret = card->driver->enable(card, config_rom, config_rom_length);
+       if (ret == 0)
+               list_add_tail(&card->link, &card_list);
index 77c0527c3de9af2b745b6fd7130ebd6928c2d1bc..ca509eb94465cfc1813ece0bd3cee2b3e5f8c57a 100644 (file)
@@ -34,3 +34,4 @@ input-winbond-cir-remove-dmesg-spam.patch
 x86-disable-hpet-msi-on-ati-sb700-sb800.patch
 iwlwifi-set-default-aggregation-frame-count-limit-to-31.patch
 drm-i915-only-enable-hotplug-for-detected-outputs.patch
+firewire-core-add_descriptor-size-check.patch