summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/st.c
diff options
context:
space:
mode:
authorMaurizio Lombardi <mlombard@redhat.com>2015-11-18 15:32:44 +0100
committerMartin K. Petersen <martin.petersen@oracle.com>2015-11-19 12:12:42 -0500
commitab08ee14393724ab52b92be643d588d41a1a05be (patch)
tree4d3f3d7c38ad4f9d178a2c15abedb84480ecdcb0 /drivers/scsi/st.c
parenta35bb4458e5e5c9dc19a0daa0629409285f3b25e (diff)
downloadlinux-ab08ee14393724ab52b92be643d588d41a1a05be.tar.gz
linux-ab08ee14393724ab52b92be643d588d41a1a05be.tar.bz2
linux-ab08ee14393724ab52b92be643d588d41a1a05be.zip
st: fix potential null pointer dereference.
If cdev_add() returns an error, the code calls cdev_del() passing the STm->cdevs[rew] pointer as parameter; the problem is that the pointer has not been initialized yet. This patch fixes the problem by moving the STm->cdevs[rew] pointer initialization before the call to cdev_add(). It also sets STm->devs[rew] and STm->cdevs[rew] to NULL in case of failure. Signed-off-by: Maurizio Lombardi <mlombard@redhat.com> Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de> Reviewed-by: Tomas Henzl <thenzl@redhat.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/st.c')
-rw-r--r--drivers/scsi/st.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index b37b9b00c4b4..3e79c80bf6c6 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -4083,6 +4083,7 @@ static int create_one_cdev(struct scsi_tape *tape, int mode, int rew)
}
cdev->owner = THIS_MODULE;
cdev->ops = &st_fops;
+ STm->cdevs[rew] = cdev;
error = cdev_add(cdev, cdev_devno, 1);
if (error) {
@@ -4091,7 +4092,6 @@ static int create_one_cdev(struct scsi_tape *tape, int mode, int rew)
pr_err("st%d: Device not attached.\n", dev_num);
goto out_free;
}
- STm->cdevs[rew] = cdev;
i = mode << (4 - ST_NBR_MODE_BITS);
snprintf(name, 10, "%s%s%s", rew ? "n" : "",
@@ -4110,8 +4110,9 @@ static int create_one_cdev(struct scsi_tape *tape, int mode, int rew)
return 0;
out_free:
cdev_del(STm->cdevs[rew]);
- STm->cdevs[rew] = NULL;
out:
+ STm->cdevs[rew] = NULL;
+ STm->devs[rew] = NULL;
return error;
}