aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/sg.c
diff options
context:
space:
mode:
authorIshai Rabinovitz <ishai@mellanox.co.il>2006-06-29 09:39:54 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-06-30 22:28:35 -0400
commit454e8957eb60841016deb319dbbf83042fb32a39 (patch)
tree0b638af6bd2ac0083e244d228adfd12a8f6b4585 /drivers/scsi/sg.c
parent0f13fc09db68de92585558984bff1c51b87db72f (diff)
[SCSI] sg.c: Fix bad error handling in
I got a NULL derefrence in cdev_del+1 when called from sg_remove. By looking at the code of sg_add, sg_alloc and sg_remove (all in drivers/scsi/sg.c) I found out that sg_add is calling sg_alloc but if it fails afterwards it does not deallocate the space that was allocated in sg_alloc and the redundant entry has NULL in cdev. When sg_remove is being called, it tries to perform cdev_del to this NULL cdev and fails. Signed-off-by: Ishai Rabinovitz <ishai@mellanox.co.il> Acked-by: Douglas Gilbert <dougg@torque.net> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/sg.c')
-rw-r--r--drivers/scsi/sg.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 98b9312ba8da..d5bbb97bb74b 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -1402,6 +1402,7 @@ sg_add(struct class_device *cl_dev, struct class_interface *cl_intf)
1402 Sg_device *sdp = NULL; 1402 Sg_device *sdp = NULL;
1403 struct cdev * cdev = NULL; 1403 struct cdev * cdev = NULL;
1404 int error, k; 1404 int error, k;
1405 unsigned long iflags;
1405 1406
1406 disk = alloc_disk(1); 1407 disk = alloc_disk(1);
1407 if (!disk) { 1408 if (!disk) {
@@ -1429,7 +1430,7 @@ sg_add(struct class_device *cl_dev, struct class_interface *cl_intf)
1429 1430
1430 error = cdev_add(cdev, MKDEV(SCSI_GENERIC_MAJOR, k), 1); 1431 error = cdev_add(cdev, MKDEV(SCSI_GENERIC_MAJOR, k), 1);
1431 if (error) 1432 if (error)
1432 goto out; 1433 goto cdev_add_err;
1433 1434
1434 sdp->cdev = cdev; 1435 sdp->cdev = cdev;
1435 if (sg_sysfs_valid) { 1436 if (sg_sysfs_valid) {
@@ -1456,6 +1457,13 @@ sg_add(struct class_device *cl_dev, struct class_interface *cl_intf)
1456 1457
1457 return 0; 1458 return 0;
1458 1459
1460cdev_add_err:
1461 write_lock_irqsave(&sg_dev_arr_lock, iflags);
1462 kfree(sg_dev_arr[k]);
1463 sg_dev_arr[k] = NULL;
1464 sg_nr_dev--;
1465 write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
1466
1459out: 1467out:
1460 put_disk(disk); 1468 put_disk(disk);
1461 if (cdev) 1469 if (cdev)