aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen M. Cameron <scameron@beardog.cce.hp.com>2013-09-23 14:33:51 -0400
committerJames Bottomley <JBottomley@Parallels.com>2013-12-16 13:57:53 -0500
commite2d4a1f6b497e39d68775378960ad27be4f86250 (patch)
treeff624082307842cb4089d193b4a4e725fa699cca
parenta4af4606dbe959a09b2fc61da7052d5ba9b292f9 (diff)
[SCSI] hpsa: fix memory leak in CCISS_BIG_PASSTHRU ioctl
We were leaking a command buffer if a DMA mapping error was encountered in the CCISS_BIG_PASSTHRU ioctl. Signed-off-by: Stephen M. Cameron <scameron@beardog.cce.hp.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
-rw-r--r--drivers/scsi/hpsa.c11
1 files changed, 5 insertions, 6 deletions
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index bb3ee8fd2a3d..f12f55669cb3 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -3170,7 +3170,7 @@ static int hpsa_big_passthru_ioctl(struct ctlr_info *h, void __user *argp)
3170 hpsa_pci_unmap(h->pdev, c, i, 3170 hpsa_pci_unmap(h->pdev, c, i,
3171 PCI_DMA_BIDIRECTIONAL); 3171 PCI_DMA_BIDIRECTIONAL);
3172 status = -ENOMEM; 3172 status = -ENOMEM;
3173 goto cleanup1; 3173 goto cleanup0;
3174 } 3174 }
3175 c->SG[i].Addr.lower = temp64.val32.lower; 3175 c->SG[i].Addr.lower = temp64.val32.lower;
3176 c->SG[i].Addr.upper = temp64.val32.upper; 3176 c->SG[i].Addr.upper = temp64.val32.upper;
@@ -3186,24 +3186,23 @@ static int hpsa_big_passthru_ioctl(struct ctlr_info *h, void __user *argp)
3186 /* Copy the error information out */ 3186 /* Copy the error information out */
3187 memcpy(&ioc->error_info, c->err_info, sizeof(ioc->error_info)); 3187 memcpy(&ioc->error_info, c->err_info, sizeof(ioc->error_info));
3188 if (copy_to_user(argp, ioc, sizeof(*ioc))) { 3188 if (copy_to_user(argp, ioc, sizeof(*ioc))) {
3189 cmd_special_free(h, c);
3190 status = -EFAULT; 3189 status = -EFAULT;
3191 goto cleanup1; 3190 goto cleanup0;
3192 } 3191 }
3193 if (ioc->Request.Type.Direction == XFER_READ && ioc->buf_size > 0) { 3192 if (ioc->Request.Type.Direction == XFER_READ && ioc->buf_size > 0) {
3194 /* Copy the data out of the buffer we created */ 3193 /* Copy the data out of the buffer we created */
3195 BYTE __user *ptr = ioc->buf; 3194 BYTE __user *ptr = ioc->buf;
3196 for (i = 0; i < sg_used; i++) { 3195 for (i = 0; i < sg_used; i++) {
3197 if (copy_to_user(ptr, buff[i], buff_size[i])) { 3196 if (copy_to_user(ptr, buff[i], buff_size[i])) {
3198 cmd_special_free(h, c);
3199 status = -EFAULT; 3197 status = -EFAULT;
3200 goto cleanup1; 3198 goto cleanup0;
3201 } 3199 }
3202 ptr += buff_size[i]; 3200 ptr += buff_size[i];
3203 } 3201 }
3204 } 3202 }
3205 cmd_special_free(h, c);
3206 status = 0; 3203 status = 0;
3204cleanup0:
3205 cmd_special_free(h, c);
3207cleanup1: 3206cleanup1:
3208 if (buff) { 3207 if (buff) {
3209 for (i = 0; i < sg_used; i++) 3208 for (i = 0; i < sg_used; i++)