From: Greg Kroah-Hartman Date: Fri, 29 Jan 2010 21:19:32 +0000 (-0800) Subject: another .32 patch X-Git-Tag: v2.6.32.8~10 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a48ac96e383ecabe8284be088538409719925b4e;p=thirdparty%2Fkernel%2Fstable-queue.git another .32 patch --- 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 index 00000000000..c7430e16c02 --- /dev/null +++ b/queue-2.6.32/firewire-core-add_descriptor-size-check.patch @@ -0,0 +1,149 @@ +From stefanr@s5r6.in-berlin.de Fri Jan 29 13:16:03 2010 +From: Stefan Richter +Date: Fri, 29 Jan 2010 21:25:46 +0100 (CET) +Subject: firewire: core: add_descriptor size check +To: stable@kernel.org +Cc: Greg KH +Message-ID: + + +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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); + diff --git a/queue-2.6.32/series b/queue-2.6.32/series index 77c0527c3de..ca509eb9446 100644 --- a/queue-2.6.32/series +++ b/queue-2.6.32/series @@ -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