fix crash in sbp2_remove_device() when dma_set_mask() fails
PATCH 1/1 fix crash in sbp2_remove_device() when dma_set_mask() fails
Fix crash in sbp2_remove_device() when dma_set_mask() fails.
--- drivers/ieee1394/sbp2.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/ieee1394/sbp2.c +4 -4
@@ -929,13 +929,14 @@ static void sbp2_remove_device(struct sbif (!lu)return ; - hi = lu->hi; -if (lu->shost) {scsi_remove_host (lu->shost);scsi_host_put (lu->shost); }flush_scheduled_work (); + hi = lu->hi; +if (!hi) +return ;sbp2util_remove_command_orb_pool (lu);list_del (&lu->lu_list);
@@ -977,8 +978,7 @@ static void sbp2_remove_device(struct sb lu->ud->device.driver_data =NULL ; -if (hi) -module_put (hi->host->driver->owner); +module_put (hi->host->driver->owner);kfree (lu); }
Quoted 1 line · Olaf Hering
Fix crash in
sbp2_remove_device()whendma_set_mask()fails.
Thanks for finding this. I will examine the allocation and deallocation paths once more with your fix side by side later today, then move it upstream.
Signature · 3 lines
Stefan Richter -=====-=-=== =--- --=== http://arcgraph.de/sr/
Quoted 6 lines · Olaf Hering
drivers/ieee1394/sbp2.c +0
-0@@ -929,13 +929,14 @@ static void sbp2_remove_device(struct sbif (!lu)return ;
drivers/ieee1394/sbp2.c static void sbp2_remove_device(struct sb · line 939
Quoted 10 lines
drivers/ieee1394/sbp2.c +3
-2- hi = lu->hi; -if (lu->shost) {scsi_remove_host (lu->shost);scsi_host_put (lu->shost); }flush_scheduled_work (); + hi = lu->hi; +if (!hi) +return ;
We need to kfree lu here. Patch comes right away.
Quoted 13 lines
drivers/ieee1394/sbp2.c +1
-2sbp2util_remove_command_orb_pool (lu);list_del (&lu->lu_list);@@ -977,8 +978,7 @@ static void sbp2_remove_device(struct sb lu->ud->device.driver_data =NULL ; -if (hi) -module_put (hi->host->driver->owner); +module_put (hi->host->driver->owner);kfree (lu); }
Signature · 3 lines
Stefan Richter -=====-=-=== =--- -=-== http://arcgraph.de/sr/
PATCH 1/1 ieee1394: sbp2: fix sbp2_remove_device for error cases
Date:
From: Stefan Richter <[email protected]>
Subject: ieee1394: sbp2: fix sbp2_remove_device for error cases
Bug found by Olaf Hering <[email protected]>:sbp2util_remove_command_orb_pool requires a valid lu->hi pointer.
--- drivers/ieee1394/sbp2.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
drivers/ieee1394/sbp2.c +7 -7
@@ -513,9 +513,9 @@ static int sbp2util_create_command_orb_preturn 0 ; } -static void sbp2util_remove_command_orb_pool (struct sbp2_lu *lu) +static void sbp2util_remove_command_orb_pool (struct sbp2_lu *lu, +struct hpsb_host *host) { -struct hpsb_host *host = lu->hi->host;struct list_head *lh, *next;struct sbp2_command_info *cmd;unsigned long flags;
@@ -922,15 +922,16 @@ static void sbp2_remove_device(struct sbif (!lu)return ; - hi = lu->hi; +if (!hi) + goto no_hi;if (lu->shost) {scsi_remove_host (lu->shost);scsi_host_put (lu->shost); }flush_scheduled_work (); -sbp2util_remove_command_orb_pool (lu); +sbp2util_remove_command_orb_pool (lu, hi->host);list_del (&lu->lu_list);
@@ -971,9 +972,8 @@ static void sbp2_remove_device(struct sb lu->ud->device.driver_data =NULL ; -if (hi) -module_put (hi->host->driver->owner); - +module_put (hi->host->driver->owner); +no_hi:kfree (lu); }
Signature · 3 lines
Stefan Richter -=====-=-=== =--- -=-== http://arcgraph.de/sr/
PATCH 1/1 ieee1394: sbp2: fix unsafe iteration over list of devices
sbp2_host_reset and sbp2_handle_status_write are not serialized against sbp2_alloc_device and sbp2_remove_device.
--- drivers/ieee1394/sbp2.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
drivers/ieee1394/sbp2.c +15 -0
@@ -242,6 +242,8 @@ static int sbp2_max_speed_and_size(strucstatic const u8 sbp2_speedto_max_payload[] = {0x7 ,0x8 ,0x9 ,0xA ,0xB ,0xC }; +static DEFINE_RWLOCK (sbp2_hi_logical_units_lock); +static struct hpsb_highlevel sbp2_highlevel = { .name =SBP2_DEVICE_NAME , .host_reset = sbp2_host_reset,
@@ -732,6 +734,7 @@ static struct sbp2_lu *sbp2_alloc_devicestruct sbp2_fwhost_info *hi;struct Scsi_Host *shost =NULL ;struct sbp2_lu *lu =NULL ; +unsigned long flags; lu =kzalloc (sizeof (*lu),GFP_KERNEL );if (!lu) {
@@ -784,7 +787,9 @@ static struct sbp2_lu *sbp2_alloc_device lu->hi = hi; +write_lock_irqsave (&sbp2_hi_logical_units_lock, flags);list_add_tail (&lu->lu_list, &hi->logical_units); +write_unlock_irqrestore (&sbp2_hi_logical_units_lock, flags);/* Register the status FIFO address range. We could use the same FIFO * for targets at different nodes. However we need different FIFOs per
@@ -828,16 +833,20 @@ static void sbp2_host_reset(struct hpsb_ {struct sbp2_fwhost_info *hi;struct sbp2_lu *lu; +unsigned long flags; hi =hpsb_get_hostinfo (&sbp2_highlevel, host);if (!hi)return ; + +read_lock_irqsave (&sbp2_hi_logical_units_lock, flags);list_for_each_entry (lu, &hi->logical_units, lu_list)if (likely (atomic_read (&lu->state) !=SBP2LU_STATE_IN_SHUTDOWN )) {atomic_set (&lu->state,SBP2LU_STATE_IN_RESET );scsi_block_requests (lu->shost); } +read_unlock_irqrestore (&sbp2_hi_logical_units_lock, flags); }static int sbp2_start_device (struct sbp2_lu *lu)
@@ -919,6 +928,7 @@ alloc_fail:static void sbp2_remove_device (struct sbp2_lu *lu) {struct sbp2_fwhost_info *hi; +unsigned long flags;if (!lu)return ;
@@ -933,7 +943,9 @@ static void sbp2_remove_device(struct sbflush_scheduled_work ();sbp2util_remove_command_orb_pool (lu, hi->host); +write_lock_irqsave (&sbp2_hi_logical_units_lock, flags);list_del (&lu->lu_list); +write_unlock_irqrestore (&sbp2_hi_logical_units_lock, flags);if (lu->login_response) dma_free_coherent(hi->host->device.parent,
@@ -1707,6 +1719,7 @@ static int sbp2_handle_status_write(stru }/* Find the unit which wrote the status. */ +read_lock_irqsave (&sbp2_hi_logical_units_lock, flags);list_for_each_entry (lu_tmp, &hi->logical_units, lu_list) {if (lu_tmp->ne->nodeid == nodeid && lu_tmp->status_fifo_addr == addr) {
@@ -1714,6 +1727,8 @@ static int sbp2_handle_status_write(strubreak ; } } +read_unlock_irqrestore (&sbp2_hi_logical_units_lock, flags); +if (unlikely (!lu)) {SBP2_ERR ("lu is NULL - device is gone?" );return RCODE_ADDRESS_ERROR ;
Signature · 3 lines
Stefan Richter -=====-=-=== =--- -=-== http://arcgraph.de/sr/