[PATCH] fixed: checking kmalloc, init_etherdev and other fixes

From: Arnaldo Carvalho de Melo (acme@conectiva.com.br)
Date: Tue Aug 08 2000 - 00:19:04 EST


Em Mon, Aug 07, 2000 at 08:48:37PM -0700, David S. Miller escreveu:
> Date: Tue, 8 Aug 2000 00:55:42 -0300
> From: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
>
> This patch mostly includes checks for kmalloc and init_etherdev
> in the net drivers, but also fixes some bugs on some drivers,
> please take a look and consider aplying.
>
> Plain visial inspection found at least a problem in this part of
> patch.

David,

    Here is a fixed version of the patch, I've checked if all over,
hope this one doesn't have any problem.

    Now I'll have some sleep :)

- Arnaldo

diff -uNr linux-2.4.0-test6-pre7/drivers/net/3c503.c linux-2.4.0-test6-pre7.acme/drivers/net/3c503.c
--- linux-2.4.0-test6-pre7/drivers/net/3c503.c Mon Jun 19 17:30:56 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/3c503.c Tue Aug 8 01:51:46 2000
@@ -190,6 +190,9 @@
     if (dev == NULL) {
         printk("3c503.c: Passed a NULL device.\n");
         dev = init_etherdev(0, 0);
+
+ if (!dev)
+ return -ENOMEM;
     }
 
     if (ei_debug && version_printed++ == 0)
diff -uNr linux-2.4.0-test6-pre7/drivers/net/3c507.c linux-2.4.0-test6-pre7.acme/drivers/net/3c507.c
--- linux-2.4.0-test6-pre7/drivers/net/3c507.c Mon Jun 19 17:30:56 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/3c507.c Tue Aug 8 01:51:46 2000
@@ -355,7 +355,8 @@
 
         /* Allocate a new 'dev' if needed. */
         if (dev == NULL)
- dev = init_etherdev(0, sizeof(struct net_local));
+ if ((dev = init_etherdev(0, sizeof(struct net_local))) == NULL)
+ return -ENOMEM;
 
         if (net_debug && version_printed++ == 0)
                 printk(version);
diff -uNr linux-2.4.0-test6-pre7/drivers/net/3c515.c linux-2.4.0-test6-pre7.acme/drivers/net/3c515.c
--- linux-2.4.0-test6-pre7/drivers/net/3c515.c Tue Jul 11 15:12:23 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/3c515.c Tue Aug 8 01:51:46 2000
@@ -14,6 +14,12 @@
         2/2/00- Added support for kernel-level ISAPnP
                 by Stephen Frost <sfrost@snowman.net> and Alessandro Zummo
         Cleaned up for 2.3.x/softnet by Jeff Garzik and Alan Cox.
+
+ 07/30/2000 - Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ - check if kmalloc(dev->priv) in corkscrew_found_device was
+ successful, the same for kmalloc(net_device).
+ Avoid reallocating dev->priv when compiled as a module.
+ Check init_etherdev, it can return NULL
 */
 
 static char *version = "3c515.c:v0.99-sn 2000/02/12 becker@cesdis.gsfc.nasa.gov and others\n";
@@ -561,6 +567,10 @@
             sizeof(struct corkscrew_private) + 15; /* Pad for alignment */
 
         dev = (struct net_device *) kmalloc(dev_size, GFP_KERNEL);
+
+ if (!dev)
+ return NULL;
+
         memset(dev, 0, dev_size);
         /* Align the Rx and Tx ring entries. */
         dev->priv =
@@ -587,15 +597,23 @@
         vp->next_module = root_corkscrew_dev;
         root_corkscrew_dev = dev;
         if (register_netdev(dev) != 0)
- return 0;
+ return NULL;
 #else /* not a MODULE */
- if (dev) {
+ if (dev && !dev->priv) {
                 /* Caution: quad-word alignment required for rings! */
                 dev->priv =
                     kmalloc(sizeof(struct corkscrew_private), GFP_KERNEL);
+
+ if (!dev->priv)
+ return NULL;
+
                 memset(dev->priv, 0, sizeof(struct corkscrew_private));
         }
         dev = init_etherdev(dev, sizeof(struct corkscrew_private));
+
+ if (!dev)
+ return NULL;
+
         dev->base_addr = ioaddr;
         dev->irq = irq;
         dev->dma =
diff -uNr linux-2.4.0-test6-pre7/drivers/net/ac3200.c linux-2.4.0-test6-pre7.acme/drivers/net/ac3200.c
--- linux-2.4.0-test6-pre7/drivers/net/ac3200.c Mon Jun 19 17:30:57 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/ac3200.c Tue Aug 8 01:51:46 2000
@@ -139,6 +139,9 @@
         if (dev == NULL) {
                 printk("ac3200.c: Passed a NULL device.\n");
                 dev = init_etherdev(0, 0);
+
+ if (!dev)
+ return -ENOMEM;
         }
 
         printk("AC3200 in EISA slot %d, node", ioaddr/0x1000);
diff -uNr linux-2.4.0-test6-pre7/drivers/net/acenic.c linux-2.4.0-test6-pre7.acme/drivers/net/acenic.c
--- linux-2.4.0-test6-pre7/drivers/net/acenic.c Mon Aug 7 21:56:33 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/acenic.c Tue Aug 8 01:51:46 2000
@@ -132,6 +132,10 @@
         void *virt_ptr;
 
         virt_ptr = kmalloc(size, GFP_KERNEL);
+
+ if (!virt_ptr)
+ return NULL;
+
         *dma_handle = virt_to_bus(virt_ptr);
         return virt_ptr;
 }
diff -uNr linux-2.4.0-test6-pre7/drivers/net/aironet4500_card.c linux-2.4.0-test6-pre7.acme/drivers/net/aironet4500_card.c
--- linux-2.4.0-test6-pre7/drivers/net/aironet4500_card.c Fri Jul 28 06:34:44 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/aironet4500_card.c Tue Aug 8 01:51:47 2000
@@ -10,10 +10,18 @@
  * Revision 0.2, Feb 27, 2000
  * Jeff Garzik - softnet, cleanups
  *
+ * Revision 0.3, Aug 03, 2000
+ * Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ * - only zeroes dev->priv after kmalloc if it was succesfully
+ * allocated
+ * - check if request_irq, request_region and others were successful
+ * - other cleanups
+ *
+ *
  */
 #ifdef MODULE
 static const char *awc_version =
-"aironet4500_cards.c v0.2 Feb 27, 2000 Elmer Joandi, elmer@ylenurme.ee.\n";
+"aironet4500_cards.c v0.3 Jul 30, 2000 Elmer Joandi, elmer@ylenurme.ee.\n";
 #endif
 
 #include <linux/version.h>
@@ -166,16 +174,21 @@
 
         int i;
 
- if (!dev) {
- dev = init_etherdev(dev, 0 );
- }
+ if (!dev)
+ if ((dev = init_etherdev(0, 0)) == NULL) {
+ printk(KERN_CRIT "aironet4x00: could't allocate device struct\n");
+ return -ENOMEM;
+ }
+
         dev->priv = kmalloc(sizeof(struct awc_private),GFP_KERNEL );
- memset(dev->priv,0,sizeof(struct awc_private));
+
         if (!dev->priv) {
- printk(KERN_CRIT "aironet4x00: could not allocate device private, some unstability may follow\n");
- return -1;
+ printk(KERN_CRIT "aironet4x00: couldn't allocate device private\n");
+ return -ENOMEM;
         };
 
+ memset(dev->priv,0,sizeof(struct awc_private));
+
 // ether_setup(dev);
 
 // dev->tx_queue_len = tx_queue_len;
@@ -193,8 +206,12 @@
         dev->tx_timeout = &awc_tx_timeout;
         dev->watchdog_timeo = AWC_TX_TIMEOUT;
         
-
- request_irq(dev->irq,awc_interrupt, SA_SHIRQ | SA_INTERRUPT ,"Aironet 4X00",dev);
+ if (request_irq(dev->irq,awc_interrupt, SA_SHIRQ | SA_INTERRUPT ,"Aironet 4X00",dev)) {
+ printk(KERN_CRIT "aironet4x00: could not allocate device IRQ, some unstability may follow\n");
+ kfree(dev->priv);
+ dev->priv = NULL;
+ return -EAGAIN;
+ }
 
         awc_private_init( dev);
         awc_init(dev);
@@ -341,6 +358,23 @@
                         printk("No logical device found on Aironet board \n");
                         return -ENODEV;
                 }
+
+ if (!dev)
+ if ((dev = init_etherdev(0, 0)) == NULL) {
+ printk(KERN_CRIT "aironet4x00: couldn't allocate device struct\n");
+ return -ENOMEM;
+ }
+
+ dev->priv = kmalloc(sizeof(struct awc_private),GFP_KERNEL );
+
+ if (!dev->priv) {
+ printk(KERN_CRIT "aironet4x00: could not allocate device private\n");
+ return -ENOMEM;
+ };
+
+ memset(dev->priv,0,sizeof(struct awc_private));
+ ((struct awc_private *)dev->priv)->bus = logdev;
+
                 if (isapnp_cfg_begin(logdev->PNP_BUS->PNP_BUS_NUMBER, logdev->PNP_DEV_NUMBER) < 0) {
                         printk("cfg begin failed for csn %x devnum %x \n",
                                         logdev->PNP_BUS->PNP_BUS_NUMBER, logdev->PNP_DEV_NUMBER);
@@ -351,18 +385,12 @@
 
                 isa_irq_line = logdev->irq;
                 isa_ioaddr = logdev->resource[0].start;
- request_region(isa_ioaddr, AIRONET4X00_IO_SIZE, "aironet4x00 ioaddr");
 
- if (!dev) {
- dev = init_etherdev(dev, 0 );
+ if (!request_region(isa_ioaddr, AIRONET4X00_IO_SIZE, "aironet4x00 ioaddr")) {
+ kfree(dev->priv);
+ dev->priv = NULL;
+ return -EBUSY;
                 }
- dev->priv = kmalloc(sizeof(struct awc_private),GFP_KERNEL );
- memset(dev->priv,0,sizeof(struct awc_private));
- if (!dev->priv) {
- printk(KERN_CRIT "aironet4x00: could not allocate device private, some unstability may follow\n");
- return -1;
- };
- ((struct awc_private *)dev->priv)->bus = logdev;
 
         // ether_setup(dev);
         
@@ -381,9 +409,15 @@
                 dev->tx_timeout = &awc_tx_timeout;
                 dev->watchdog_timeo = AWC_TX_TIMEOUT;
                 
+ if (request_irq(dev->irq,awc_interrupt , SA_SHIRQ | SA_INTERRUPT ,"Aironet 4X00",dev)) {
+ printk(KERN_CRIT "aironet4x00: could not allocate device IRQ, some unstability may follow\n");
+ kfree(dev->priv);
+ dev->priv = NULL;
+ release_region(isa_ioaddr, AIRONET4X00_IO_SIZE);
+ return -EAGAIN;
+ }
+
                 netif_start_queue (dev);
-
- request_irq(dev->irq,awc_interrupt , SA_SHIRQ | SA_INTERRUPT ,"Aironet 4X00",dev);
 
                 awc_private_init( dev);
 
@@ -513,17 +547,24 @@
                 isa_ioaddr = io[card];
                 isa_irq_line = irq[card];
 
- request_region(isa_ioaddr, AIRONET4X00_IO_SIZE, "aironet4x00 ioaddr");
+ if (!request_region(isa_ioaddr, AIRONET4X00_IO_SIZE, "aironet4x00 ioaddr"))
+ return -EBUSY;
 
- if (!dev) {
- dev = init_etherdev(dev, 0 );
- }
+ if (!dev)
+ if ((dev = init_etherdev(0, 0)) == NULL) {
+ printk(KERN_CRIT "aironet4x00: couldn't allocate device struct, some unstability may follow\n");
+ release_region(isa_ioaddr, AIRONET4X00_IO_SIZE);
+ return -ENOMEM;
+ }
+
+
                 dev->priv = kmalloc(sizeof(struct awc_private),GFP_KERNEL );
- memset(dev->priv,0,sizeof(struct awc_private));
                 if (!dev->priv) {
                         printk(KERN_CRIT "aironet4x00: could not allocate device private, some unstability may follow\n");
+ release_region(isa_ioaddr, AIRONET4X00_IO_SIZE);
                         return -1;
                 };
+ memset(dev->priv,0,sizeof(struct awc_private));
 
         // ether_setup(dev);
         
@@ -542,13 +583,24 @@
                 dev->tx_timeout = &awc_tx_timeout;
                 dev->watchdog_timeo = AWC_TX_TIMEOUT;
                 
- request_irq(dev->irq,awc_interrupt ,SA_INTERRUPT ,"Aironet 4X00",dev);
+ if (request_irq(dev->irq,awc_interrupt ,SA_INTERRUPT ,"Aironet 4X00",dev)) {
+ printk(KERN_CRIT "aironet4x00: could not allocate device IRQ, some unstability may follow\n");
+ release_region(isa_ioaddr, AIRONET4X00_IO_SIZE);
+ kfree(dev->priv);
+ dev->priv = NULL;
+ return -EAGAIN;
+ }
 
                 awc_private_init( dev);
                 if ( awc_init(dev) ){
                         printk("card not found at irq %x mem %x\n",irq[card],io[card]);
- if (card==0)
- return -1;
+ if (card==0) {
+ free_irq(dev->irq, dev);
+ release_region(isa_ioaddr, AIRONET4X00_IO_SIZE);
+ kfree(dev->priv);
+ dev->priv = NULL;
+ return -ENODEV;
+ }
                         break;
                 }
 
@@ -798,8 +850,11 @@
         struct net_device * dev;
         int i;
 
-
         dev = init_etherdev(0, sizeof(struct awc_private) );
+
+ if (!dev)
+ return -1;
+
 
 // dev->tx_queue_len = tx_queue_len;
         ether_setup(dev);
diff -uNr linux-2.4.0-test6-pre7/drivers/net/apne.c linux-2.4.0-test6-pre7.acme/drivers/net/apne.c
--- linux-2.4.0-test6-pre7/drivers/net/apne.c Mon Jun 19 17:30:57 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/apne.c Tue Aug 8 01:51:47 2000
@@ -181,7 +181,10 @@
     /* We should have a "dev" from Space.c or the static module table. */
     if (dev == NULL) {
         printk(KERN_ERR "apne.c: Passed a NULL device.\n");
- dev = init_etherdev(0, 0);
+ if ((dev = init_etherdev(0, 0)) == NULL) {
+ printk(KERN_ERR "apne.c: out of memory.\n");
+ return -ENOMEM;
+ }
     }
 
     if (ei_debug && version_printed++ == 0)
diff -uNr linux-2.4.0-test6-pre7/drivers/net/ariadne2.c linux-2.4.0-test6-pre7.acme/drivers/net/ariadne2.c
--- linux-2.4.0-test6-pre7/drivers/net/ariadne2.c Mon Jun 19 17:30:57 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/ariadne2.c Tue Aug 8 01:51:47 2000
@@ -116,7 +116,10 @@
     /* We should have a "dev" from Space.c or the static module table. */
     if (dev == NULL) {
         printk(KERN_ERR "ariadne2.c: Passed a NULL device.\n");
- dev = init_etherdev(0, 0);
+ if ((dev = init_etherdev(0, 0)) == NULL) {
+ printk(KERN_ERR "ariadne2.c: out of memory.\n");
+ return -ENOMEM;
+ }
     }
 
     /* Reset card. Who knows what dain-bramaged state it was left in. */
diff -uNr linux-2.4.0-test6-pre7/drivers/net/at1700.c linux-2.4.0-test6-pre7.acme/drivers/net/at1700.c
--- linux-2.4.0-test6-pre7/drivers/net/at1700.c Mon Aug 7 21:56:33 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/at1700.c Tue Aug 8 01:51:47 2000
@@ -326,7 +326,8 @@
 
         /* Allocate a new 'dev' if needed. */
         if (dev == NULL)
- dev = init_etherdev(0, sizeof(struct net_local));
+ if ((dev = init_etherdev(0, sizeof(struct net_local))) == NULL)
+ return -ENOMEM;
 
         if (is_at1700)
                 irq = at1700_irqmap[(read_eeprom(ioaddr, 12)&0x04)
diff -uNr linux-2.4.0-test6-pre7/drivers/net/atari_bionet.c linux-2.4.0-test6-pre7.acme/drivers/net/atari_bionet.c
--- linux-2.4.0-test6-pre7/drivers/net/atari_bionet.c Fri Jul 28 06:34:44 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/atari_bionet.c Tue Aug 8 01:51:47 2000
@@ -374,7 +374,9 @@
         }
 
         if (dev->priv == NULL)
- dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
+ if ((dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL)) == NULL)
+ return -ENOMEM;
+
         memset(dev->priv, 0, sizeof(struct net_local));
 
         dev->open = bionet_open;
diff -uNr linux-2.4.0-test6-pre7/drivers/net/atari_pamsnet.c linux-2.4.0-test6-pre7.acme/drivers/net/atari_pamsnet.c
--- linux-2.4.0-test6-pre7/drivers/net/atari_pamsnet.c Fri Jul 28 06:34:44 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/atari_pamsnet.c Tue Aug 8 01:51:47 2000
@@ -12,6 +12,10 @@
  *
  * Little adaptions for integration into pl7 by Roman Hodek
  *
+ * Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 07/30/2000
+ * - check if kmalloc(dev->priv) was successful in bionet_probe
+ *
+ *
         What is it ?
         ------------
         This driver controls the PAMsNet LAN-Adapter which connects
@@ -630,7 +634,9 @@
 
         /* Initialize the device structure. */
         if (dev->priv == NULL)
- dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
+ if ((dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL)) == NULL)
+ return -ENOMEM;
+
         memset(dev->priv, 0, sizeof(struct net_local));
 
         dev->open = pamsnet_open;
diff -uNr linux-2.4.0-test6-pre7/drivers/net/atarilance.c linux-2.4.0-test6-pre7.acme/drivers/net/atarilance.c
--- linux-2.4.0-test6-pre7/drivers/net/atarilance.c Wed Aug 18 15:36:41 1999
+++ linux-2.4.0-test6-pre7.acme/drivers/net/atarilance.c Tue Aug 8 01:51:47 2000
@@ -511,7 +511,9 @@
   probe_ok:
         init_etherdev( dev, sizeof(struct lance_private) );
         if (!dev->priv)
- dev->priv = kmalloc( sizeof(struct lance_private), GFP_KERNEL );
+ if ((dev->priv = kmalloc( sizeof(struct lance_private), GFP_KERNEL)) == NULL)
+ return 0;
+
         lp = (struct lance_private *)dev->priv;
         MEM = (struct lance_memory *)memaddr;
         IO = lp->iobase = (struct lance_ioreg *)ioaddr;
diff -uNr linux-2.4.0-test6-pre7/drivers/net/bagetlance.c linux-2.4.0-test6-pre7.acme/drivers/net/bagetlance.c
--- linux-2.4.0-test6-pre7/drivers/net/bagetlance.c Sat May 13 12:29:40 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/bagetlance.c Tue Aug 8 01:51:47 2000
@@ -584,7 +584,9 @@
   probe_ok:
         init_etherdev( dev, sizeof(struct lance_private) );
         if (!dev->priv)
- dev->priv = kmalloc( sizeof(struct lance_private), GFP_KERNEL );
+ if ((dev->priv = kmalloc( sizeof(struct lance_private), GFP_KERNEL)) == NULL)
+ return 0;
+
         lp = (struct lance_private *)dev->priv;
         MEM = (struct lance_memory *)memaddr;
         IO = lp->iobase = (struct lance_ioreg *)ioaddr;
diff -uNr linux-2.4.0-test6-pre7/drivers/net/bmac.c linux-2.4.0-test6-pre7.acme/drivers/net/bmac.c
--- linux-2.4.0-test6-pre7/drivers/net/bmac.c Sun Feb 13 16:47:01 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/bmac.c Tue Aug 8 01:51:47 2000
@@ -1292,6 +1292,12 @@
 
         dev = init_etherdev(NULL, PRIV_BYTES);
 
+ if (!dev) {
+ printk(KERN_ERR "init_etherdev failed, out of memory for BMAC %s\n",
+ bmac->full_name);
+ return;
+ }
+
         dev->base_addr = (unsigned long)
                 ioremap(bmac->addrs[0].address, bmac->addrs[0].size);
         dev->irq = bmac->intrs[0].line;
diff -uNr linux-2.4.0-test6-pre7/drivers/net/declance.c linux-2.4.0-test6-pre7.acme/drivers/net/declance.c
--- linux-2.4.0-test6-pre7/drivers/net/declance.c Sat May 13 12:29:40 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/declance.c Tue Aug 8 01:51:47 2000
@@ -1018,6 +1018,9 @@
 
         if (dev == NULL) {
                 dev = init_etherdev(0, sizeof(struct lance_private) + 8);
+
+ if (!dev)
+ return -ENOMEM;
         } else {
                 dev->priv = kmalloc(sizeof(struct lance_private) + 8,
                                     GFP_KERNEL);
diff -uNr linux-2.4.0-test6-pre7/drivers/net/dgrs.c linux-2.4.0-test6-pre7.acme/drivers/net/dgrs.c
--- linux-2.4.0-test6-pre7/drivers/net/dgrs.c Mon Jun 19 17:30:58 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/dgrs.c Tue Aug 8 01:51:47 2000
@@ -71,6 +71,12 @@
  * into the kernel.
  * - Better handling of multicast addresses.
  *
+ * Fixes:
+ * Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 08/03/2000
+ * - fix dgrs_found_device wrt checking kmalloc return and
+ * rollbacking the partial steps of the whole process when
+ * one of the devices can't be allocated.
+ *
  */
 
 static char *version = "$Id: dgrs.c,v 1.13 2000/06/06 04:07:00 rick Exp $";
@@ -1245,13 +1251,17 @@
 )
 {
         DGRS_PRIV *priv;
- struct net_device *dev;
+ struct net_device *dev, *aux;
 
         /* Allocate and fill new device structure. */
         int dev_size = sizeof(struct net_device) + sizeof(DGRS_PRIV);
- int i;
+ int i, ret;
 
         dev = (struct net_device *) kmalloc(dev_size, GFP_KERNEL);
+
+ if (!dev)
+ return -ENOMEM;
+
         memset(dev, 0, dev_size);
         dev->priv = ((void *)dev) + sizeof(struct net_device);
         priv = (DGRS_PRIV *)dev->priv;
@@ -1269,11 +1279,12 @@
 
         dev->init = dgrs_probe1;
         ether_setup(dev);
- priv->next_dev = dgrs_root_dev;
- dgrs_root_dev = dev;
         if (register_netdev(dev) != 0)
                 return -EIO;
 
+ priv->next_dev = dgrs_root_dev;
+ dgrs_root_dev = dev;
+
         if ( !dgrs_nicmode )
                 return (0); /* Switch mode, we are done */
 
@@ -1290,6 +1301,12 @@
                         /* Allocate new dev and priv structures */
                 devN = (struct net_device *) kmalloc(dev_size, GFP_KERNEL);
                         /* Make it an exact copy of dev[0]... */
+
+ if (!devN) {
+ ret = -ENOMEM;
+ goto fail;
+ }
+
                 memcpy(devN, dev, dev_size);
                 devN->priv = ((void *)devN) + sizeof(struct net_device);
                 privN = (DGRS_PRIV *)devN->priv;
@@ -1300,16 +1317,33 @@
                 devN->irq = 0;
                         /* ... and base MAC address off address of 1st port */
                 devN->dev_addr[5] += i;
- privN->chan = i+1;
- priv->devtbl[i] = devN;
                 devN->init = dgrs_initclone;
                 ether_setup(devN);
+
+ if (register_netdev(devN) != 0) {
+ kfree(devN);
+ ret = -EIO;
+ goto fail;
+ }
+
+ privN->chan = i+1;
+ priv->devtbl[i] = devN;
                 privN->next_dev = dgrs_root_dev;
                 dgrs_root_dev = devN;
- if (register_netdev(devN) != 0)
- return -EIO;
         }
         return (0);
+fail:
+ aux = priv->next_dev;
+
+ while (dgrs_root_dev != aux) {
+ struct net_device *d = dgrs_root_dev;
+
+ dgrs_root_dev = ((DGRS_PRIV *)dgrs_root_dev->priv)->next_dev;
+ unregister_netdev(d);
+ kfree(d);
+ }
+
+ return ret;
 }
 
 /*
diff -uNr linux-2.4.0-test6-pre7/drivers/net/e2100.c linux-2.4.0-test6-pre7.acme/drivers/net/e2100.c
--- linux-2.4.0-test6-pre7/drivers/net/e2100.c Mon Jun 19 17:30:58 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/e2100.c Tue Aug 8 01:51:47 2000
@@ -168,8 +168,12 @@
 
         /* We should have a "dev" from Space.c or the static module table. */
         if (dev == NULL) {
- printk("e2100.c: Passed a NULL device.\n");
- dev = init_etherdev(0, 0);
+ printk(KERN_ERR "e2100.c: Passed a NULL device.\n");
+
+ if ((dev = init_etherdev(0, 0)) == NULL) {
+ printk(KERN_ERR "e2100.c: Passed a NULL device.\n");
+ return -ENOMEM;
+ }
         }
 
         printk("%s: E21** at %#3x,", dev->name, ioaddr);
@@ -178,7 +182,7 @@
 
         /* Allocate dev->priv and fill in 8390 specific dev fields. */
         if (ethdev_init(dev)) {
- printk (" unable to get memory for dev->priv.\n");
+ printk (KERN_ERR " unable to get memory for dev->priv.\n");
                 return -ENOMEM;
         }
 
diff -uNr linux-2.4.0-test6-pre7/drivers/net/es3210.c linux-2.4.0-test6-pre7.acme/drivers/net/es3210.c
--- linux-2.4.0-test6-pre7/drivers/net/es3210.c Mon Jun 19 17:30:58 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/es3210.c Tue Aug 8 01:51:47 2000
@@ -183,8 +183,12 @@
 
         /* We should have a "dev" from Space.c or the static module table. */
         if (dev == NULL) {
- printk("es3210.c: Passed a NULL device.\n");
- dev = init_etherdev(0, 0);
+ printk(KERN_ERR "es3210.c: Passed a NULL device.\n");
+
+ if ((dev = init_etherdev(0, 0)) == NULL) {
+ printk(KERN_ERR "es3210.c: out of memory.\n");
+ return -ENOMEM;
+ }
         }
 
         printk("es3210.c: ES3210 rev. %ld at %#x, node", eisa_id>>24, ioaddr);
diff -uNr linux-2.4.0-test6-pre7/drivers/net/eth16i.c linux-2.4.0-test6-pre7.acme/drivers/net/eth16i.c
--- linux-2.4.0-test6-pre7/drivers/net/eth16i.c Mon Jun 19 17:30:58 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/eth16i.c Tue Aug 8 01:51:47 2000
@@ -140,6 +140,10 @@
         - IRQ configuration with module parameter. I will do
           this when i will get enough info about setting
           irq without configuration utility.
+
+ Changes:
+ Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 08/06/2000
+ - check init_etherdev return in eth16i_probe1
 */
 
 static char *version =
@@ -495,6 +499,10 @@
         if(eth16i_check_signature(ioaddr) != 0)
                 return -ENODEV;
 
+ if(dev == NULL)
+ if ((dev = init_etherdev(0, 0)) == NULL)
+ return -ENOMEM;
+
         /*
            Now it seems that we have found a ethernet chip in this particular
            ioaddr. The MB86985 chip has this feature, that when you read a
@@ -508,9 +516,6 @@
 
         outb(0x00, ioaddr + RESET); /* Reset some parts of chip */
         BITSET(ioaddr + CONFIG_REG_0, BIT(7)); /* Disable the data link */
-
- if(dev == NULL)
- dev = init_etherdev(0, 0);
 
         if( (eth16i_debug & version_printed++) == 0)
                 printk(KERN_INFO "%s", version);
diff -uNr linux-2.4.0-test6-pre7/drivers/net/fmv18x.c linux-2.4.0-test6-pre7.acme/drivers/net/fmv18x.c
--- linux-2.4.0-test6-pre7/drivers/net/fmv18x.c Mon Jun 19 17:30:58 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/fmv18x.c Tue Aug 8 01:51:47 2000
@@ -29,6 +29,14 @@
     at1700.c
     The Fujitsu MB86965 datasheet.
     The Fujitsu FMV-181/182 user's guide
+
+ Changes:
+ Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 08/06/2000
+ - check init_etherdev return in fmv18x_probe1
+ - only allocates dev->priv if needed, i.e. if init_etherdev
+ is not used, cause in this case it will get allocated
+ - check request_region, and release the region if later on the
+ fmv18x_probe1 function fails.
 */
 
 static const char *version =
@@ -190,21 +198,31 @@
                 irq = irqmap[(inb(ioaddr + FJ_CONFIG0)>>6) & 0x03];
         }
 
+ /* Allocate a new 'dev' if needed. */
+ if (dev == NULL) {
+ if ((dev = init_etherdev(0, sizeof(struct net_local))) == NULL)
+ return -ENOMEM;
+ } else {
+ /* Initialize the device structure. */
+ dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
+ if (dev->priv == NULL)
+ return -ENOMEM;
+ memset(dev->priv, 0, sizeof(struct net_local));
+ }
+
+ /* Grab the region so that we can find another board if the IRQ request
+ fails. */
+ if (!request_region(ioaddr, FMV18X_IO_EXTENT, "fmv18x"))
+ return -EBUSY;
+
         /* Snarf the interrupt vector now. */
         if (request_irq(irq, &net_interrupt, 0, "fmv18x", dev)) {
                 printk ("FMV-18x found at %#3x, but it's unusable due to a conflict on"
                                 "IRQ %d.\n", ioaddr, irq);
+ release_region(ioaddr, FMV18X_IO_EXTENT);
                 return -EAGAIN;
         }
 
- /* Allocate a new 'dev' if needed. */
- if (dev == NULL)
- dev = init_etherdev(0, sizeof(struct net_local));
-
- /* Grab the region so that we can find another board if the IRQ request
- fails. */
- request_region(ioaddr, FMV18X_IO_EXTENT, "fmv18x");
-
         printk("%s: FMV-18x found at %#3x, IRQ %d, address ", dev->name,
                    ioaddr, irq);
 
@@ -262,12 +280,6 @@
 
         if (net_debug)
                 printk(version);
-
- /* Initialize the device structure. */
- dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
- if (dev->priv == NULL)
- return -ENOMEM;
- memset(dev->priv, 0, sizeof(struct net_local));
 
         dev->open = net_open;
         dev->stop = net_close;
diff -uNr linux-2.4.0-test6-pre7/drivers/net/gmac.c linux-2.4.0-test6-pre7.acme/drivers/net/gmac.c
--- linux-2.4.0-test6-pre7/drivers/net/gmac.c Mon Aug 7 21:56:33 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/gmac.c Tue Aug 8 01:51:47 2000
@@ -5,6 +5,10 @@
  * Copyright (C) 2000 Paul Mackerras & Ben. Herrenschmidt
  *
  * portions based on sunhme.c by David S. Miller
+ *
+ * Changes:
+ * Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 08/06/2000
+ * - check init_etherdev return in gmac_probe1
  *
  */
 
@@ -1178,7 +1182,13 @@
         }
 
         dev = init_etherdev(0, sizeof(struct gmac));
- memset(dev->priv, 0, sizeof(struct gmac));
+
+ if (!dev) {
+ printk(KERN_ERR "GMAC: init_etherdev failed, out of memory\n");
+ free_page(tx_descpage);
+ free_page(rx_descpage);
+ return;
+ }
 
         gm = (struct gmac *) dev->priv;
         dev->base_addr = gmac->addrs[0].address;
diff -uNr linux-2.4.0-test6-pre7/drivers/net/hp-plus.c linux-2.4.0-test6-pre7.acme/drivers/net/hp-plus.c
--- linux-2.4.0-test6-pre7/drivers/net/hp-plus.c Mon Jun 19 17:30:58 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/hp-plus.c Tue Aug 8 01:51:47 2000
@@ -161,8 +161,11 @@
 
         /* We should have a "dev" from Space.c or the static module table. */
         if (dev == NULL) {
- printk("hp-plus.c: Passed a NULL device.\n");
- dev = init_etherdev(0, 0);
+ printk(KERN_ERR "hp-plus.c: Passed a NULL device.\n");
+ if ((dev = init_etherdev(0, 0)) == NULL) {
+ printk(KERN_ERR "hp-plus.c: init_etherdev failed, out of memory.\n");
+ return -ENOMEM;
+ }
         }
 
         if (ei_debug && version_printed++ == 0)
diff -uNr linux-2.4.0-test6-pre7/drivers/net/hp.c linux-2.4.0-test6-pre7.acme/drivers/net/hp.c
--- linux-2.4.0-test6-pre7/drivers/net/hp.c Mon Jun 19 17:30:58 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/hp.c Tue Aug 8 01:51:47 2000
@@ -134,7 +134,10 @@
         /* We should have a "dev" from Space.c or the static module table. */
         if (dev == NULL) {
                 printk("hp.c: Passed a NULL device.\n");
- dev = init_etherdev(0, 0);
+ if ((dev = init_etherdev(0, 0)) == NULL) {
+ printk("hp.c: init_etherdev failed, out of memory.\n");
+ return -ENOMEM;
+ }
         }
 
         if (ei_debug && version_printed++ == 0)
diff -uNr linux-2.4.0-test6-pre7/drivers/net/hp100.c linux-2.4.0-test6-pre7.acme/drivers/net/hp100.c
--- linux-2.4.0-test6-pre7/drivers/net/hp100.c Fri Jul 28 06:34:44 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/hp100.c Tue Aug 8 01:51:47 2000
@@ -3026,6 +3026,10 @@
     {
       /* Create device and set basics args */
       hp100_devlist[i] = kmalloc(sizeof(struct net_device), GFP_KERNEL);
+
+ if (!hp100_devlist[i])
+ return -ENOMEM;
+
       memset(hp100_devlist[i], 0x00, sizeof(struct net_device));
 #if LINUX_VERSION_CODE >= 0x020362 /* 2.3.99-pre7 */
       memcpy(hp100_devlist[i]->name, hp100_name[i], IFNAMSIZ); /* Copy name */
diff -uNr linux-2.4.0-test6-pre7/drivers/net/hplance.c linux-2.4.0-test6-pre7.acme/drivers/net/hplance.c
--- linux-2.4.0-test6-pre7/drivers/net/hplance.c Mon Jun 19 17:30:58 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/hplance.c Tue Aug 8 01:51:47 2000
@@ -106,8 +106,10 @@
         struct hplance_private *lp;
         int i;
         
- if (dev == NULL)
- dev = init_etherdev(0, sizeof(struct hplance_private));
+ if (dev == NULL) {
+ if ((dev = init_etherdev(0, sizeof(struct hplance_private))) == NULL)
+ return -ENOMEM;
+ }
         else
         {
                 dev->priv = kmalloc(sizeof(struct hplance_private), GFP_KERNEL);
diff -uNr linux-2.4.0-test6-pre7/drivers/net/hydra.c linux-2.4.0-test6-pre7.acme/drivers/net/hydra.c
--- linux-2.4.0-test6-pre7/drivers/net/hydra.c Sun Feb 13 17:21:42 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/hydra.c Tue Aug 8 01:51:47 2000
@@ -13,6 +13,11 @@
 /* The Amiganet is a Zorro-II board made by Hydra Systems. It contains a */
 /* NS8390 NIC (network interface controller) clone, 16 or 64K on-board RAM */
 /* and 10BASE-2 (thin coax) and AUI connectors. */
+/* */
+/* Changes */
+/* Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 08/06/2000 */
+/* - check init_etherdev in hydra_probe */
+/* - dev->priv is already zeroed by init_etherdev */
 
 
 #include <linux/module.h>
@@ -176,8 +181,13 @@
                 strcpy(z->name, "Hydra Ethernet Card");
 
                 dev = init_etherdev(NULL, sizeof(struct hydra_private));
- memset(dev->priv, 0, sizeof(struct hydra_private));
-
+
+ if (!dev) {
+ release_mem_region(base_addr, 0x20);
+ release_mem_region(board, 0x4000);
+ continue;
+ }
+
                 for(j = 0; j < ETHER_ADDR_LEN; j++)
                         dev->dev_addr[j] = *((u8 *)ZTWO_VADDR(board + HYDRA_ADDRPROM + 2*j));
     
diff -uNr linux-2.4.0-test6-pre7/drivers/net/ibmlana.c linux-2.4.0-test6-pre7.acme/drivers/net/ibmlana.c
--- linux-2.4.0-test6-pre7/drivers/net/ibmlana.c Fri Jul 28 06:34:44 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/ibmlana.c Tue Aug 8 01:51:47 2000
@@ -70,6 +70,10 @@
   June 1st, 2000
         corrected version codes, added support for the latest 2.3 changes
 
+ Fixes:
+ Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 08/03/2000
+ - check kmalloc return in ibmlana_probe
+
  *************************************************************************/
 
 #include <linux/version.h>
@@ -1046,7 +1050,7 @@
         /* can't work without an MCA bus ;-) */
 
         if (MCA_bus == 0)
- return ENODEV;
+ return -ENODEV;
 
         /* start address of 1 --> forced detection */
 
@@ -1055,10 +1059,17 @@
 
         /* search through slots */
 
- if (dev != NULL) {
- base = dev->mem_start;
- irq = dev->irq;
- }
+ base = dev->mem_start;
+ irq = dev->irq;
+
+ /* allocate structure */
+
+ priv = dev->priv =
+ (ibmlana_priv *) kmalloc(sizeof(ibmlana_priv), GFP_KERNEL);
+
+ if (!priv)
+ return -ENOMEM;
+
         slot = mca_find_adapter(IBM_LANA_ID, startslot);
 
         while (slot != -1) {
@@ -1101,7 +1112,7 @@
         /* nothing found ? */
 
         if (slot == -1)
- return ((base != 0) || (irq != 0)) ? ENXIO : ENODEV;
+ return ((base != 0) || (irq != 0)) ? -ENXIO : -ENODEV;
 
         /* announce success */
         printk("%s: IBM LAN Adapter/A found in slot %d\n", dev->name,
@@ -1124,10 +1135,6 @@
         mca_mark_as_used(slot);
 #endif
 
- /* allocate structure */
-
- priv = dev->priv =
- (ibmlana_priv *) kmalloc(sizeof(ibmlana_priv), GFP_KERNEL);
         priv->slot = slot;
         priv->realirq = irq;
         priv->medium = medium;
diff -uNr linux-2.4.0-test6-pre7/drivers/net/jazzsonic.c linux-2.4.0-test6-pre7.acme/drivers/net/jazzsonic.c
--- linux-2.4.0-test6-pre7/drivers/net/jazzsonic.c Thu Aug 26 18:28:05 1999
+++ linux-2.4.0-test6-pre7.acme/drivers/net/jazzsonic.c Tue Aug 8 01:51:47 2000
@@ -11,6 +11,10 @@
  * A driver for the onboard Sonic ethernet controller on Mips Jazz
  * systems (Acer Pica-61, Mips Magnum 4000, Olivetti M700 and
  * perhaps others, too)
+ *
+ * Changes:
+ * Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 08/06/2000
+ * - check init_etherdev return in sonic_probe1
  */
 
 #include <linux/kernel.h>
@@ -144,11 +148,12 @@
         return -ENODEV;
     }
     
- request_region(base_addr, 0x100, "SONIC");
-
     /* Allocate a new 'dev' if needed. */
     if (dev == NULL)
- dev = init_etherdev(0, sizeof(struct sonic_local));
+ if ((dev = init_etherdev(0, sizeof(struct sonic_local))) == NULL)
+ return -ENOMEM;
+
+ request_region(base_addr, 0x100, "SONIC");
 
     if (sonic_debug && version_printed++ == 0)
       printk(version);
diff -uNr linux-2.4.0-test6-pre7/drivers/net/lance.c linux-2.4.0-test6-pre7.acme/drivers/net/lance.c
--- linux-2.4.0-test6-pre7/drivers/net/lance.c Mon Jun 19 17:30:58 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/lance.c Tue Aug 8 01:51:47 2000
@@ -23,6 +23,8 @@
       - added PCnetPCI II (79C970A) to chip table
         Paul Gortmaker (gpg109@rsphy1.anu.edu.au):
         - hopefully fix above so Linux/Alpha can use ISA cards too.
+ Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 08/03/2000
+ - checking kmalloc return in some places in lance_probe1
     8/20/96 Fixed 7990 autoIRQ failure and reversed unneeded alignment -djb
     v1.12 10/27/97 Module support -djb
     v1.14 2/3/98 Module support modified, made PCI support optional -djb
@@ -488,9 +490,21 @@
         lp->name = chipname;
         lp->rx_buffs = (unsigned long)kmalloc(PKT_BUF_SZ*RX_RING_SIZE,
                                                                                   GFP_DMA | GFP_KERNEL);
- if (lance_need_isa_bounce_buffers)
+
+ if (!lp->rx_buffs) {
+ kfree(lp);
+ return -ENOMEM;
+ }
+
+ if (lance_need_isa_bounce_buffers) {
                 lp->tx_bounce_buffs = kmalloc(PKT_BUF_SZ*TX_RING_SIZE,
                                                                           GFP_DMA | GFP_KERNEL);
+ if (!lp->tx_bounce_buffs) {
+ kfree(lp);
+ kfree((void *)lp->rx_buffs);
+ return -ENOMEM;
+ }
+ }
         else
                 lp->tx_bounce_buffs = NULL;
 
diff -uNr linux-2.4.0-test6-pre7/drivers/net/lne390.c linux-2.4.0-test6-pre7.acme/drivers/net/lne390.c
--- linux-2.4.0-test6-pre7/drivers/net/lne390.c Mon Jun 19 17:30:58 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/lne390.c Tue Aug 8 01:51:48 2000
@@ -164,8 +164,11 @@
 
         /* We should have a "dev" from Space.c or the static module table. */
         if (dev == NULL) {
- printk("lne390.c: Passed a NULL device.\n");
- dev = init_etherdev(0, 0);
+ printk(KERN_ERR "lne390.c: Passed a NULL device.\n");
+ if ((dev = init_etherdev(0, 0)) == NULL) {
+ printk(KERN_ERR "lne390.c: init_etherdev failed, out of memory.\n");
+ return -ENOMEM;
+ }
         }
 
         /* Allocate dev->priv and fill in 8390 specific dev fields. */
diff -uNr linux-2.4.0-test6-pre7/drivers/net/mac89x0.c linux-2.4.0-test6-pre7.acme/drivers/net/mac89x0.c
--- linux-2.4.0-test6-pre7/drivers/net/mac89x0.c Mon Jun 19 17:30:58 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/mac89x0.c Tue Aug 8 01:51:48 2000
@@ -48,6 +48,10 @@
   I/O space and NuBus interrupts for these cards, but neglected to
   provide anything even remotely resembling a NuBus ROM. Therefore we
   have to probe for them in a brain-damaged ISA-like fashion.
+
+ Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 07/30/2000
+ - check if kmalloc(dev->priv) in mac89x0_probe was successful
+ - the same for init_module
 */
 
 static char *version =
@@ -215,6 +219,10 @@
         /* Initialize the net_device structure. */
         if (dev->priv == NULL) {
                 dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
+
+ if (!dev->priv)
+ return -ENOMEM;
+
                 memset(dev->priv, 0, sizeof(struct net_local));
         }
         lp = (struct net_local *)dev->priv;
@@ -637,6 +645,11 @@
         dev_cs89x0.name = namespace;
         dev_cs89x0.init = mac89x0_probe;
         dev_cs89x0.priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
+
+ if (!dev_cs89x0.priv) {
+ printk(KERN_WARNING "mac89x0.c: out of memory\n");
+ return -ENOMEM;
+ }
         memset(dev_cs89x0.priv, 0, sizeof(struct net_local));
         lp = (struct net_local *)dev_cs89x0.priv;
 
diff -uNr linux-2.4.0-test6-pre7/drivers/net/mace.c linux-2.4.0-test6-pre7.acme/drivers/net/mace.c
--- linux-2.4.0-test6-pre7/drivers/net/mace.c Sun Feb 13 16:47:01 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/mace.c Tue Aug 8 01:51:48 2000
@@ -3,6 +3,11 @@
  * Apple Powermacs. Assumes it's under a DBDMA controller.
  *
  * Copyright (C) 1996 Paul Mackerras.
+ *
+ * Changes:
+ * Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ * - check init_etherdev return in mace_probe1
+ * - init_etherdev zeroes dev->priv, so no need here.
  */
 
 #include <linux/module.h>
@@ -133,7 +138,12 @@
         }
 
         dev = init_etherdev(0, PRIV_BYTES);
- memset(dev->priv, 0, PRIV_BYTES);
+
+ if (!dev) {
+ printk(KERN_ERR "init_etherdev failed, out of memory for MACE %s\n",
+ mace->full_name);
+ return;
+ }
 
         mp = (struct mace_data *) dev->priv;
         dev->base_addr = mace->addrs[0].address;
diff -uNr linux-2.4.0-test6-pre7/drivers/net/macsonic.c linux-2.4.0-test6-pre7.acme/drivers/net/macsonic.c
--- linux-2.4.0-test6-pre7/drivers/net/macsonic.c Tue Feb 1 05:43:51 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/macsonic.c Tue Aug 8 01:51:48 2000
@@ -20,6 +20,12 @@
  * and duplicating packets. Needs more testing.
  *
  * 99/01/03 MSch: upgraded to version 0.92 of the core driver, fixed.
+ *
+ * Fixes:
+ * Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 08/03/2000
+ * - check kmalloc return in mac_onboard_sonic_probe and mac_nubus_sonic_probe
+ * - check init_etherdev return
+ * - dev->priv already zeroed by init_etherdev
  */
 
 #include <linux/kernel.h>
@@ -318,16 +324,21 @@
                 dev = init_etherdev(dev, sizeof(struct sonic_local));
                 /* methinks this will always be true but better safe than sorry */
                 if (dev->priv == NULL)
- dev->priv = kmalloc(sizeof(struct sonic_local), GFP_KERNEL);
+ if ((dev->priv = kmalloc(sizeof(struct sonic_local), GFP_KERNEL)) == NULL)
+ return -ENOMEM;
+
+ memset(dev->priv, 0, sizeof(struct sonic_local));
         } else {
                 dev = init_etherdev(NULL, sizeof(struct sonic_local));
+
+ if (!dev)
+ return -ENOMEM;
         }
 
         if (dev == NULL)
                 return -ENOMEM;
 
         lp = (struct sonic_local*) dev->priv;
- memset(lp, 0, sizeof(struct sonic_local));
         /* Danger! My arms are flailing wildly! You *must* set this
            before using sonic_read() */
 
@@ -514,16 +525,20 @@
                 dev = init_etherdev(dev, sizeof(struct sonic_local));
                 /* methinks this will always be true but better safe than sorry */
                 if (dev->priv == NULL)
- dev->priv = kmalloc(sizeof(struct sonic_local), GFP_KERNEL);
+ if ((dev->priv = kmalloc(sizeof(struct sonic_local), GFP_KERNEL)) == NULL)
+ return -ENOMEM;
+ memset(dev->priv, 0, sizeof(struct sonic_local));
         } else {
                 dev = init_etherdev(NULL, sizeof(struct sonic_local));
+
+ if (!dev)
+ return -ENOMEM;
         }
 
         if (dev == NULL)
                 return -ENOMEM;
 
         lp = (struct sonic_local*) dev->priv;
- memset(lp, 0, sizeof(struct sonic_local));
         /* Danger! My arms are flailing wildly! You *must* set this
            before using sonic_read() */
         lp->reg_offset = reg_offset;
diff -uNr linux-2.4.0-test6-pre7/drivers/net/myri_sbus.c linux-2.4.0-test6-pre7.acme/drivers/net/myri_sbus.c
--- linux-2.4.0-test6-pre7/drivers/net/myri_sbus.c Mon Jun 19 17:30:58 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/myri_sbus.c Tue Aug 8 01:51:48 2000
@@ -892,6 +892,9 @@
         DET(("myri_ether_init(%p,%p,%d):\n", dev, sdev, num));
         dev = init_etherdev(0, sizeof(struct myri_eth));
 
+ if (!dev)
+ return -ENOMEM;
+
         if (version_printed++ == 0)
                 printk(version);
 
diff -uNr linux-2.4.0-test6-pre7/drivers/net/ne.c linux-2.4.0-test6-pre7.acme/drivers/net/ne.c
--- linux-2.4.0-test6-pre7/drivers/net/ne.c Sat Jul 8 23:38:16 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/ne.c Tue Aug 8 01:51:48 2000
@@ -332,7 +332,10 @@
         if (dev == NULL)
         {
                 printk(KERN_ERR "ne.c: Passed a NULL device.\n");
- dev = init_etherdev(0, 0);
+ if ((dev = init_etherdev(0, 0)) == NULL) {
+ printk(KERN_ERR "ne.c: init_etherdev failed, out of memory.\n");
+ return -ENOMEM;
+ }
         }
 
         if (ei_debug && version_printed++ == 0)
diff -uNr linux-2.4.0-test6-pre7/drivers/net/ne2.c linux-2.4.0-test6-pre7.acme/drivers/net/ne2.c
--- linux-2.4.0-test6-pre7/drivers/net/ne2.c Mon Jun 19 17:30:58 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/ne2.c Tue Aug 8 01:51:48 2000
@@ -46,6 +46,9 @@
    Mon Nov 16 15:28:23 CET 1998 (Wim Dumon)
    - pass 'dev' as last parameter of request_irq in stead of 'NULL'
    
+ Sun Aug 6 17:15:09 BRT 2000 (Arnaldo Carvalho de Melo <acme@conectiva.com.br>)
+ - check init_etherdev return in ne2_probe1
+
    * WARNING
         -------
         This is alpha-test software. It is not guaranteed to work. As a
@@ -210,7 +213,10 @@
         /* We should have a "dev" from Space.c or the static module table. */
         if (dev == NULL) {
                 printk(KERN_ERR "ne2.c: Passed a NULL device.\n");
- dev = init_etherdev(0, 0);
+ if ((dev = init_etherdev(0, 0)) == NULL) {
+ printk(KERN_ERR "ne2.c: init_etherdev failed, out of memory.\n");
+ return -ENOMEM;
+ }
         }
 
         if (ei_debug && version_printed++ == 0)
diff -uNr linux-2.4.0-test6-pre7/drivers/net/ne3210.c linux-2.4.0-test6-pre7.acme/drivers/net/ne3210.c
--- linux-2.4.0-test6-pre7/drivers/net/ne3210.c Mon Jun 19 17:30:59 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/ne3210.c Tue Aug 8 01:51:48 2000
@@ -160,7 +160,10 @@
         /* We should have a "dev" from Space.c or the static module table. */
         if (dev == NULL) {
                 printk("ne3210.c: Passed a NULL device.\n");
- dev = init_etherdev(0, 0);
+ if ((dev = init_etherdev(0, 0)) == NULL) {
+ printk("ne3210.c: init_etherdev failed, out of memory\n");
+ return -ENOMEM;
+ }
         }
 
         /* Allocate dev->priv and fill in 8390 specific dev fields. */
diff -uNr linux-2.4.0-test6-pre7/drivers/net/oaknet.c linux-2.4.0-test6-pre7.acme/drivers/net/oaknet.c
--- linux-2.4.0-test6-pre7/drivers/net/oaknet.c Mon Jun 19 17:30:56 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/oaknet.c Tue Aug 8 01:51:48 2000
@@ -12,6 +12,10 @@
  * Additional inspiration from the "tcd8390.c" driver from TiVo, Inc.
  * and "enetLib.c" from IBM.
  *
+ * Changes:
+ * Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 08/06/2000
+ * - check init_etherdev return in oaknet_init
+ *
  */
 
 #include <linux/module.h>
@@ -117,7 +121,7 @@
 
         if ((reg0 = ei_ibp(ioaddr)) == 0xFF) {
                 release_region(OAKNET_IO_BASE, OAKNET_IO_SIZE);
- return (ENODEV);
+ return (-ENODEV);
         }
 
         /*
@@ -140,7 +144,7 @@
                 dev->base_addr = 0;
 
                 release_region(dev->base_addr, OAKNET_IO_SIZE);
- return (ENODEV);
+ return (-ENODEV);
         }
 
         /*
@@ -148,7 +152,9 @@
          * our own device structure.
          */
 
- dev = init_etherdev(0, 0);
+ if ((dev = init_etherdev(0, 0)) == NULL)
+ return -ENOMEM;
+
         oaknet_devs = dev;
 
         /*
@@ -181,6 +187,7 @@
                 printk("%s: unable to request interrupt %d.\n",
                        dev->name, dev->irq);
                 kfree(dev->priv);
+ dev->priv = NULL;
                 release_region(dev->base_addr, OAKNET_IO_SIZE);
                 return (EAGAIN);
         }
diff -uNr linux-2.4.0-test6-pre7/drivers/net/rtl8129.c linux-2.4.0-test6-pre7.acme/drivers/net/rtl8129.c
--- linux-2.4.0-test6-pre7/drivers/net/rtl8129.c Tue Jul 11 15:12:24 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/rtl8129.c Tue Aug 8 01:51:48 2000
@@ -16,6 +16,10 @@
         http://cesdis.gsfc.nasa.gov/linux/drivers/rtl8139.html
 
         Twister-tuning table provided by Kinston <shangh@realtek.com.tw>.
+
+ Fixes:
+ Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 08/03/2000
+ - check kmalloc return in rtl8129_probe1
 */
 
 static const char *version =
@@ -407,6 +411,18 @@
 
         dev = init_etherdev(NULL, 0);
 
+ if (!dev)
+ return NULL;
+
+ /* Some data structures must be quadword aligned. */
+ tp = kmalloc(sizeof(*tp), GFP_KERNEL | GFP_DMA);
+
+ if (!tp)
+ return NULL;
+
+ memset(tp, 0, sizeof(*tp));
+ dev->priv = tp;
+
         printk(KERN_INFO "%s: %s at %#lx, IRQ %d, ",
                    dev->name, pci_tbl[chip_idx].name, ioaddr, irq);
 
@@ -431,11 +447,6 @@
 
         dev->base_addr = ioaddr;
         dev->irq = irq;
-
- /* Some data structures must be quadword aligned. */
- tp = kmalloc(sizeof(*tp), GFP_KERNEL | GFP_DMA);
- memset(tp, 0, sizeof(*tp));
- dev->priv = tp;
 
         tp->next_module = root_rtl8129_dev;
         root_rtl8129_dev = dev;
diff -uNr linux-2.4.0-test6-pre7/drivers/net/sb1000.c linux-2.4.0-test6-pre7.acme/drivers/net/sb1000.c
--- linux-2.4.0-test6-pre7/drivers/net/sb1000.c Fri Jul 28 06:34:45 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/sb1000.c Tue Aug 8 01:51:48 2000
@@ -209,13 +209,10 @@
                                 "S/N %#8.8x, IRQ %d.\n", dev->name, dev->base_addr,
                                 dev->rmem_end, serial_number, dev->irq);
 
- dev = init_etherdev(dev, 0);
+ dev = init_etherdev(dev, sizeof(struct sb1000_private));
 
- /* Make up a SB1000-specific-data structure. */
- dev->priv = kmalloc(sizeof(struct sb1000_private), GFP_KERNEL);
- if (dev->priv == NULL)
+ if (!dev)
                         return -ENOMEM;
- memset(dev->priv, 0, sizeof(struct sb1000_private));
 
                 if (sb1000_debug > 0)
                         printk(KERN_NOTICE "%s", version);
diff -uNr linux-2.4.0-test6-pre7/drivers/net/seeq8005.c linux-2.4.0-test6-pre7.acme/drivers/net/seeq8005.c
--- linux-2.4.0-test6-pre7/drivers/net/seeq8005.c Mon Jun 19 17:42:38 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/seeq8005.c Tue Aug 8 01:51:48 2000
@@ -272,7 +272,8 @@
 
         /* Allocate a new 'dev' if needed. */
         if (dev == NULL)
- dev = init_etherdev(0, sizeof(struct net_local));
+ if ((dev = init_etherdev(0, sizeof(struct net_local))) == NULL)
+ return -ENOMEM;
 
         if (net_debug && version_printed++ == 0)
                 printk(version);
diff -uNr linux-2.4.0-test6-pre7/drivers/net/sk_mca.c linux-2.4.0-test6-pre7.acme/drivers/net/sk_mca.c
--- linux-2.4.0-test6-pre7/drivers/net/sk_mca.c Fri Jul 28 06:34:46 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/sk_mca.c Tue Aug 8 01:51:48 2000
@@ -79,6 +79,10 @@
   June 1st, 2000
         added changes for recent 2.3 kernels
 
+ Fixes:
+ Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 08/03/2000
+ - check kmalloc return in skmca_probe
+
  *************************************************************************/
 
 #include <linux/kernel.h>
@@ -1136,7 +1140,14 @@
         /* nothing found ? */
 
         if (slot == -1)
- return ((base != 0) || (irq != 0)) ? ENXIO : ENODEV;
+ return ((base != 0) || (irq != 0)) ? -ENXIO : -ENODEV;
+
+ /* allocate structure */
+ priv = dev->priv =
+ (skmca_priv *) kmalloc(sizeof(skmca_priv), GFP_KERNEL);
+
+ if (!priv)
+ return -ENOMEM;
 
         /* make procfs entries */
 
@@ -1155,9 +1166,6 @@
         printk("%s: SKNet %s adapter found in slot %d\n", dev->name,
                junior ? "Junior MC2" : "MC2+", slot + 1);
 
- /* allocate structure */
- priv = dev->priv =
- (skmca_priv *) kmalloc(sizeof(skmca_priv), GFP_KERNEL);
         priv->slot = slot;
         priv->macbase = base + 0x3fc0;
         priv->ioregaddr = base + 0x3ff0;
diff -uNr linux-2.4.0-test6-pre7/drivers/net/smc-ultra.c linux-2.4.0-test6-pre7.acme/drivers/net/smc-ultra.c
--- linux-2.4.0-test6-pre7/drivers/net/smc-ultra.c Mon Jun 19 17:42:39 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/smc-ultra.c Tue Aug 8 01:51:48 2000
@@ -154,7 +154,8 @@
                 return -ENODEV;
 
         if (dev == NULL)
- dev = init_etherdev(0, 0);
+ if ((dev = init_etherdev(0, 0)) == NULL)
+ return -ENOMEM;
 
         if (ei_debug && version_printed++ == 0)
                 printk(version);
diff -uNr linux-2.4.0-test6-pre7/drivers/net/smc-ultra32.c linux-2.4.0-test6-pre7.acme/drivers/net/smc-ultra32.c
--- linux-2.4.0-test6-pre7/drivers/net/smc-ultra32.c Mon Jun 19 17:42:39 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/smc-ultra32.c Tue Aug 8 01:51:48 2000
@@ -151,7 +151,10 @@
         /* We should have a "dev" from Space.c or the static module table. */
         if (dev == NULL) {
                 printk("smc-ultra32.c: Passed a NULL device.\n");
- dev = init_etherdev(0, 0);
+ if ((dev = init_etherdev(0, 0)) == NULL) {
+ printk("smc-ultra32.c: Passed a NULL device.\n");
+ return -ENOMEM;
+ }
         }
 
         if (ei_debug && version_printed++ == 0)
diff -uNr linux-2.4.0-test6-pre7/drivers/net/stnic.c linux-2.4.0-test6-pre7.acme/drivers/net/stnic.c
--- linux-2.4.0-test6-pre7/drivers/net/stnic.c Fri Jul 28 06:34:46 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/stnic.c Tue Aug 8 01:51:48 2000
@@ -105,6 +105,10 @@
 
   /* New style probing API */
   dev = init_etherdev (0, 0);
+
+ if (!dev)
+ return -ENOMEM;
+
   stnic_dev = dev;
 
   /* Allocate dev->priv and fill in 8390 specific dev fields. */
diff -uNr linux-2.4.0-test6-pre7/drivers/net/sun3lance.c linux-2.4.0-test6-pre7.acme/drivers/net/sun3lance.c
--- linux-2.4.0-test6-pre7/drivers/net/sun3lance.c Mon Jan 31 16:30:00 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/sun3lance.c Tue Aug 8 01:52:54 2000
@@ -303,7 +303,11 @@
 
         init_etherdev( dev, sizeof(struct lance_private) );
         if (!dev->priv)
- dev->priv = kmalloc( sizeof(struct lance_private), GFP_KERNEL );
+ if ((dev->priv = kmalloc( sizeof(struct lance_private), GFP_KERNEL)) == NULL) {
+ printk("lance: lance_probe: kmalloc(dev->priv) failed!\n");
+ return 0;
+ }
+
         lp = (struct lance_private *)dev->priv;
         MEM = (struct lance_memory *)sun3_dvma_malloc(sizeof(struct
                                                              lance_memory));
diff -uNr linux-2.4.0-test6-pre7/drivers/net/sunbmac.c linux-2.4.0-test6-pre7.acme/drivers/net/sunbmac.c
--- linux-2.4.0-test6-pre7/drivers/net/sunbmac.c Tue Jul 11 19:46:08 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/sunbmac.c Tue Aug 8 01:51:48 2000
@@ -1061,6 +1061,9 @@
         /* Get a new device struct for this interface. */
         dev = init_etherdev(0, sizeof(struct bigmac));
 
+ if (!dev)
+ return -ENOMEM;
+
         if (version_printed++ == 0)
                 printk(KERN_INFO "%s", version);
 
diff -uNr linux-2.4.0-test6-pre7/drivers/net/sunhme.c linux-2.4.0-test6-pre7.acme/drivers/net/sunhme.c
--- linux-2.4.0-test6-pre7/drivers/net/sunhme.c Mon Jun 19 17:42:39 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/sunhme.c Tue Aug 8 01:51:48 2000
@@ -2528,6 +2528,9 @@
         }
         if (dev == NULL) {
                 dev = init_etherdev(0, sizeof(struct happy_meal));
+
+ if (dev == NULL)
+ return -ENOMEM;
         } else {
                 dev->priv = kmalloc(sizeof(struct happy_meal), GFP_KERNEL);
                 if (dev->priv == NULL)
@@ -2712,6 +2715,9 @@
         }
         if (dev == NULL) {
                 dev = init_etherdev(0, sizeof(struct happy_meal));
+
+ if (dev == NULL)
+ return -ENOMEM;
         } else {
                 dev->priv = kmalloc(sizeof(struct happy_meal), GFP_KERNEL);
                 if (dev->priv == NULL)
diff -uNr linux-2.4.0-test6-pre7/drivers/net/sunlance.c linux-2.4.0-test6-pre7.acme/drivers/net/sunlance.c
--- linux-2.4.0-test6-pre7/drivers/net/sunlance.c Thu Jul 6 02:15:25 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/sunlance.c Tue Aug 8 01:51:48 2000
@@ -1319,6 +1319,9 @@
 
         if (dev == NULL) {
                 dev = init_etherdev (0, sizeof (struct lance_private) + 8);
+
+ if (dev == NULL)
+ return -ENOMEM;
         } else {
                 dev->priv = kmalloc(sizeof (struct lance_private) + 8,
                                     GFP_KERNEL);
diff -uNr linux-2.4.0-test6-pre7/drivers/net/sunqe.c linux-2.4.0-test6-pre7.acme/drivers/net/sunqe.c
--- linux-2.4.0-test6-pre7/drivers/net/sunqe.c Mon Jun 19 17:42:39 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/sunqe.c Tue Aug 8 01:51:48 2000
@@ -5,10 +5,15 @@
  * if you make it look like a LANCE.
  *
  * Copyright (C) 1996, 1999 David S. Miller (davem@redhat.com)
+ *
+ * Changes:
+ * Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 08/06/2000
+ * - check init_etherdev return in qec_ether_init
+ * - no need to check dev->priv, init_etherdev checks it
  */
 
 static char *version =
- "sunqe.c:v2.9 9/11/99 David S. Miller (davem@redhat.com)\n";
+ "sunqe.c:v2.10 8/6/2000 David S. Miller (davem@redhat.com)\n";
 
 #include <linux/module.h>
 
@@ -749,6 +754,10 @@
         int i, j, res = ENOMEM;
 
         dev = init_etherdev(0, sizeof(struct sunqe));
+
+ if (dev == NULL)
+ return -ENOMEM;
+
         qe_devs[0] = dev;
         qeps[0] = (struct sunqe *) dev->priv;
         qeps[0]->channel = 0;
@@ -762,7 +771,7 @@
         qe_devs[1] = qe_devs[2] = qe_devs[3] = NULL;
         for (i = 1; i < 4; i++) {
                 qe_devs[i] = init_etherdev(0, sizeof(struct sunqe));
- if (qe_devs[i] == NULL || qe_devs[i]->priv == NULL)
+ if (qe_devs[i] == NULL)
                         goto qec_free_devs;
                 qeps[i] = (struct sunqe *) qe_devs[i]->priv;
                 for (j = 0; j < 6; j++)
diff -uNr linux-2.4.0-test6-pre7/drivers/net/tlan.c linux-2.4.0-test6-pre7.acme/drivers/net/tlan.c
--- linux-2.4.0-test6-pre7/drivers/net/tlan.c Mon Jun 19 17:42:39 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/tlan.c Tue Aug 8 01:51:48 2000
@@ -32,6 +32,8 @@
  * new PCI BIOS interface.
  * Alan Cox <alan@redhat.com>: Fixed the out of memory
  * handling.
+ * Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 08/03/2000
+ * - check kmalloc(dev->priv) return in tlan_probe
  *
  * Torben Mathiasen <torben.mathiasen@compaq.com> New Maintainer!
  *
@@ -422,11 +424,14 @@
                         printk(KERN_ERR "TLAN: Could not allocate memory for device.\n");
                         return -ENOMEM;
                 }
- priv = dev->priv;
                 if (dev->priv == NULL) {
                         dev->priv = kmalloc(sizeof(TLanPrivateInfo), GFP_KERNEL);
- priv = dev->priv;
+ if (!dev->priv) {
+ printk(KERN_ERR "TLAN: Could not allocate memory for device.\n");
+ return -ENOMEM;
+ }
                 }
+ priv = dev->priv;
                 memset(priv, 0, sizeof(TLanPrivateInfo));
                 
                 pad_allocated = 1;
diff -uNr linux-2.4.0-test6-pre7/drivers/net/wd.c linux-2.4.0-test6-pre7.acme/drivers/net/wd.c
--- linux-2.4.0-test6-pre7/drivers/net/wd.c Mon Jun 19 17:42:38 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/wd.c Tue Aug 8 01:51:48 2000
@@ -126,8 +126,11 @@
 
         /* We should have a "dev" from Space.c or the static module table. */
         if (dev == NULL) {
- printk("wd.c: Passed a NULL device.\n");
- dev = init_etherdev(0, 0);
+ printk(KERN_ERR "wd.c: Passed a NULL device.\n");
+ if ((dev = init_etherdev(0, 0)) == NULL) {
+ printk(KERN_ERR "wd.c: Passed a NULL device.\n");
+ return -ENOMEM;
+ }
         }
 
         /* Check for semi-valid mem_start/end values if supplied. */

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



This archive was generated by hypermail 2b29 : Tue Aug 15 2000 - 21:00:14 EST