From 07fb75a50600c0c480b40c6d11dbc993f21bc2bc Mon Sep 17 00:00:00 2001 From: Jesper Juhl <jesper.juhl@gmail.com> Date: Sun, 14 May 2006 00:39:38 +0200 Subject: [SCSI] fix (unlikely) memory leak in DAC960 driver The Coverity checker found a memory leak (bug nr. 1245) in drivers/block/DAC960.c::DAC960_V2_ProcessCompletedCommand() The leak is pretty unlikely since it requires that the first of two successive kmalloc() calls fail while the second one succeeds. But it can still happen even if it's unlikely. If the first call that allocates 'PhysicalDeviceInfo' fails but the one that allocates 'InquiryUnitSerialNumber' succeeds, then we will leak the memory allocated to 'InquiryUnitSerialNumber' when the variable goes out of scope. A simple fix for this is to change the existing code that frees 'PhysicalDeviceInfo' if that one was allocated but 'InquiryUnitSerialNumber' was not, into a check for either pointer being NULL and if so just free both. This is safe since kfree() can deal with being passed a NULL pointer and it avoids the leak. While I was there I also removed the casts of the kmalloc() return value since it's pointless. I also updated the driver version since this patch changes the workings of the code (however slightly). This issue could probably be fixed a lot more elegantly, but the code is a big mess IMHO and I just took the least intrusive route to a fix that I could find instead of starting on a cleanup as well (that can come later). Please consider for inclusion. Signed-off-by: Jesper Juhl <jesper.juhl@gmail.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com> --- drivers/block/DAC960.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c index 45bcda54488..dd8a1501142 100644 --- a/drivers/block/DAC960.c +++ b/drivers/block/DAC960.c @@ -17,8 +17,8 @@ */ -#define DAC960_DriverVersion "2.5.47" -#define DAC960_DriverDate "14 November 2002" +#define DAC960_DriverVersion "2.5.48" +#define DAC960_DriverDate "14 May 2006" #include <linux/module.h> @@ -4780,15 +4780,16 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command) (NewPhysicalDeviceInfo->LogicalUnit != PhysicalDeviceInfo->LogicalUnit)) { - PhysicalDeviceInfo = (DAC960_V2_PhysicalDeviceInfo_T *) + PhysicalDeviceInfo = kmalloc(sizeof(DAC960_V2_PhysicalDeviceInfo_T), GFP_ATOMIC); InquiryUnitSerialNumber = - (DAC960_SCSI_Inquiry_UnitSerialNumber_T *) kmalloc(sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T), GFP_ATOMIC); - if (InquiryUnitSerialNumber == NULL && - PhysicalDeviceInfo != NULL) + if (InquiryUnitSerialNumber == NULL || + PhysicalDeviceInfo == NULL) { + kfree(InquiryUnitSerialNumber); + InquiryUnitSerialNumber = NULL; kfree(PhysicalDeviceInfo); PhysicalDeviceInfo = NULL; } -- cgit v1.2.3-18-g5258 From 5d5ff44fe6775ccb922fd1f7d478b2ba9ca95068 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig <hch@lst.de> Date: Sat, 3 Jun 2006 13:21:13 +0200 Subject: [SCSI] fix up request buffer reference in various scsi drivers Various scsi drivers use scsi_cmnd.buffer and scsi_cmnd.bufflen in their queuecommand functions. Those fields are internal storage for the midlayer only and are used to restore the original payload after request_buffer and request_bufflen have been overwritten for EH. Using the buffer and bufflen fields means they do very broken things in error handling. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com> --- drivers/block/cciss_scsi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/block') diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c index 597c007fe81..afdff32f672 100644 --- a/drivers/block/cciss_scsi.c +++ b/drivers/block/cciss_scsi.c @@ -578,7 +578,7 @@ complete_scsi_command( CommandList_struct *cp, int timeout, __u32 tag) if (cmd->use_sg) { pci_unmap_sg(ctlr->pdev, - cmd->buffer, cmd->use_sg, + cmd->request_buffer, cmd->use_sg, cmd->sc_data_direction); } else if (cmd->request_bufflen) { @@ -1210,7 +1210,7 @@ cciss_scatter_gather(struct pci_dev *pdev, struct scsi_cmnd *cmd) { unsigned int use_sg, nsegs=0, len; - struct scatterlist *scatter = (struct scatterlist *) cmd->buffer; + struct scatterlist *scatter = (struct scatterlist *) cmd->request_buffer; __u64 addr64; /* is it just one virtual address? */ @@ -1232,7 +1232,7 @@ cciss_scatter_gather(struct pci_dev *pdev, } /* else, must be a list of virtual addresses.... */ else if (cmd->use_sg <= MAXSGENTRIES) { /* not too many addrs? */ - use_sg = pci_map_sg(pdev, cmd->buffer, cmd->use_sg, + use_sg = pci_map_sg(pdev, cmd->request_buffer, cmd->use_sg, cmd->sc_data_direction); for (nsegs=0; nsegs < use_sg; nsegs++) { -- cgit v1.2.3-18-g5258