Commit 98c74837 authored by Kai Germaschewski's avatar Kai Germaschewski

ISDN: Fix bugs found by the Stanford checker

Unreversed allocations on the error path and the like.
parent 25cbbe6e
...@@ -148,7 +148,7 @@ static dev_link_t *avmcs_attach(void) ...@@ -148,7 +148,7 @@ static dev_link_t *avmcs_attach(void)
/* Initialize the dev_link_t structure */ /* Initialize the dev_link_t structure */
link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
if (!link) if (!link)
return NULL; goto err;
memset(link, 0, sizeof(struct dev_link_t)); memset(link, 0, sizeof(struct dev_link_t));
link->release.function = &avmcs_release; link->release.function = &avmcs_release;
link->release.data = (u_long)link; link->release.data = (u_long)link;
...@@ -181,7 +181,7 @@ static dev_link_t *avmcs_attach(void) ...@@ -181,7 +181,7 @@ static dev_link_t *avmcs_attach(void)
/* Allocate space for private device-specific data */ /* Allocate space for private device-specific data */
local = kmalloc(sizeof(local_info_t), GFP_KERNEL); local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
if (!local) if (!local)
return NULL; goto err_kfree;
memset(local, 0, sizeof(local_info_t)); memset(local, 0, sizeof(local_info_t));
link->priv = local; link->priv = local;
...@@ -201,10 +201,14 @@ static dev_link_t *avmcs_attach(void) ...@@ -201,10 +201,14 @@ static dev_link_t *avmcs_attach(void)
if (ret != 0) { if (ret != 0) {
cs_error(link->handle, RegisterClient, ret); cs_error(link->handle, RegisterClient, ret);
avmcs_detach(link); avmcs_detach(link);
return NULL; goto err;
} }
return link; return link;
err_kfree:
kfree(link);
err:
return NULL;
} /* avmcs_attach */ } /* avmcs_attach */
/*====================================================================== /*======================================================================
......
...@@ -819,34 +819,34 @@ icn_loadboot(u_char * buffer, icn_card * card) ...@@ -819,34 +819,34 @@ icn_loadboot(u_char * buffer, icn_card * card)
#endif #endif
if (!(codebuf = kmalloc(ICN_CODE_STAGE1, GFP_KERNEL))) { if (!(codebuf = kmalloc(ICN_CODE_STAGE1, GFP_KERNEL))) {
printk(KERN_WARNING "icn: Could not allocate code buffer\n"); printk(KERN_WARNING "icn: Could not allocate code buffer\n");
return -ENOMEM; ret = -ENOMEM;
goto out;
} }
if (copy_from_user(codebuf, buffer, ICN_CODE_STAGE1)) { if (copy_from_user(codebuf, buffer, ICN_CODE_STAGE1)) {
kfree(codebuf); ret = -EFAULT;
return -EFAULT; goto out_kfree;
} }
if (!card->rvalid) { if (!card->rvalid) {
if (check_region(card->port, ICN_PORTLEN)) { if (!request_region(card->port, ICN_PORTLEN, card->regname)) {
printk(KERN_WARNING printk(KERN_WARNING
"icn: (%s) ports 0x%03x-0x%03x in use.\n", "icn: (%s) ports 0x%03x-0x%03x in use.\n",
CID, CID,
card->port, card->port,
card->port + ICN_PORTLEN); card->port + ICN_PORTLEN);
kfree(codebuf); ret = -EBUSY;
return -EBUSY; goto out_kfree;
} }
request_region(card->port, ICN_PORTLEN, card->regname);
card->rvalid = 1; card->rvalid = 1;
if (card->doubleS0) if (card->doubleS0)
card->other->rvalid = 1; card->other->rvalid = 1;
} }
if (!dev.mvalid) { if (!dev.mvalid) {
if (check_mem_region(dev.memaddr, 0x4000)) { if (!request_mem_region(dev.memaddr, 0x4000, "icn-isdn (all cards)")) {
printk(KERN_WARNING printk(KERN_WARNING
"icn: memory at 0x%08lx in use.\n", dev.memaddr); "icn: memory at 0x%08lx in use.\n", dev.memaddr);
return -EBUSY; ret = -EBUSY;
goto out_kfree;
} }
request_mem_region(dev.memaddr, 0x4000, "icn-isdn (all cards)");
dev.shmem = ioremap(dev.memaddr, 0x4000); dev.shmem = ioremap(dev.memaddr, 0x4000);
dev.mvalid = 1; dev.mvalid = 1;
} }
...@@ -888,13 +888,15 @@ icn_loadboot(u_char * buffer, icn_card * card) ...@@ -888,13 +888,15 @@ icn_loadboot(u_char * buffer, icn_card * card)
printk(KERN_DEBUG "Bootloader transferred\n"); printk(KERN_DEBUG "Bootloader transferred\n");
#endif #endif
} }
kfree(codebuf);
SLEEP(1); SLEEP(1);
OUTB_P(0xff, ICN_RUN); /* Start Boot-Code */ OUTB_P(0xff, ICN_RUN); /* Start Boot-Code */
if ((ret = icn_check_loader(card->doubleS0 ? 2 : 1))) if ((ret = icn_check_loader(card->doubleS0 ? 2 : 1))) {
return ret; goto out_kfree;
if (!card->doubleS0) }
return 0; if (!card->doubleS0) {
ret = 0;
goto out_kfree;
}
/* reached only, if we have a Double-S0-Card */ /* reached only, if we have a Double-S0-Card */
#ifdef BOOT_DEBUG #ifdef BOOT_DEBUG
printk(KERN_DEBUG "Map Bank 0\n"); printk(KERN_DEBUG "Map Bank 0\n");
...@@ -905,7 +907,12 @@ icn_loadboot(u_char * buffer, icn_card * card) ...@@ -905,7 +907,12 @@ icn_loadboot(u_char * buffer, icn_card * card)
icn_lock_channel(card, 0); /* Lock Bank 0 */ icn_lock_channel(card, 0); /* Lock Bank 0 */
restore_flags(flags); restore_flags(flags);
SLEEP(1); SLEEP(1);
return (icn_check_loader(1)); ret = (icn_check_loader(1));
out_kfree:
kfree(codebuf);
out:
return ret;
} }
static int static int
......
...@@ -261,39 +261,6 @@ static int __init sc_init(void) ...@@ -261,39 +261,6 @@ static int __init sc_init(void)
} }
pr_debug("current IRQ: %d b: %d\n",irq[b],b); pr_debug("current IRQ: %d b: %d\n",irq[b],b);
/*
* See if we should probe for an irq
*/
if(irq[b]) {
/*
* No we were given one
* See that it is supported and free
*/
pr_debug("Trying for IRQ: %d\n",irq[b]);
if (irq_supported(irq[b])) {
if(REQUEST_IRQ(irq[b], interrupt_handler,
SA_PROBE, "sc_probe", NULL)) {
pr_debug("IRQ %d is already in use\n",
irq[b]);
continue;
}
FREE_IRQ(irq[b], NULL);
}
}
else {
/*
* Yes, we need to probe for an IRQ
*/
pr_debug("Probing for IRQ...\n");
for (i = 0; i < MAX_IRQS ; i++) {
if(!REQUEST_IRQ(sup_irq[i], interrupt_handler, SA_PROBE, "sc_probe", NULL)) {
pr_debug("Probed for and found IRQ %d\n", sup_irq[i]);
FREE_IRQ(sup_irq[i], NULL);
irq[b] = sup_irq[i];
break;
}
}
}
/* /*
* Make sure we got an IRQ * Make sure we got an IRQ
...@@ -379,8 +346,16 @@ static int __init sc_init(void) ...@@ -379,8 +346,16 @@ static int __init sc_init(void)
* Lock down the hardware resources * Lock down the hardware resources
*/ */
adapter[cinst]->interrupt = irq[b]; adapter[cinst]->interrupt = irq[b];
REQUEST_IRQ(adapter[cinst]->interrupt, interrupt_handler, SA_INTERRUPT, if (request_irq(adapter[cinst]->interrupt, interrupt_handler, SA_INTERRUPT,
interface->id, NULL); interface->id, NULL))
{
kfree(adapter[cinst]->channel);
indicate_status(cinst, ISDN_STAT_UNLOAD, 0, NULL); /* Fix me */
kfree(interface);
kfree(adapter[cinst]);
continue;
}
adapter[cinst]->iobase = io[b]; adapter[cinst]->iobase = io[b];
for(i = 0 ; i < MAX_IO_REGS - 1 ; i++) { for(i = 0 ; i < MAX_IO_REGS - 1 ; i++) {
adapter[cinst]->ioport[i] = io[b] + i * 0x400; adapter[cinst]->ioport[i] = io[b] + i * 0x400;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment