public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [CHECKER] Resource leaks in driver shutdown functions
@ 2004-05-03 18:46 Ken Ashcraft
  2004-05-04  8:43 ` [PATCH] sis900 fix (Was: [CHECKER] Resource leaks in driver shutdown functions) Daniele Venzano
  0 siblings, 1 reply; 7+ messages in thread
From: Ken Ashcraft @ 2004-05-03 18:46 UTC (permalink / raw)
  To: linux-kernel, linux
  Cc: linux-ns83820, alfred, aarnold, sailer, maxk, andrew.grover,
	paul.s.diefenbaugh, webvenza, acme, niemeyer, becker, weisd3458,
	thorn, hiro, gw4pts, 100136.3530, gniibe, zimerman

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 */
}



^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2004-05-17 19:42 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-05-03 18:46 [CHECKER] Resource leaks in driver shutdown functions Ken Ashcraft
2004-05-04  8:43 ` [PATCH] sis900 fix (Was: [CHECKER] Resource leaks in driver shutdown functions) Daniele Venzano
2004-05-04 15:28   ` Randy.Dunlap
2004-05-04 17:54     ` Daniele Venzano
2004-05-06 17:23   ` Rob Landley
2004-05-07 15:06     ` Daniele Venzano
2004-05-11 17:35       ` Rob Landley

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox