rpms/kernel/devel kernel.spec, 1.453, 1.454 linux-2.6-firewire-git-pending.patch, 1.6, 1.7

Jarod Wilson (jwilson) fedora-extras-commits at redhat.com
Wed Feb 27 04:42:18 UTC 2008


Author: jwilson

Update of /cvs/pkgs/rpms/kernel/devel
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv6812

Modified Files:
	kernel.spec linux-2.6-firewire-git-pending.patch 
Log Message:
* Tue Feb 26 2008 Jarod Wilson <jwilson at redhat.com>
- firewire-sbp2: fix refcounting bug that prevented module unload



Index: kernel.spec
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/kernel.spec,v
retrieving revision 1.453
retrieving revision 1.454
diff -u -r1.453 -r1.454
--- kernel.spec	26 Feb 2008 20:33:43 -0000	1.453
+++ kernel.spec	27 Feb 2008 04:41:28 -0000	1.454
@@ -1733,6 +1733,9 @@
 %kernel_variant_files -a /%{image_install_path}/xen*-%{KVERREL} -e /etc/ld.so.conf.d/kernelcap-%{KVERREL}.conf %{with_xen} xen
 
 %changelog
+* Tue Feb 26 2008 Jarod Wilson <jwilson at redhat.com>
+- firewire-sbp2: fix refcounting bug that prevented module unload
+
 * Tue Feb 26 2008 Dave Jones <davej at redhat.com>
 - 2.6.25-rc3-git1
 

linux-2.6-firewire-git-pending.patch:

Index: linux-2.6-firewire-git-pending.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/linux-2.6-firewire-git-pending.patch,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- linux-2.6-firewire-git-pending.patch	25 Feb 2008 22:32:56 -0000	1.6
+++ linux-2.6-firewire-git-pending.patch	27 Feb 2008 04:41:28 -0000	1.7
@@ -132,6 +132,156 @@
 http://arcgraph.de/sr/
 
 
+Patch "firewire: fw-sbp2: fix NULL pointer deref. in scsi_remove_device"
+had the unintended effect that firewire-sbp2 could not be unloaded
+anymore until all SBP-2 devices were unplugged.
+
+We now fix the NULL pointer bug by reacquiring a reference to the sdev
+instead of holding a reference to the sdev (and to the module) all the
+time.
+
+Signed-off-by: Stefan Richter <stefanr at s5r6.in-berlin.de>
+---
+
+This applies on top of current linux-2.6.git master as well as on top of
+linux1394-2.6.git master.
+
+
+ drivers/firewire/fw-sbp2.c |   46 +++++++++++++++++++++----------------
+ 1 file changed, 27 insertions(+), 19 deletions(-)
+
+Index: linux/drivers/firewire/fw-sbp2.c
+===================================================================
+--- linux.orig/drivers/firewire/fw-sbp2.c
++++ linux/drivers/firewire/fw-sbp2.c
+@@ -122,7 +122,6 @@ static const char sbp2_driver_name[] = "
+ struct sbp2_logical_unit {
+ 	struct sbp2_target *tgt;
+ 	struct list_head link;
+-	struct scsi_device *sdev;
+ 	struct fw_address_handler address_handler;
+ 	struct list_head orb_list;
+ 
+@@ -139,6 +138,7 @@ struct sbp2_logical_unit {
+ 	int generation;
+ 	int retries;
+ 	struct delayed_work work;
++	bool has_sdev;
+ 	bool blocked;
+ };
+ 
+@@ -751,20 +751,33 @@ static void sbp2_unblock(struct sbp2_tar
+ 	scsi_unblock_requests(shost);
+ }
+ 
++static int sbp2_lun2int(u16 lun)
++{
++	struct scsi_lun eight_bytes_lun;
++
++	memset(&eight_bytes_lun, 0, sizeof(eight_bytes_lun));
++	eight_bytes_lun.scsi_lun[0] = (lun >> 8) & 0xff;
++	eight_bytes_lun.scsi_lun[1] = lun & 0xff;
++
++	return scsilun_to_int(&eight_bytes_lun);
++}
++
+ static void sbp2_release_target(struct kref *kref)
+ {
+ 	struct sbp2_target *tgt = container_of(kref, struct sbp2_target, kref);
+ 	struct sbp2_logical_unit *lu, *next;
+ 	struct Scsi_Host *shost =
+ 		container_of((void *)tgt, struct Scsi_Host, hostdata[0]);
++	struct scsi_device *sdev;
+ 
+ 	/* prevent deadlocks */
+ 	sbp2_unblock(tgt);
+ 
+ 	list_for_each_entry_safe(lu, next, &tgt->lu_list, link) {
+-		if (lu->sdev) {
+-			scsi_remove_device(lu->sdev);
+-			scsi_device_put(lu->sdev);
++		sdev = scsi_device_lookup(shost, 0, 0, sbp2_lun2int(lu->lun));
++		if (sdev) {
++			scsi_remove_device(sdev);
++			scsi_device_put(sdev);
+ 		}
+ 		sbp2_send_management_orb(lu, tgt->node_id, lu->generation,
+ 				SBP2_LOGOUT_REQUEST, lu->login_id, NULL);
+@@ -807,7 +820,6 @@ static void sbp2_login(struct work_struc
+ 	struct fw_device *device = fw_device(tgt->unit->device.parent);
+ 	struct Scsi_Host *shost;
+ 	struct scsi_device *sdev;
+-	struct scsi_lun eight_bytes_lun;
+ 	struct sbp2_login_response response;
+ 	int generation, node_id, local_node_id;
+ 
+@@ -820,7 +832,7 @@ static void sbp2_login(struct work_struc
+ 	local_node_id = device->card->node_id;
+ 
+ 	/* If this is a re-login attempt, log out, or we might be rejected. */
+-	if (lu->sdev)
++	if (lu->has_sdev)
+ 		sbp2_send_management_orb(lu, device->node_id, generation,
+ 				SBP2_LOGOUT_REQUEST, lu->login_id, NULL);
+ 
+@@ -859,7 +871,7 @@ static void sbp2_login(struct work_struc
+ 	sbp2_agent_reset(lu);
+ 
+ 	/* This was a re-login. */
+-	if (lu->sdev) {
++	if (lu->has_sdev) {
+ 		sbp2_cancel_orbs(lu);
+ 		sbp2_conditionally_unblock(lu);
+ 		goto out;
+@@ -868,13 +880,8 @@ static void sbp2_login(struct work_struc
+ 	if (lu->tgt->workarounds & SBP2_WORKAROUND_DELAY_INQUIRY)
+ 		ssleep(SBP2_INQUIRY_DELAY);
+ 
+-	memset(&eight_bytes_lun, 0, sizeof(eight_bytes_lun));
+-	eight_bytes_lun.scsi_lun[0] = (lu->lun >> 8) & 0xff;
+-	eight_bytes_lun.scsi_lun[1] = lu->lun & 0xff;
+ 	shost = container_of((void *)tgt, struct Scsi_Host, hostdata[0]);
+-
+-	sdev = __scsi_add_device(shost, 0, 0,
+-				 scsilun_to_int(&eight_bytes_lun), lu);
++	sdev = __scsi_add_device(shost, 0, 0, sbp2_lun2int(lu->lun), lu);
+ 	/*
+ 	 * FIXME:  We are unable to perform reconnects while in sbp2_login().
+ 	 * Therefore __scsi_add_device() will get into trouble if a bus reset
+@@ -896,7 +903,8 @@ static void sbp2_login(struct work_struc
+ 	}
+ 
+ 	/* No error during __scsi_add_device() */
+-	lu->sdev = sdev;
++	lu->has_sdev = true;
++	scsi_device_put(sdev);
+ 	sbp2_allow_block(lu);
+ 	goto out;
+ 
+@@ -934,11 +942,11 @@ static int sbp2_add_logical_unit(struct 
+ 		return -ENOMEM;
+ 	}
+ 
+-	lu->tgt  = tgt;
+-	lu->sdev = NULL;
+-	lu->lun  = lun_entry & 0xffff;
+-	lu->retries = 0;
+-	lu->blocked = false;
++	lu->tgt      = tgt;
++	lu->lun      = lun_entry & 0xffff;
++	lu->retries  = 0;
++	lu->has_sdev = false;
++	lu->blocked  = false;
+ 	++tgt->dont_block;
+ 	INIT_LIST_HEAD(&lu->orb_list);
+ 	INIT_DELAYED_WORK(&lu->work, sbp2_login);
+
+-- 
+Stefan Richter
+-=====-==--- --=- ==-=-
+http://arcgraph.de/sr/
+
+
 The bus management workqueue job was in danger to dereference NULL
 pointers.  Also, after having temporarily lifted card->lock, a few node
 pointers and a device pointer may have become invalid.
@@ -370,12 +520,17 @@
 
 Signed-off-by: Stefan Richter <stefanr at s5r6.in-berlin.de>
 ---
+
+Update:  Refreshed to be applicable after patch "firewire: fw-sbp2:
+better fix for NULL pointer dereference in scsi_remove_device".
+
+
  drivers/firewire/fw-card.c        |   10 +++++++++-
  drivers/firewire/fw-device.c      |   21 ++++++---------------
  drivers/firewire/fw-device.h      |   16 ++++++++++++++--
- drivers/firewire/fw-sbp2.c        |    4 ++++
+ drivers/firewire/fw-sbp2.c        |    3 +++
  drivers/firewire/fw-transaction.h |    2 ++
- 5 files changed, 35 insertions(+), 18 deletions(-)
+ 5 files changed, 34 insertions(+), 18 deletions(-)
 
 Index: linux/drivers/firewire/fw-card.c
 ===================================================================
@@ -475,23 +630,15 @@
 ===================================================================
 --- linux.orig/drivers/firewire/fw-sbp2.c
 +++ linux/drivers/firewire/fw-sbp2.c
-@@ -757,6 +757,7 @@ static void sbp2_release_target(struct k
- 	struct sbp2_logical_unit *lu, *next;
- 	struct Scsi_Host *shost =
- 		container_of((void *)tgt, struct Scsi_Host, hostdata[0]);
-+	struct fw_device *device = fw_device(tgt->unit->device.parent);
- 
- 	/* prevent deadlocks */
- 	sbp2_unblock(tgt);
-@@ -778,6 +779,7 @@ static void sbp2_release_target(struct k
+@@ -791,6 +791,7 @@ static void sbp2_release_target(struct k
  
  	put_device(&tgt->unit->device);
  	scsi_host_put(shost);
-+	fw_device_put(device);
++	fw_device_put(fw_device(tgt->unit->device.parent));
  }
  
  static struct workqueue_struct *sbp2_wq;
-@@ -1080,6 +1082,8 @@ static int sbp2_probe(struct device *dev
+@@ -1088,6 +1089,8 @@ static int sbp2_probe(struct device *dev
  	if (scsi_add_host(shost, &unit->device) < 0)
  		goto fail_shost_put;
  
@@ -551,7 +698,7 @@
 
 -- 
 Stefan Richter
--=====-==--- --=- ==---
+-=====-==--- --=- ==-=-
 http://arcgraph.de/sr/
 
 
@@ -805,16 +952,16 @@
 ===================================================================
 --- linux.orig/drivers/firewire/fw-sbp2.c
 +++ linux/drivers/firewire/fw-sbp2.c
-@@ -777,7 +777,7 @@ static void sbp2_release_target(struct k
+@@ -789,7 +789,7 @@ static void sbp2_release_target(struct k
  	scsi_remove_host(shost);
  	fw_notify("released %s\n", tgt->bus_id);
  
 -	put_device(&tgt->unit->device);
 +	fw_unit_put(tgt->unit);
  	scsi_host_put(shost);
- 	fw_device_put(device);
+ 	fw_device_put(fw_device(tgt->unit->device.parent));
  }
-@@ -1083,7 +1083,7 @@ static int sbp2_probe(struct device *dev
+@@ -1090,7 +1090,7 @@ static int sbp2_probe(struct device *dev
  		goto fail_shost_put;
  
  	fw_device_get(device);
@@ -823,10 +970,3 @@
  
  	/* Initialize to values that won't match anything in our table. */
  	firmware_revision = 0xff000000;
-
--- 
-Stefan Richter
--=====-==--- --=- ==---
-http://arcgraph.de/sr/
-
-




More information about the fedora-extras-commits mailing list