[SCSI] dpt_i2o: several use after free issues
adpt_i2o_delete_hba() calls kfree() so we have to save "pHba->next" before calling it. Also inside adpt_i2o_delete_hba() itself, there was another use after free bug which I fixed by moving the kfree() down a line. Signed-off-by: Dan Carpenter <error27@gmail.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
This commit is contained in:
parent
d620a7cf05
commit
229bab6bac
@ -188,7 +188,8 @@ MODULE_DEVICE_TABLE(pci,dptids);
|
|||||||
static int adpt_detect(struct scsi_host_template* sht)
|
static int adpt_detect(struct scsi_host_template* sht)
|
||||||
{
|
{
|
||||||
struct pci_dev *pDev = NULL;
|
struct pci_dev *pDev = NULL;
|
||||||
adpt_hba* pHba;
|
adpt_hba *pHba;
|
||||||
|
adpt_hba *next;
|
||||||
|
|
||||||
PINFO("Detecting Adaptec I2O RAID controllers...\n");
|
PINFO("Detecting Adaptec I2O RAID controllers...\n");
|
||||||
|
|
||||||
@ -206,7 +207,8 @@ static int adpt_detect(struct scsi_host_template* sht)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* In INIT state, Activate IOPs */
|
/* In INIT state, Activate IOPs */
|
||||||
for (pHba = hba_chain; pHba; pHba = pHba->next) {
|
for (pHba = hba_chain; pHba; pHba = next) {
|
||||||
|
next = pHba->next;
|
||||||
// Activate does get status , init outbound, and get hrt
|
// Activate does get status , init outbound, and get hrt
|
||||||
if (adpt_i2o_activate_hba(pHba) < 0) {
|
if (adpt_i2o_activate_hba(pHba) < 0) {
|
||||||
adpt_i2o_delete_hba(pHba);
|
adpt_i2o_delete_hba(pHba);
|
||||||
@ -243,7 +245,8 @@ rebuild_sys_tab:
|
|||||||
PDEBUG("HBA's in OPERATIONAL state\n");
|
PDEBUG("HBA's in OPERATIONAL state\n");
|
||||||
|
|
||||||
printk("dpti: If you have a lot of devices this could take a few minutes.\n");
|
printk("dpti: If you have a lot of devices this could take a few minutes.\n");
|
||||||
for (pHba = hba_chain; pHba; pHba = pHba->next) {
|
for (pHba = hba_chain; pHba; pHba = next) {
|
||||||
|
next = pHba->next;
|
||||||
printk(KERN_INFO"%s: Reading the hardware resource table.\n", pHba->name);
|
printk(KERN_INFO"%s: Reading the hardware resource table.\n", pHba->name);
|
||||||
if (adpt_i2o_lct_get(pHba) < 0){
|
if (adpt_i2o_lct_get(pHba) < 0){
|
||||||
adpt_i2o_delete_hba(pHba);
|
adpt_i2o_delete_hba(pHba);
|
||||||
@ -263,7 +266,8 @@ rebuild_sys_tab:
|
|||||||
adpt_sysfs_class = NULL;
|
adpt_sysfs_class = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (pHba = hba_chain; pHba; pHba = pHba->next) {
|
for (pHba = hba_chain; pHba; pHba = next) {
|
||||||
|
next = pHba->next;
|
||||||
if (adpt_scsi_host_alloc(pHba, sht) < 0){
|
if (adpt_scsi_host_alloc(pHba, sht) < 0){
|
||||||
adpt_i2o_delete_hba(pHba);
|
adpt_i2o_delete_hba(pHba);
|
||||||
continue;
|
continue;
|
||||||
@ -1229,11 +1233,10 @@ static void adpt_i2o_delete_hba(adpt_hba* pHba)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
pci_dev_put(pHba->pDev);
|
pci_dev_put(pHba->pDev);
|
||||||
kfree(pHba);
|
|
||||||
|
|
||||||
if (adpt_sysfs_class)
|
if (adpt_sysfs_class)
|
||||||
device_destroy(adpt_sysfs_class,
|
device_destroy(adpt_sysfs_class,
|
||||||
MKDEV(DPTI_I2O_MAJOR, pHba->unit));
|
MKDEV(DPTI_I2O_MAJOR, pHba->unit));
|
||||||
|
kfree(pHba);
|
||||||
|
|
||||||
if(hba_count <= 0){
|
if(hba_count <= 0){
|
||||||
unregister_chrdev(DPTI_I2O_MAJOR, DPT_DRIVER);
|
unregister_chrdev(DPTI_I2O_MAJOR, DPT_DRIVER);
|
||||||
|
Loading…
Reference in New Issue
Block a user