Linux-kernel mailing list archive 2000-32,: more fun with malloc/free

# more fun with malloc/free

Dawson Engler (engler@csl.Stanford.EDU)
Wed, 9 Aug 2000 17:42:47 -0700 (PDT)

- Messages sorted by: [ date ][ thread ][ subject ][ author ]
- Next message: David S. Miller: "Re: [2.4.0-test6-pre9] memory leak?"
- Previous message: Igmar Palsenberg: "Re: NE2000 PCI issue"

Hi All,

to save people trouble wading through false positives, here's another
batch of annotated errors caught by the tool. Seem to be divided 50/50
between "not checking for allocation failure" and "not freeing memory
on error paths."

If anyone goes through and verifies/disproves some of these, we'd
appreciate the feedback.

Dawson
--------------------------------------------------------------
/u2/engler/ic/linux-2.3.99/drivers/net/wan/lmc/lmc_main.c:518:lmc_ioctl: ERROR: did not free data on error path

data = kmalloc(xc.len, GFP_KERNEL);
if(data == 0x0){
printk(KERN_WARNING "%s: Failed to allocate memory for copy\n", dev->name);
ret = -ENOMEM;
break;
}

LMC_COPY_FROM_USER(data, xc.data, xc.len);

where LMC_* returns with an error if copy fails:.

#define LMC_COPY_FROM_USER(x, y, z)
if(copy_from_user ((x), (y), (z))) return -EFAULT

--------------------------------------------------------------
/u2/engler/ic/linux-2.3.99/drivers/net/wan/lmc/lmc_proto.c:106:lmc_proto_init: ERROR: Unchecked use of malloc'd var 'sc'

sc->pd = kmalloc(sizeof(struct ppp_device), GFP_KERNEL);
sc->pd->dev = sc->lmc_device;

--------------------------------------------------------------
/u2/engler/ic/linux-2.3.99/drivers/net/wan/comx.c:508:comx_init_dev: ERROR: did not free ch on error path

if ((ch = kmalloc(sizeof(struct comx_channel), GFP_KERNEL)) == NULL) {
return -ENOMEM;
}
...
if ((ch->avg_bytes = kmalloc(ch->loadavg_size *
ch allocated
---> return -ENOMEM;
}
--------------------------------------------------------------
/u2/engler/ic/linux-2.3.99/drivers/net/wan/comx.c:899:comx_mkdir: ERROR: did not free dev on error path
/u2/engler/ic/linux-2.3.99/drivers/net/wan/comx.c:889:comx_mkdir: ERROR: did not free dev on error path
/u2/engler/ic/linux-2.3.99/drivers/net/wan/comx.c:884:comx_mkdir: ERROR: did not free dev on error path

I *think*. If it comes through and retrys again its going to overwrite and
lose this memory. Also

if ((dev = kmalloc(sizeof(struct net_device), GFP_KERNEL)) == NULL) {
return -ENOMEM;
}

...
[PLUS: could register dev but it might not be fully setup. Then you'll come
through and register again.]
---> if (register_netdevice(dev)) {

[dev is allocated but lost]
----> return -EIO;
}

ch=dev->priv;
if((ch->if_ptr = (void *)kmalloc(sizeof(struct ppp_device),
GFP_KERNEL)) == NULL) {
return -ENOMEM;
}
memset(ch->if_ptr, 0, sizeof(struct ppp_device));
ch->debug_file = debug_file;
ch->procdir = new_dir;
new_dir->data = dev;

ch->debug_start = ch->debug_end = 0;
if ((ch->debug_area = kmalloc(ch->debug_size = DEFAULT_DEBUG_SIZE,
GFP_KERNEL)) == NULL) {
lost ch->if_ptr
--> return -ENOMEM;
}

ch->lineup_delay = DEFAULT_LINEUP_DELAY;

---------------------------------------------------------------
/u2/engler/ic/linux-2.3.99/drivers/net/wan/comx-hw-comx.c:1289:COMX_init: ERROR: did not free ch on error path
/u2/engler/ic/linux-2.3.99/drivers/net/wan/comx-hw-comx.c:1278:COMX_init: ERROR: did not free ch on error path
/u2/engler/ic/linux-2.3.99/drivers/net/wan/comx-hw-comx.c:1266:COMX_init: ERROR: did not free ch on error path
/u2/engler/ic/linux-2.3.99/drivers/net/wan/comx-hw-comx.c:1254:COMX_init: ERROR: did not free ch on error path
/u2/engler/ic/linux-2.3.99/drivers/net/wan/comx-hw-comx.c:1243:COMX_init: ERROR: did not free ch on error path
/u2/engler/ic/linux-2.3.99/drivers/net/wan/comx-hw-comx.c:1232:COMX_init: ERROR: did not free ch on error path

this gets lost on a retry since you don't check if it already exists:

if ((ch->HW_privdata = kmalloc(sizeof(struct comx_privdata),
GFP_KERNEL)) == NULL) {
return -ENOMEM;
}
...

if ((new_file = create_proc_entry(FILENAME_MEMADDR, S_IFREG | 0644,
ch->procdir)) == NULL) {
ch->HW_privdata seems to get lost
----> return -EIO;
}
--------------------------------------------------------------------

/u2/engler/ic/linux-2.3.99/drivers/net/wan/comx-hw-locomx.c:403:LOCOMX_init: ERROR: did not free ch on error path
/u2/engler/ic/linux-2.3.99/drivers/net/wan/comx-hw-locomx.c:393:LOCOMX_init: ERROR: did not free ch on error path
/u2/engler/ic/linux-2.3.99/drivers/net/wan/comx-hw-mixcom.c:869:MIXCOM_init: ERROR: did not free ch on error path
/u2/engler/ic/linux-2.3.99/drivers/net/wan/comx-hw-mixcom.c:859:MIXCOM_init: ERROR: did not free ch on error path
/u2/engler/ic/linux-2.3.99/drivers/net/wan/comx-hw-mixcom.c:837:MIXCOM_init: ERROR: did not free ch on error path
/u2/engler/ic/linux-2.3.99/drivers/net/wan/comx-hw-mixcom.c:827:MIXCOM_init: ERROR: did not free ch on error path

Seems like its going to lose:
/* Alloc data for private structure */
if ((ch->HW_privdata = kmalloc(sizeof(struct locomx_data),
GFP_KERNEL)) == NULL) {
return -ENOMEM;

on all of these since ch->HW_privdata does not get checked on retry.

-------------------------------------------------------------------
/u2/engler/ic/linux-2.3.99/drivers/net/wan/lapbether.c:444:lapbeth_new_device: ERROR: Unchecked use of malloc'd var 'buf'
/u2/engler/ic/linux-2.3.99/drivers/net/wan/lapbether.c:434:lapbeth_new_device: ERROR: Unchecked use of malloc'd var 'buf'

buf = kmalloc(14, GFP_KERNEL);

for (k = 0; k < MAXLAPBDEV; k++) {
struct net_device *odev;

used
---> sprintf(buf, "lapb%d", k);
if ((odev = __dev_get_by_name(buf)) == NULL || lapbeth_check_devices(odev))
break;
}

-----------------------------------------------------------------------
/u2/engler/ic/linux-2.3.99/drivers/net/wan/sdla.c:1215:sdla_xfer: ERROR: did not free temp on error path
/u2/engler/ic/linux-2.3.99/drivers/net/wan/sdla.c:1206:sdla_xfer: ERROR: did not free temp on error path

if (read)
{
temp = kmalloc(mem.len, GFP_KERNEL);
if (!temp) return(-ENOMEM);
sdla_read(dev, mem.addr, temp, mem.len);
if(copy_to_user(mem.data, temp, mem.len))
lost temp
---> return -EFAULT;
kfree(temp);
}
else
{
temp = kmalloc(mem.len, GFP_KERNEL);
if (!temp)
return(-ENOMEM);
if(copy_from_user(temp, mem.data, mem.len))
lost temp
----> return -EFAULT;
sdla_write(dev, mem.addr, temp, mem.len);
kfree(temp);
}
-----------------------------------------------------------------------

/u2/engler/ic/linux-2.3.99/drivers/net/appletalk/ipddp.c:245:ipddp_create: ERROR: did not free rt on error path

struct ipddp_route *rt =(struct ipddp_route*) kmalloc(sizeof(*rt), GFP_KERNEL); struct ipddp_route *test;

if(rt == NULL)
return -ENOMEM;

rt->ip = new_rt->ip;
rt->at = new_rt->at;
rt->next = NULL;
rt->dev = atrtr_get_dev(&rt->at); if(rt->dev == NULL) return (-ENETUNREACH);

-----------------------------------------------------------------------
/u2/engler/ic/linux-2.3.99/drivers/net/skfp/skfddi.c:690:skfp_driver_init: ERROR: memset of unchecked var 'bp'!

alloc
---> bp->SharedMemAddr = kmalloc(bp->SharedMemSize, GFP_KERNEL);
if (!bp->SharedMemSize) {
printk("could not allocate mem for ");
printk("hardware module: %ld byte\n",
bp->SharedMemSize);
return (-1);
}
bp->SharedMemHeap = 0; // Nothing used yet.

} else {
bp->SharedMemAddr = NULL;
bp->SharedMemHeap = 0;
} // SharedMemSize > 0
use
---> memset(bp->SharedMemAddr, 0, bp->SharedMemS

-----------------------------------------------------------------------

/u2/engler/ic/linux-2.3.99/drivers/parport/daisy.c:50:add_dev: ERROR: allocated 7 bytes for 'newdev' need 16

swapped GFP_KERNEL and size:
newdev = kmalloc (GFP_KERNEL, sizeof (struct daisydev));

----------------------------------------------------------------------
/u2/engler/ic/linux-2.3.99/drivers/sound/softoss.c:1117:softsyn_load_patch: ERROR: did not free patch on error path

patch = vmalloc(sizeof(*patch));

if(copy_from_user(&((char *) patch)[offs], &(addr)[offs], sizeof_patch - offs))
lost patch
----> return -EFAULT;

----------------------------------------------------------------------

/u2/engler/ic/linux-2.3.99/drivers/sound/sonicvibes.c:2604:sv_probe: ERROR: did not free s on error path

kfree_s(s, sizeof(struct sv_state));
return -1;

------------------------------------------------------------------

/u2/engler/ic/linux-2.3.99/drivers/pcmcia/cs.c:337:register_ss_entry: ERROR: memset of unchecked var 's'!

s = kmalloc(sizeof(struct socket_info_t), GFP_KERNEL);
memset(s, 0, sizeof(socket_info_t));

------------------------------------------------------------------
/u2/engler/ic/linux-2.3.99/drivers/pcmcia/cs.c:1411:pcmcia_register_client: ERROR: memset of unchecked var 's'!

s->config = kmalloc(sizeof(config_t) * s->functions, GFP_KERNEL);
memset(s->config, 0, sizeof(config_t) * s->functions);
------------------------------------------------------------------

/u2/engler/ic/linux-2.3.99/drivers/pcmcia/ds.c:414:bind_request: ERROR: Unchecked use of malloc'd var 'b'

b = kmalloc(sizeof(socket_bind_t), GFP_KERNEL);
b->driver = driver;

------------------------------------------------------------------
/u2/engler/ic/linux-2.3.99/drivers/pcmcia/ds.c:424:bind_request: ERROR: did not free driver on error path

if (driver->attach) { b->instance = driver->attach();
if (b->instance == NULL) {
printk(KERN_NOTICE "ds: unable to create instance "
"of '%s'!\n", (char *)bind_info->dev_info);
lost b
----> return -ENODEV;
}
}
------------------------------------------------------------------
/u2/engler/ic/linux-2.3.99/drivers/pcmcia/bulkmem.c:232:setup_erase_request: ERROR: Unchecked use of malloc'd var 'busy'

busy = kmalloc(sizeof(erase_busy_t), GFP_KERNEL);
busy->erase = erase;

------------------------------------------------------------------
/u2/engler/ic/linux-2.3.99/drivers/pcmcia/bulkmem.c:363:setup_regions: ERROR: Unchecked use of malloc'd var 'r'

r = kmalloc(sizeof(*r), GFP_KERNEL);
r->region_magic = REGION_MAGIC;

------------------------------------------------------------------
/u2/engler/ic/linux-2.3.99/drivers/pcmcia/rsrc_mgr.c:193:do_io_probe: ERROR: memset of unchecked var 'b'!

b = kmalloc(256, GFP_KERNEL);
memset(b, 0, 256);

------------------------------------------------------------------
/u2/engler/ic/linux-2.3.99/drivers/video/matrox/matroxfb_crtc2.c:638:matroxfb_dh_regit: ERROR: memset of unchecked var 'd'!

d = kmalloc(sizeof(*d), GFP_KERNEL);
memset(d, 0, sizeof(*d));

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

- Next message: David S. Miller: "Re: [2.4.0-test6-pre9] memory leak?"
- Previous message: Igmar Palsenberg: "Re: NE2000 PCI issue"