Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6:
firewire: ohci: fix crashes with TSB43AB23 on 64bit systems
firewire: core: fix use-after-free regression in FCP handler
firewire: cdev: add_descriptor documentation fix
firewire: core: add_descriptor size check

+70 -29
+28 -13
drivers/firewire/core-card.c
··· 57 57 static int descriptor_count; 58 58 59 59 static __be32 tmp_config_rom[256]; 60 + /* ROM header, bus info block, root dir header, capabilities = 7 quadlets */ 61 + static size_t config_rom_length = 1 + 4 + 1 + 1; 60 62 61 63 #define BIB_CRC(v) ((v) << 0) 62 64 #define BIB_CRC_LENGTH(v) ((v) << 16) ··· 75 73 #define BIB_CMC ((1) << 30) 76 74 #define BIB_IMC ((1) << 31) 77 75 78 - static size_t generate_config_rom(struct fw_card *card, __be32 *config_rom) 76 + static void generate_config_rom(struct fw_card *card, __be32 *config_rom) 79 77 { 80 78 struct fw_descriptor *desc; 81 79 int i, j, k, length; ··· 132 130 for (i = 0; i < j; i += length + 1) 133 131 length = fw_compute_block_crc(config_rom + i); 134 132 135 - return j; 133 + WARN_ON(j != config_rom_length); 136 134 } 137 135 138 136 static void update_config_roms(void) 139 137 { 140 138 struct fw_card *card; 141 - size_t length; 142 139 143 140 list_for_each_entry (card, &card_list, link) { 144 - length = generate_config_rom(card, tmp_config_rom); 145 - card->driver->set_config_rom(card, tmp_config_rom, length); 141 + generate_config_rom(card, tmp_config_rom); 142 + card->driver->set_config_rom(card, tmp_config_rom, 143 + config_rom_length); 146 144 } 145 + } 146 + 147 + static size_t required_space(struct fw_descriptor *desc) 148 + { 149 + /* descriptor + entry into root dir + optional immediate entry */ 150 + return desc->length + 1 + (desc->immediate > 0 ? 1 : 0); 147 151 } 148 152 149 153 int fw_core_add_descriptor(struct fw_descriptor *desc) 150 154 { 151 155 size_t i; 156 + int ret; 152 157 153 158 /* 154 159 * Check descriptor is valid; the length of all blocks in the ··· 171 162 172 163 mutex_lock(&card_mutex); 173 164 174 - list_add_tail(&desc->link, &descriptor_list); 175 - descriptor_count++; 176 - if (desc->immediate > 0) 165 + if (config_rom_length + required_space(desc) > 256) { 166 + ret = -EBUSY; 167 + } else { 168 + list_add_tail(&desc->link, &descriptor_list); 169 + config_rom_length += required_space(desc); 177 170 descriptor_count++; 178 - update_config_roms(); 171 + if (desc->immediate > 0) 172 + descriptor_count++; 173 + update_config_roms(); 174 + ret = 0; 175 + } 179 176 180 177 mutex_unlock(&card_mutex); 181 178 182 - return 0; 179 + return ret; 183 180 } 184 181 EXPORT_SYMBOL(fw_core_add_descriptor); 185 182 ··· 194 179 mutex_lock(&card_mutex); 195 180 196 181 list_del(&desc->link); 182 + config_rom_length -= required_space(desc); 197 183 descriptor_count--; 198 184 if (desc->immediate > 0) 199 185 descriptor_count--; ··· 444 428 int fw_card_add(struct fw_card *card, 445 429 u32 max_receive, u32 link_speed, u64 guid) 446 430 { 447 - size_t length; 448 431 int ret; 449 432 450 433 card->max_receive = max_receive; ··· 452 437 453 438 mutex_lock(&card_mutex); 454 439 455 - length = generate_config_rom(card, tmp_config_rom); 456 - ret = card->driver->enable(card, tmp_config_rom, length); 440 + generate_config_rom(card, tmp_config_rom); 441 + ret = card->driver->enable(card, tmp_config_rom, config_rom_length); 457 442 if (ret == 0) 458 443 list_add_tail(&card->link, &card_list); 459 444
+36 -14
drivers/firewire/core-cdev.c
··· 35 35 #include <linux/preempt.h> 36 36 #include <linux/sched.h> 37 37 #include <linux/spinlock.h> 38 + #include <linux/string.h> 38 39 #include <linux/time.h> 39 40 #include <linux/uaccess.h> 40 41 #include <linux/vmalloc.h> ··· 596 595 client->device->max_speed); 597 596 } 598 597 598 + static inline bool is_fcp_request(struct fw_request *request) 599 + { 600 + return request == NULL; 601 + } 602 + 599 603 static void release_request(struct client *client, 600 604 struct client_resource *resource) 601 605 { 602 606 struct inbound_transaction_resource *r = container_of(resource, 603 607 struct inbound_transaction_resource, resource); 604 608 605 - if (r->request) 609 + if (is_fcp_request(r->request)) 610 + kfree(r->data); 611 + else 606 612 fw_send_response(client->device->card, r->request, 607 613 RCODE_CONFLICT_ERROR); 608 614 kfree(r); ··· 624 616 struct address_handler_resource *handler = callback_data; 625 617 struct inbound_transaction_resource *r; 626 618 struct inbound_transaction_event *e; 619 + void *fcp_frame = NULL; 627 620 int ret; 628 621 629 622 r = kmalloc(sizeof(*r), GFP_ATOMIC); ··· 635 626 r->request = request; 636 627 r->data = payload; 637 628 r->length = length; 629 + 630 + if (is_fcp_request(request)) { 631 + /* 632 + * FIXME: Let core-transaction.c manage a 633 + * single reference-counted copy? 634 + */ 635 + fcp_frame = kmemdup(payload, length, GFP_ATOMIC); 636 + if (fcp_frame == NULL) 637 + goto failed; 638 + 639 + r->data = fcp_frame; 640 + } 638 641 639 642 r->resource.release = release_request; 640 643 ret = add_client_resource(handler->client, &r->resource, GFP_ATOMIC); ··· 661 640 e->request.closure = handler->closure; 662 641 663 642 queue_event(handler->client, &e->event, 664 - &e->request, sizeof(e->request), payload, length); 643 + &e->request, sizeof(e->request), r->data, length); 665 644 return; 666 645 667 646 failed: 668 647 kfree(r); 669 648 kfree(e); 670 - if (request) 649 + kfree(fcp_frame); 650 + 651 + if (!is_fcp_request(request)) 671 652 fw_send_response(card, request, RCODE_CONFLICT_ERROR); 672 653 } 673 654 ··· 740 717 741 718 r = container_of(resource, struct inbound_transaction_resource, 742 719 resource); 743 - if (r->request) { 744 - if (request->length < r->length) 745 - r->length = request->length; 746 - if (copy_from_user(r->data, u64_to_uptr(request->data), 747 - r->length)) { 748 - ret = -EFAULT; 749 - kfree(r->request); 750 - goto out; 751 - } 752 - fw_send_response(client->device->card, r->request, 753 - request->rcode); 720 + if (is_fcp_request(r->request)) 721 + goto out; 722 + 723 + if (request->length < r->length) 724 + r->length = request->length; 725 + if (copy_from_user(r->data, u64_to_uptr(request->data), r->length)) { 726 + ret = -EFAULT; 727 + kfree(r->request); 728 + goto out; 754 729 } 730 + fw_send_response(client->device->card, r->request, request->rcode); 755 731 out: 756 732 kfree(r); 757 733
+3 -1
drivers/firewire/ohci.c
··· 2420 2420 2421 2421 #define PCI_VENDOR_ID_AGERE PCI_VENDOR_ID_ATT 2422 2422 #define PCI_DEVICE_ID_AGERE_FW643 0x5901 2423 + #define PCI_DEVICE_ID_TI_TSB43AB23 0x8024 2423 2424 2424 2425 static int __devinit pci_probe(struct pci_dev *dev, 2425 2426 const struct pci_device_id *ent) ··· 2489 2488 #if !defined(CONFIG_X86_32) 2490 2489 /* dual-buffer mode is broken with descriptor addresses above 2G */ 2491 2490 if (dev->vendor == PCI_VENDOR_ID_TI && 2492 - dev->device == PCI_DEVICE_ID_TI_TSB43AB22) 2491 + (dev->device == PCI_DEVICE_ID_TI_TSB43AB22 || 2492 + dev->device == PCI_DEVICE_ID_TI_TSB43AB23)) 2493 2493 ohci->use_dualbuffer = false; 2494 2494 #endif 2495 2495
+3 -1
include/linux/firewire-cdev.h
··· 380 380 * @immediate: If non-zero, immediate key to insert before pointer 381 381 * @key: Upper 8 bits of root directory pointer 382 382 * @data: Userspace pointer to contents of descriptor block 383 - * @length: Length of descriptor block data, in bytes 383 + * @length: Length of descriptor block data, in quadlets 384 384 * @handle: Handle to the descriptor, written by the kernel 385 385 * 386 386 * Add a descriptor block and optionally a preceding immediate key to the local ··· 393 393 * 394 394 * If not 0, the @immediate field specifies an immediate key which will be 395 395 * inserted before the root directory pointer. 396 + * 397 + * @immediate, @key, and @data array elements are CPU-endian quadlets. 396 398 * 397 399 * If successful, the kernel adds the descriptor and writes back a handle to the 398 400 * kernel-side object to be used for later removal of the descriptor block and