lkml.org 
[lkml]   [2004]   [May]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
Subject[CHECKER] Resource leaks in driver shutdown functions
From
When device drivers have constructor (ctor) functions that allocate
resources, those resources must be freed in the corresponding destructor
(dtor) functions. What I've done is pair ctor/dtor functions where I
could in the drivers (i.e. init/shutdown, open/close, attach/detach, etc.)
and then found functions like request_irq/free_irq that should be paired
within those ctor/dtor pairs. Any dtor that doesn't free a resource
allocated in the ctor is marked as an error. The resource allocation line
numbers are given in the error messages.

The resource allocation/freeing functions in question below are:
irq_request/free_irq
netif_start_queue/netif_stop_queue
kmalloc/kfree
ei_open/ei_close
netif_device_attach/netif_device_detach
parport_register_device/parport_unregister_device

If these functions do not always need to be paired, I would appreciate an
explanation.

This is an experimental checker, so be warned that these reports are not
necessarily valid.

If you are CC'd on this email, it is because I think you are the
maintainer for some of the code below. Search for your email address
below to find it.

Thanks for your feedback,
Ken Ashcraft

# Total = 14
# BUGs | File Name
1 | /drivers/acpi/thermal.c
1 | /drivers/usb/serial/ir-usb.c
1 | /drivers/net/wireless/wl3501_cs.c
1 | /drivers/net/sis900.c
1 | /drivers/net/ns83820.c
1 | /drivers/net/smc-ultra32.c
1 | /drivers/net/tokenring/lanstreamer.c
1 | /drivers/net/hamradio/hdlcdrv.c
1 | /drivers/net/plip.c
1 | /drivers/net/smc-mca.c
1 | /drivers/net/smc-ultra.c
1 | /drivers/bluetooth/hci_vhci.c
1 | /drivers/net/ibmlana.c
1 | /drivers/net/rcpci45.c
---------------------------------------------------------
[BUG] Pete Popov and Brian Moyle, ported by Alan Cox
/home/kash/linux/2.6.3/linux-2.6.3/drivers/net/rcpci45.c:731:RCclose:ERROR:INTERFACE_A_B:
Not calling free_irq. See RCopen:339 [COUNTER=request_irq-free_irq]
[fit=1] [fit_fn=2] [fn_ex=0] [fn_counter=1] [ex=97] [counter=2] [z =
4.47241827790349] [fn-z = -2]
} else
printk (KERN_WARNING "%s: unexpected timer irq\n", dev->name);
}

static int

Error --->
RCclose (struct net_device *dev)
{
PDPA pDpa = dev->priv;

---------------------------------------------------------
[BUG] linux-ns83820@kvack.org
/home/kash/linux/2.6.3/linux-2.6.3/drivers/net/ns83820.c:1385:ns83820_stop:ERROR:INTERFACE_A_B:
Not calling netif_stop_queue. See ns83820_open:1507
[COUNTER=netif_start_queue-netif_stop_queue] [fit=2] [fit_fn=3] [fn_ex=0]
[fn_counter=1] [ex=99] [counter=5] [z = 3.87329366897913] [fn-z = -2]
schedule();
} while (readl(dev->base + CR) & which);
Dprintk("okay!\n");
}


Error --->
static int ns83820_stop(struct net_device *ndev)
{
struct ns83820 *dev = PRIV(ndev);

---------------------------------------------------------
[BUG] alfred@ccac.rwth-aachen.de, aarnold@elsa.de
/home/kash/linux/2.6.3/linux-2.6.3/drivers/net/ibmlana.c:799:ibmlana_close:ERROR:INTERFACE_A_B:
Not calling netif_stop_queue. See ibmlana_open:793
[COUNTER=netif_start_queue-netif_stop_queue] [fit=2] [fit_fn=4] [fn_ex=0]
[fn_counter=1] [ex=99] [counter=5] [z = 3.87329366897913] [fn-z = -2]
return 0;
}

/* close driver. Shut down board and free allocated resources */


Error --->
static int ibmlana_close(struct net_device *dev)
{
/* turn off board */

---------------------------------------------------------
[BUG] sailer@ife.ee.ethz.ch
/home/kash/linux/2.6.3/linux-2.6.3/drivers/net/hamradio/hdlcdrv.c:582:hdlcdrv_close:ERROR:INTERFACE_A_B:
Not calling netif_stop_queue. See hdlcdrv_open:573
[COUNTER=netif_start_queue-netif_stop_queue] [fit=2] [fit_fn=5] [fn_ex=0]
[fn_counter=1] [ex=99] [counter=5] [z = 3.87329366897913] [fn-z = -2]
/* --------------------------------------------------------------------- */
/*
* The inverse routine to hdlcdrv_open().
*/


Error --->
static int hdlcdrv_close(struct net_device *dev)
{
struct hdlcdrv_state *s;
int i = 0;
---------------------------------------------------------
[BUG]
/home/kash/linux/2.6.3/linux-2.6.3/drivers/usb/serial/ir-usb.c:329:ir_close:ERROR:INTERFACE_A_B:
Not calling kfree. See ir_open:293 [COUNTER=kmalloc-kfree] [fit=3]
[fit_fn=2] [fn_ex=0] [fn_counter=1] [ex=105] [counter=13] [z =
2.43952273743055] [fn-z = -2]
dev_err(&port->dev, "%s - failed submitting read urb, error %d\n",
__FUNCTION__, result);

return result;
}


Error --->
static void ir_close (struct usb_serial_port *port, struct file * filp)
{
struct usb_serial *serial;

---------------------------------------------------------
[BUG] maxk@qualcomm.com looks like a leak of private_data
/home/kash/linux/2.6.3/linux-2.6.3/drivers/bluetooth/hci_vhci.c:300:hci_vhci_chr_close:ERROR:INTERFACE_A_B:
Not calling kfree. See hci_vhci_chr_open:269 [COUNTER=kmalloc-kfree]
[fit=3] [fit_fn=1] [fn_ex=0] [fn_counter=1] [ex=105] [counter=13] [z =
2.43952273743055] [fn-z = -2]

file->private_data = hci_vhci;
return 0;
}


Error --->
static int hci_vhci_chr_close(struct inode *inode, struct file *file)
{
struct hci_vhci_struct *hci_vhci = (struct hci_vhci_struct *)
file->private_data;

---------------------------------------------------------
[BUG] streamer_open has a bunch of memory leaks on error paths too
/home/kash/linux/2.6.3/linux-2.6.3/drivers/net/tokenring/lanstreamer.c:1202:streamer_close:ERROR:INTERFACE_A_B:
Not calling kfree. See streamer_open:774 [COUNTER=kmalloc-kfree] [fit=3]
[fit_fn=10] [fn_ex=0] [fn_counter=1] [ex=105] [counter=13] [z =
2.43952273743055] [fn-z = -2]
return 1;
}
}



Error --->
static int streamer_close(struct net_device *dev)
{
struct streamer_private *streamer_priv =
(struct streamer_private *) dev->priv;
---------------------------------------------------------
[BUG] andrew.grover@intel.com, paul.s.diefenbaugh@intel.com
/home/kash/linux/2.6.3/linux-2.6.3/drivers/acpi/thermal.c:1290:acpi_thermal_remove:ERROR:INTERFACE_A_B:
Not calling kfree. See acpi_thermal_add:1243 [COUNTER=kmalloc-kfree]
[fit=3] [fit_fn=7] [fn_ex=0] [fn_counter=1] [ex=105] [counter=13] [z =
2.43952273743055] [fn-z = -2]
return_VALUE(result);
}


static int

Error --->
acpi_thermal_remove (
struct acpi_device *device,
int type)
{
---------------------------------------------------------
[BUG] webvenza@libero.it
/home/kash/linux/2.6.3/linux-2.6.3/drivers/net/sis900.c:2191:sis900_suspend:ERROR:INTERFACE_A_B:
Not calling netif_device_detach. See sis900_resume:2229
[COUNTER=netif_device_attach-netif_device_detach] [fit=4] [fit_fn=2]
[fn_ex=0] [fn_counter=1] [ex=18] [counter=2] [z = 1.11803398874989] [fn-z
= -2]
pci_set_drvdata(pci_dev, NULL);
}

#ifdef CONFIG_PM


Error --->
static int sis900_suspend(struct pci_dev *pci_dev, u32 state)
{
struct net_device *net_dev = pci_get_drvdata(pci_dev);
struct sis900_private *sis_priv = net_dev->priv;
---------------------------------------------------------
[BUG] acme@conectiva.com.br, niemeyer@conectiva.com
/home/kash/linux/2.6.3/linux-2.6.3/drivers/net/wireless/wl3501_cs.c:1286:wl3501_close:ERROR:INTERFACE_A_B:
Not calling netif_device_detach. See wl3501_open:1423
[COUNTER=netif_device_attach-netif_device_detach] [fit=4] [fit_fn=1]
[fn_ex=0] [fn_counter=1] [ex=18] [counter=2] [z = 1.11803398874989] [fn-z
= -2]
fail:
printk(KERN_WARNING "%s: failed!\n", __FUNCTION__);
goto out;
}


Error --->
static int wl3501_close(struct net_device *dev)
{
struct wl3501_card *this = dev->priv;
int rc = -ENODEV;
---------------------------------------------------------
[BUG]
/home/kash/linux/2.6.3/linux-2.6.3/drivers/net/smc-ultra32.c:301:ultra32_close:ERROR:INTERFACE_A_B:
Not calling ei_close. See ultra32_open:297 [COUNTER=ei_open-ei_close]
[fit=9] [fit_fn=2] [fn_ex=0] [fn_counter=1] [ex=13] [counter=3] [z =
0.125] [fn-z = -2]
outb(0xff, dev->base_addr + EN0_ERWCNT);
ei_open(dev);
return 0;
}


Error --->
static int ultra32_close(struct net_device *dev)
{
int ioaddr = dev->base_addr - ULTRA32_NIC_OFFSET; /* CMDREG */

---------------------------------------------------------
[BUG] becker@scyld.com
/home/kash/linux/2.6.3/linux-2.6.3/drivers/net/smc-ultra.c:511:ultra_close_card:ERROR:INTERFACE_A_B:
Not calling ei_close. See ultra_open:386 [COUNTER=ei_open-ei_close]
[fit=9] [fit_fn=3] [fn_ex=0] [fn_counter=1] [ex=13] [counter=3] [z =
0.125] [fn-z = -2]
/* An extra odd byte is OK here as well. */
outsw(ioaddr + IOPD, buf, (count+1)>>1);
}

static int

Error --->
ultra_close_card(struct net_device *dev)
{
int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* CMDREG */

---------------------------------------------------------
[BUG] weisd3458@uni.edu does the steps of ei_close but in wrong order and
without holding locks
/home/kash/linux/2.6.3/linux-2.6.3/drivers/net/smc-mca.c:432:ultramca_close_card:ERROR:INTERFACE_A_B:
Not calling ei_close. See ultramca_open:365 [COUNTER=ei_open-ei_close]
[fit=9] [fit_fn=1] [fn_ex=0] [fn_counter=1] [ex=13] [counter=3] [z =
0.125] [fn-z = -2]
unsigned long shmem = dev->mem_start + ((start_page - START_PG) << 8);

isa_memcpy_toio(shmem, buf, count);
}


Error --->
static int ultramca_close_card(struct net_device *dev)
{
int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */

---------------------------------------------------------
[BUG] (becker@scyld.com, thorn@daimi.aau.dk, hiro@sanpo.t.u-tokyo.ac.jp,
gw4pts@gw4pts.ampr.org, 100136.3530@compuserve.com, gniibe@mri.co.jp,
zimerman@mailandnews.com) parport_unregister_device called in
plip_cleanup_module. Looks like if we call, plip_attach, plip_detach,
plip_attach, the first nl->pardev is lost
/home/kash/linux/2.6.3/linux-2.6.3/drivers/net/plip.c:1331:plip_detach:ERROR:INTERFACE_A_B:
Not calling parport_unregister_device. See plip_attach:1292
[COUNTER=parport_register_device-parport_unregister_device] [fit=10]
[fit_fn=1] [fn_ex=0] [fn_counter=1] [ex=3] [counter=1] [z = -0.25] [fn-z =
-2]
return;
}

/* plip_detach() is called (by the parport code) when a port is
* no longer available to use. */

Error --->
static void plip_detach (struct parport *port)
{
/* Nothing to do */
}


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-03-22 14:02    [W:0.117 / U:0.384 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site